bfg-common 1.5.595 → 1.5.596

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 (172) hide show
  1. package/CODE_STYLE.md +109 -109
  2. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  3. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  4. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  5. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  6. package/assets/localization/local_be.json +4 -0
  7. package/assets/localization/local_en.json +4 -0
  8. package/assets/localization/local_hy.json +4 -0
  9. package/assets/localization/local_kk.json +4 -0
  10. package/assets/localization/local_ru.json +4 -0
  11. package/assets/localization/local_zh.json +4 -0
  12. package/components/atoms/TheIcon3.vue +50 -50
  13. package/components/atoms/collapse/CollapseNav.vue +170 -170
  14. package/components/atoms/perPage/PerPage.vue +58 -58
  15. package/components/atoms/table/dataGrid/DataGrid.vue +1718 -1718
  16. package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
  17. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  18. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  19. package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
  20. package/components/common/browse/Browse.vue +9 -0
  21. package/components/common/browse/BrowseNew.vue +2 -1
  22. package/components/common/browse/BrowseOld.vue +2 -1
  23. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  24. package/components/common/diagramMain/modals/lib/config/portModal.ts +251 -251
  25. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  26. package/components/common/diagramMain/port/Port.vue +580 -580
  27. package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
  28. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
  29. package/components/common/pages/backups/DetailView.vue +52 -52
  30. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  31. package/components/common/pages/backups/modals/Modals.vue +243 -243
  32. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  33. package/components/common/pages/backups/modals/createBackup/lib/config/readyToCompleteOptions.ts +69 -69
  34. package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
  35. package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
  36. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  37. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  38. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  39. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  40. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  41. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  42. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  43. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  44. package/components/common/select/radio/RadioGroup.vue +137 -137
  45. package/components/common/spiceConsole/Drawer.vue +420 -420
  46. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  47. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  48. package/components/common/tools/Actions.vue +207 -207
  49. package/components/common/treeView/TreeView.vue +52 -52
  50. package/components/common/vm/actions/add/Add.vue +819 -819
  51. package/components/common/vm/actions/clone/Clone.vue +694 -694
  52. package/components/common/vm/actions/common/customizeHardware/CustomizeHardware.vue +205 -205
  53. package/components/common/vm/actions/common/customizeHardware/New.vue +325 -325
  54. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +679 -679
  55. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/Bus.vue +101 -101
  56. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDrive.vue +227 -227
  57. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/Media.vue +29 -29
  58. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +323 -323
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/coresPerSocket/CoresPerSocket.vue +81 -81
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/hotPlug/HotPlug.vue +40 -40
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/maxCpu/MaxCpu.vue +91 -91
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/model/Model.vue +92 -92
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/Shares.vue +133 -133
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/tooltip/Tooltip.vue +27 -27
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/limit/Limit.vue +214 -214
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +280 -280
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/New.vue +158 -158
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Old.vue +155 -155
  70. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/hotPlug/HotPlug.vue +29 -29
  71. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +483 -483
  72. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/cache/Cache.vue +59 -59
  73. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/file/File.vue +24 -24
  74. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/limitIops/LimitIops.vue +96 -96
  75. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/Location.vue +142 -142
  76. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/storageModal/StorageModal.vue +55 -55
  77. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/maximumSize/MaximumSize.vue +26 -26
  78. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/mode/Mode.vue +61 -61
  79. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/provisioning/Provisioning.vue +57 -57
  80. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/sharing/Sharing.vue +59 -59
  81. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +257 -257
  82. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/adapterType/AdapterType.vue +56 -56
  83. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/Location.vue +65 -65
  84. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +111 -111
  85. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/NewPciDevice.vue +199 -199
  86. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIo.vue +27 -27
  87. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +29 -29
  88. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/Note.vue +23 -23
  89. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGrid.vue +40 -40
  90. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/typeSelection/TypeSelection.vue +34 -34
  91. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbController.vue +47 -47
  92. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +15 -15
  93. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/inputDevices/InputDevices.vue +15 -15
  94. package/components/common/vm/actions/common/customizeHardware/virtualHardware/reservation/Reservation.vue +194 -194
  95. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCard.vue +129 -129
  96. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/model/Model.vue +35 -35
  97. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/numberDisplays/NumberDisplays.vue +50 -50
  98. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/totalVideoMemory/TotalVideoMemory.vue +104 -104
  99. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +70 -70
  100. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptions.vue +42 -42
  101. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +32 -32
  102. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +57 -57
  103. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/menu/Menu.vue +25 -25
  104. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +155 -155
  105. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +82 -82
  106. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +74 -74
  107. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/copyPaste/CopyPaste.vue +25 -25
  108. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/fileTransfer/FileTransfer.vue +25 -25
  109. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/folderSharing/FolderSharing.vue +17 -17
  110. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  111. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +99 -99
  112. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  113. package/components/common/vm/actions/common/customizeHardware/vmoptions/tools/Tools.vue +42 -42
  114. package/components/common/vm/actions/common/select/compatibility/Compatibility.vue +105 -105
  115. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  116. package/components/common/vm/actions/common/select/createType/CreateType.vue +36 -36
  117. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  118. package/components/common/vm/actions/common/select/options/Options.vue +53 -53
  119. package/components/common/vm/actions/common/select/os/Os.vue +152 -152
  120. package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
  121. package/components/common/vm/actions/common/select/storage/Storage.vue +170 -170
  122. package/components/common/vm/actions/common/select/storage/new/New.vue +311 -311
  123. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  124. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  125. package/components/common/vm/actions/common/select/template/Template.vue +75 -75
  126. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  127. package/components/common/vm/actions/common/select/template/treeView/TreeView.vue +85 -85
  128. package/components/common/vm/actions/editSettings/EditSettings.vue +169 -169
  129. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  130. package/components/common/vm/actions/register/Register.vue +332 -352
  131. package/components/common/vm/actions/register/RegisterNew.vue +218 -0
  132. package/components/common/vm/actions/register/RegisterOld.vue +127 -0
  133. package/components/common/vm/actions/register/lib/config/index.ts +1 -0
  134. package/components/common/vm/actions/register/lib/config/steps.ts +86 -86
  135. package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
  136. package/components/common/wizards/common/compatibility/New.vue +99 -99
  137. package/components/common/wizards/common/compatibility/Old.vue +53 -53
  138. package/components/common/wizards/common/steps/computeResource/ComputeResource.vue +86 -86
  139. package/components/common/wizards/common/steps/computeResource/New.vue +93 -93
  140. package/components/common/wizards/common/steps/name/Name.vue +178 -178
  141. package/components/common/wizards/common/steps/name/New.vue +221 -221
  142. package/components/common/wizards/common/steps/name/Old.vue +121 -121
  143. package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
  144. package/components/common/wizards/common/steps/name/location/Location.vue +85 -85
  145. package/components/common/wizards/common/steps/name/location/New.vue +40 -40
  146. package/components/common/wizards/datastore/add/Add.vue +228 -228
  147. package/components/common/wizards/datastore/add/lib/utils.ts +85 -85
  148. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  149. package/components/common/wizards/vm/migrate/select/computeResource/ComputeResource.vue +205 -205
  150. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  151. package/composables/useAppVersion.ts +21 -21
  152. package/composables/useLocal.ts +6 -6
  153. package/composables/useLocalCommon.ts +39 -39
  154. package/lib/models/interfaces.ts +1 -0
  155. package/package.json +2 -2
  156. package/plugins/console.ts +21 -21
  157. package/plugins/date.ts +233 -233
  158. package/plugins/mouse.ts +21 -21
  159. package/plugins/panelStates.ts +70 -70
  160. package/plugins/text.ts +59 -59
  161. package/plugins/time.ts +58 -58
  162. package/public/spice-console/application/clientgui.js +854 -854
  163. package/public/spice-console/application/packetfactory.js +211 -211
  164. package/public/spice-console/application/virtualmouse.js +147 -147
  165. package/public/spice-console/lib/images/bitmap.js +203 -203
  166. package/public/spice-console/network/spicechannel.js +440 -440
  167. package/public/spice-console/process/cursorprocess.js +121 -121
  168. package/public/spice-console/process/inputprocess.js +227 -227
  169. package/public/spice-console/process/mainprocess.js +210 -210
  170. package/public/spice-console/run.js +210 -210
  171. package/store/main/mutations.ts +7 -7
  172. package/store/main/state.ts +7 -7
@@ -1,854 +1,854 @@
1
- /*
2
- Copyright (c) 2016 eyeOS
3
-
4
- This file is part of Open365.
5
-
6
- Open365 is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Affero General Public License as
8
- published by the Free Software Foundation, either version 3 of the
9
- License, or (at your option) any later version.
10
-
11
- This program is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Affero General Public License for more details.
15
-
16
- You should have received a copy of the GNU Affero General Public License
17
- along with this program. If not, see <http://www.gnu.org/licenses/>.
18
- */
19
-
20
- wdi.SPICE_INPUT_MOTION_ACK_BUNCH = 8
21
-
22
- wdi.ClientGui = $.spcExtend(wdi.EventObject.prototype, {
23
- width: null,
24
- height: null,
25
- canvas: null,
26
- ack_wait: 0,
27
- mouse_mode: 0,
28
- mouse_status: 0,
29
- eventLayer: null,
30
- counter: 0,
31
- mainCanvas: 0,
32
- firstTime: true,
33
- clientOffsetX: 0,
34
- clientOffsetY: 0,
35
- magnifier: null,
36
- magnifierBackground: null,
37
- firstMove: true,
38
- isMagnified: true,
39
- isMouseDown: false,
40
- soundStarted: false,
41
- canvasMarginY: 0,
42
- canvasMarginX: 0,
43
- stuckKeysHandler: null,
44
- isKeyboardEnabled: false,
45
-
46
- subCanvas: {},
47
- inputManager: null,
48
- clipboardEnabled: true,
49
- layer: null,
50
- freezeClass: 'freeze',
51
- app: {},
52
-
53
- init: function (c) {
54
- this.time = Date.now()
55
- this.canvas = {}
56
- this.contexts = {}
57
- this.superInit()
58
- this.magnifier = window
59
- .$('<canvas/>')
60
- .attr({
61
- width: 150,
62
- height: 150,
63
- })
64
- .css({
65
- position: 'absolute',
66
- left: '0px',
67
- top: '0px',
68
- })
69
- this.stuckKeysHandler = c.stuckKeysHandler || new wdi.StuckKeysHandler()
70
- this.settings = c.settings || {}
71
- this.stuckKeysHandler.addListener(
72
- 'inputStuck',
73
- this._sendInput.bind(this),
74
- this
75
- )
76
-
77
- //load magnifier background
78
- this.magnifierBackground = window.$('<img/>')
79
- this.magnifierBackground.attr(
80
- 'src',
81
- '/spice-console/resources/magnifier.png'
82
- )
83
- this.initSound()
84
- this.inputManager =
85
- c.inputManager ||
86
- new wdi.InputManager({
87
- stuckKeysHandler: this.stuckKeysHandler,
88
- window: $(window),
89
- })
90
- this.inputManager.setCurrentWindow(window)
91
- this.clipBoardDataParser =
92
- c.clipBoardDataParser || new wdi.ClipboardDataParser({})
93
- this.localClipboard =
94
- c.localClipboard || new wdi.LocalClipboard({ clientGui: this })
95
- this.app = c.app
96
-
97
- var self = this
98
- this.eventHandlers = {
99
- hide: function () {
100
- self.stuckKeysHandler.releaseAllKeys()
101
- },
102
- }
103
- window.$(document).on(this.eventHandlers)
104
- },
105
-
106
- dispose: function () {
107
- wdi.Debug.log('Disposing ClientGui')
108
- $(document).off(this.eventHandlers)
109
- this.unbindDOM()
110
- this.removeAllCanvases()
111
- this.inputManager.dispose()
112
- this.stuckKeysHandler.dispose()
113
- this.localClipboard.dispose()
114
-
115
- this.width = null
116
- this.height = null
117
- this.canvas = null
118
- this.ack_wait = 0
119
- this.mouse_mode = 0
120
- this.mouse_status = 0
121
- this.eventLayer = null
122
- this.counter = 0
123
- this.mainCanvas = 0
124
- this.firstTime = true
125
- this.clientOffsetX = 0
126
- this.clientOffsetY = 0
127
- this.magnifier = null
128
- this.magnifierBackground = null
129
- this.firstMove = true
130
- this.isMagnified = true
131
- this.isMouseDown = false
132
- this.soundStarted = false
133
- this.canvasMarginY = 0
134
- this.canvasMarginX = 0
135
- this.stuckKeysHandler = null
136
- this.subCanvas = {}
137
- this.inputManager = null
138
- this.clipboardEnabled = true
139
- this.layer = null
140
- clearInterval(self.rightClickTimer) //cancel, this is not a right click
141
- clearInterval(self.mouseDownTimer) //cancel
142
- },
143
-
144
- removeAllCanvases: function () {
145
- var self = this
146
- Object.keys(this.canvas).forEach(function (key) {
147
- $(self.canvas[key]).remove()
148
- delete self.canvas[key]
149
- delete self.contexts[key]
150
- })
151
- $(this.eventLayer).remove()
152
- this.eventLayer = null
153
- },
154
-
155
- unbindDOM: function () {
156
- if (this.eventLayer) {
157
- var events = [
158
- 'touchstart',
159
- 'touchmove',
160
- 'touchend',
161
- 'mouseup',
162
- 'mousedown',
163
- 'mousemove',
164
- 'contextmenu',
165
- 'mousewheel',
166
- ]
167
- events.forEach(function (event) {
168
- $(this.eventLayer).unbind(event)
169
- })
170
- }
171
- },
172
-
173
- freeze: function () {
174
- if (this.canvas[0]) {
175
- var image = new Image()
176
- var cnv = this.canvas[0]
177
- var $cnv = $(cnv)
178
- $(image).attr('style', $cnv.attr('style'))
179
- $(image).attr('class', this.freezeClass)
180
- image.src = cnv.toDataURL('image/png')
181
- $cnv.parent().append($(image))
182
- }
183
- },
184
-
185
- cancelFreeze: function () {
186
- $('.' + this.freezeClass).remove()
187
- },
188
-
189
- setLayer: function (layer) {
190
- this.layer = layer
191
- },
192
-
193
- disableClipboard: function () {
194
- this.clipboardEnabled = false
195
- },
196
-
197
- _sendInput: function (params) {
198
- var data = params
199
- var type = data[0]
200
- var event = data[1]
201
- this.fire('input', [type, event])
202
- },
203
-
204
- releaseAllKeys: function () {
205
- this.stuckKeysHandler.releaseAllKeys()
206
- },
207
-
208
- getContext: function (surface_id) {
209
- return this.contexts[surface_id]
210
- },
211
-
212
- getCanvas: function (surface_id) {
213
- return this.canvas[surface_id]
214
- },
215
-
216
- checkFeatures: function () {
217
- if (!Modernizr.canvas || !Modernizr.websockets) {
218
- alert(
219
- 'Your Browser is not compatible with WDI. Visit ... for a list of compatible browsers'
220
- )
221
- return false
222
- }
223
- return true
224
- },
225
-
226
- deleteSubCanvas: function (window) {
227
- var obj = this.subCanvas[window['hwnd']]
228
- this.subCanvas[window['hwnd']] = null
229
- return obj
230
- },
231
-
232
- moveSubCanvas: function (window) {
233
- var obj = this.subCanvas[window['hwnd']]
234
- obj['info'] = window
235
- this._fillSubCanvasFromWindow(window)
236
- return obj
237
- },
238
-
239
- resizeSubCanvas: function (window) {
240
- var obj = this.subCanvas[window['hwnd']]
241
- $([obj['canvas'], obj['eventLayer']]).attr({
242
- width: window['width'],
243
- height: window['height'],
244
- })
245
- obj['info'] = window
246
- this._fillSubCanvasFromWindow(window)
247
- return obj
248
- },
249
-
250
- _fillSubCanvasFromWindow: function (window) {
251
- var top = parseInt(window.top, 10)
252
- var left = parseInt(window.left, 10)
253
- var width = parseInt(window.width, 10)
254
- var height = parseInt(window.height, 10)
255
- this.fillSubCanvas({
256
- top: top,
257
- left: left,
258
- right: left + width,
259
- bottom: top + height,
260
- })
261
- },
262
-
263
- createNewSubCanvas: function (window) {
264
- var evtlayer = this.createEventLayer(
265
- window['hwnd'] + '_event',
266
- window['width'],
267
- window['height']
268
- )
269
- this.subCanvas[window['hwnd']] = {
270
- canvas: $('<canvas/>')
271
- .attr({
272
- width: window['width'],
273
- height: window['height'],
274
- })
275
- .css({
276
- display: window['iconic'] ? 'none' : 'block',
277
- })[0],
278
- eventLayer: evtlayer,
279
- info: window,
280
- position: 0,
281
- }
282
- //we have the main area drawn?
283
- if (this.canvas[this.mainCanvas]) {
284
- this._fillSubCanvasFromWindow(window)
285
- }
286
- return [this.subCanvas[window['hwnd']]]
287
- },
288
-
289
- fillSubCanvas: function (filterPosition) {
290
- var canvas = this.canvas[this.mainCanvas]
291
- var info = null
292
- for (var i in this.subCanvas) {
293
- if (
294
- this.subCanvas[i] != null &&
295
- this.subCanvas[i] !== undefined &&
296
- this.subCanvas.hasOwnProperty(i)
297
- ) {
298
- info = this.subCanvas[i]['info']
299
- if (filterPosition != null || filterPosition != undefined) {
300
- var top = parseInt(info['top'], 10)
301
- var left = parseInt(info['left'], 10)
302
- var width = parseInt(info['width'], 10)
303
- var height = parseInt(info['height'], 10)
304
- var position = {
305
- top: top,
306
- left: left,
307
- right: left + width,
308
- bottom: top + height,
309
- }
310
- if (
311
- wdi.CollisionDetector.thereIsBoxCollision(position, filterPosition)
312
- ) {
313
- this._doDrawSubCanvas(canvas, this.subCanvas[i], info)
314
- }
315
- } else {
316
- this._doDrawSubCanvas(canvas, this.subCanvas[i], info)
317
- }
318
- }
319
- }
320
- },
321
-
322
- _doDrawSubCanvas: function (canvas, subCanvas, info) {
323
- if (
324
- this.canvas[this.mainCanvas] == null ||
325
- this.canvas[this.mainCanvas] == undefined
326
- ) {
327
- return
328
- }
329
- var destCtx = null
330
- if (info['iconic'] === 0) {
331
- var destCanvas = subCanvas['canvas']
332
- destCtx = destCanvas.getContext('2d')
333
-
334
- var x = 0
335
- var y = 0
336
- var width = +info.width
337
- var height = +info.height
338
- var left = +info['left']
339
- var top = +info['top']
340
-
341
- if (left < 0) {
342
- width = width + left
343
- x = -left
344
- left = 0
345
- }
346
-
347
- if (top < 0) {
348
- height = height + top
349
- y = -top
350
- top = 0
351
- }
352
-
353
- try {
354
- // if width or height are less than 1 or a float
355
- // drawImage fails in firefox (ERROR: IndexSizeError)
356
- width = Math.max(1, Math.floor(width))
357
- height = Math.max(1, Math.floor(height))
358
- if (width > canvas.width) width = canvas.width
359
- if (height > canvas.height) height = canvas.height
360
- destCtx.drawImage(canvas, left, top, width, height, x, y, width, height)
361
- } catch (err) {
362
- wdi.Debug.error(err)
363
- }
364
- }
365
- },
366
-
367
- removeCanvas: function (spiceMessage) {
368
- var surface = spiceMessage.args
369
- if (surface.surface_id === this.mainCanvas) {
370
- $(this.eventLayer).remove()
371
- this.eventLayer = null
372
- }
373
-
374
- this.canvas[surface.surface_id].keepAlive = false
375
- delete this.canvas[surface.surface_id]
376
- delete this.contexts[surface.surface_id]
377
- },
378
-
379
- drawCanvas: function (spiceMessage) {
380
- wdi.Debug.log('clientgui time: ', this.time)
381
- var surface = spiceMessage.args
382
-
383
- // // Custom code
384
- // // Проверяем если ширина вм-а меньше ширины окна, вставляем по центру
385
- // if (surface.width < window.innerWidth) {
386
- // const x = (window.innerWidth - surface.width) / 2
387
- // this.setCanvasMargin({
388
- // x,
389
- // y: this.canvasMarginY,
390
- // })
391
- // this.setClientOffset(-x, this.canvasMarginY)
392
- // }
393
- // // Custom code End
394
-
395
- var cnv = wdi.GlobalPool.create('Canvas')
396
- cnv.keepAlive = true //prevent this canvas to return to the pool by packetfilter
397
-
398
- cnv.id = 'canvas_' + surface.surface_id
399
- cnv.width = surface.width * this.pixelRatio
400
- cnv.height = surface.height * this.pixelRatio
401
- cnv.style.position = 'absolute'
402
- cnv.style.top = this.canvasMarginY + 'px'
403
- cnv.style.left = this.canvasMarginX + 'px'
404
- cnv.style.width = surface.width + 'px'
405
- cnv.style.height = surface.height + 'px'
406
-
407
- this.canvas[surface.surface_id] = cnv
408
- this.contexts[surface.surface_id] = cnv.getContext('2d')
409
-
410
- if (surface.flags && !wdi.SeamlessIntegration) {
411
- this.mainCanvas = surface.surface_id
412
-
413
- this.eventLayer = this.createEventLayer(
414
- 'eventLayer',
415
- surface.width,
416
- surface.height
417
- )
418
-
419
- var evLayer = $(this.eventLayer).css({
420
- position: 'absolute',
421
- top: this.canvasMarginY + 'px',
422
- left: this.canvasMarginX + 'px',
423
- })[0]
424
-
425
- if (this.layer) {
426
- this.layer.appendChild(cnv)
427
- this.layer.appendChild(evLayer)
428
- } else {
429
- document.body.appendChild(cnv)
430
- document.body.appendChild(evLayer)
431
- }
432
- !this.isKeyboardEnabled && this.enableKeyboard()
433
- }
434
-
435
- //this goes here?
436
- if (this.firstTime && this.clipboardEnabled) {
437
- var self = this
438
- var PASTES_PER_SECOND = this.settings.PASTES_PER_SECOND || 5
439
-
440
- var firePaste = _.throttle(function (data) {
441
- self.fire('paste', data)
442
- }, 1000 / PASTES_PER_SECOND)
443
-
444
- $(document).bind('paste', function (event) {
445
- self.clipBoardDataParser.parse(
446
- event.originalEvent.clipboardData,
447
- firePaste
448
- )
449
- })
450
-
451
- $(document).bind('copy', function (e) {
452
- self.app.sendShortcut(wdi.keyShortcutsHandled.CTRLC)
453
- })
454
-
455
- this.firstTime = false
456
- }
457
-
458
- //notify about resolution
459
- if (surface.flags) {
460
- this.fire('resolution', [
461
- this.canvas[surface.surface_id].width,
462
- this.canvas[surface.surface_id].height,
463
- ])
464
- }
465
- },
466
-
467
- disableKeyboard: function () {
468
- var documentDOM = window.$(window.document)
469
- documentDOM.unbind('keydown', this.handleKey)
470
- documentDOM.unbind('keyup', this.handleKey)
471
- documentDOM.unbind('keypress', this.handleKey)
472
- this.inputManager.disable()
473
- },
474
-
475
- enableKeyboard: function () {
476
- var self = this,
477
- documentDOM = window.$(window.document)
478
- documentDOM['keydown']([self], this.handleKey)
479
- documentDOM['keypress']([self], this.handleKey)
480
- documentDOM['keyup']([self], this.handleKey)
481
- this.inputManager.enable()
482
- !this.isKeyboardEnabled && (this.isKeyboardEnabled = true)
483
- },
484
-
485
- setCanvasMargin: function (canvasMargin) {
486
- this.canvasMarginX = canvasMargin.x
487
- this.canvasMarginY = canvasMargin.y
488
- },
489
-
490
- createEventLayer: function (event_id, width, height) {
491
- var self = this
492
-
493
- var eventLayer = $('<canvas/>')
494
- .css({
495
- cursor: 'default',
496
- position: 'absolute',
497
- })
498
- .attr({
499
- id: event_id,
500
- // width: window.innerWidth,
501
- // height: window.innerHeight
502
- // Правильнее слой события делать с размером самого вм-а
503
- width, // Custom code
504
- height, // Custom code
505
- })
506
-
507
- if (window['bowser']['firefox']) {
508
- eventLayer.attr('contentEditable', true)
509
- }
510
-
511
- eventLayer.bind('touchstart', function (event) {
512
- event.preventDefault()
513
- var touch =
514
- event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]
515
- var x = touch.pageX
516
- var y = touch.pageY
517
- self.generateEvent.call(self, 'mousemove', [
518
- x + self.clientOffsetX,
519
- y + self.clientOffsetY,
520
- self.mouse_status,
521
- ])
522
- if (event.originalEvent.touches.length === 1) {
523
- self.enabledTouchMove = true
524
- self.launchRightClick.call(self, x, y)
525
- } else if (event.originalEvent.touches.length === 2) {
526
- self.touchX = x
527
- self.touchY = y
528
- self.enabledTouchMove = false
529
- } else if (event.originalEvent.touches.length === 3) {
530
- self.touchY3 = y
531
- self.enabledTouchMove = false
532
- }
533
- })
534
-
535
- eventLayer.bind('touchmove', function (event) {
536
- var touch =
537
- event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]
538
- var x = touch.pageX
539
- var y = touch.pageY
540
- //TODO: ignore first move
541
- if (event.originalEvent.touches.length === 1 && self.enabledTouchMove) {
542
- self.isMagnified = true //magnified!
543
- clearInterval(self.rightClickTimer) //cancel, this is not a right click
544
-
545
- if (!self.isMouseDown) {
546
- clearInterval(self.mouseDownTimer) //cancel, not enough time to send mousedown
547
- self.launchMouseDown() //fire again
548
- }
549
-
550
- self.generateEvent.call(self, 'mousemove', [
551
- x + self.clientOffsetX,
552
- y + self.clientOffsetY - 80,
553
- self.mouse_status,
554
- ])
555
- var pos = $(this).offset()
556
- var myX = x - pos.left
557
- var myY = y - pos.top
558
-
559
- //draw magnifier
560
- if (self.firstMove) {
561
- $('body').append(self.magnifier) //TODO: append to body?
562
- self.firstMove = false
563
- }
564
-
565
- var posX = myX - 75
566
- var posY = myY - 160
567
-
568
- self.magnifier.css({
569
- left: posX,
570
- top: posY,
571
- })
572
-
573
- //fill magnifier
574
- var ctx = self.magnifier[0].getContext('2d')
575
- ctx.clearRect(0, 0, 150, 150)
576
- ctx.save()
577
- ctx.beginPath()
578
- ctx.arc(75, 75, 75, 0, 2 * Math.PI, false)
579
- ctx.clip()
580
- ctx.drawImage(
581
- self.getCanvas(0),
582
- myX - 50, //-50 because we are going to get
583
- myY - 50 - 80, //100 px and we want the finder to be the center
584
- //-80 becasue the magnifier is 160px up (160/2)
585
- //we need to clean all this after the demo
586
- //is working
587
- 100,
588
- 100,
589
- 0,
590
- 0,
591
- 150,
592
- 150
593
- )
594
- // //draw the background
595
- ctx.drawImage(self.magnifierBackground[0], 0, 0)
596
- ctx.restore()
597
- //empty magnifier
598
- } else if (event.originalEvent.touches.length === 2) {
599
- var delta = self.touchY - y
600
- if (Math.abs(delta) > 10) {
601
- var button = delta > 0 ? 4 : 3
602
- self.touchX = x
603
- self.touchY = y
604
- self.generateEvent.call(self, 'mousedown', button)
605
- self.generateEvent.call(self, 'mouseup', button)
606
- }
607
- } else if (event.originalEvent.touches.length === 3) {
608
- var delta = self.touchY3 - y
609
- if (delta > 100) {
610
- document.getElementById('hiddeninput').select()
611
- }
612
- }
613
- event.preventDefault()
614
- })
615
-
616
- eventLayer.bind('touchend', function (event) {
617
- if (self.enabledTouchMove) {
618
- var touch =
619
- event.originalEvent.touches[0] ||
620
- event.originalEvent.changedTouches[0]
621
- var x = touch.pageX
622
- var y = touch.pageY
623
- if (!self.isMouseDown) {
624
- self.generateEvent.call(self, 'mousedown', 0)
625
- }
626
- self.isMouseDown = false
627
- self.generateEvent.call(self, 'mouseup', 0)
628
- var pos = $(this).offset()
629
-
630
- self.enabledTouchMove = false
631
- self.firstMove = true
632
- if (self.isMagnified) {
633
- self.magnifier.remove()
634
- }
635
- self.isMagnified = false
636
- }
637
- clearInterval(self.rightClickTimer) //cancel, this is not a right click
638
- clearInterval(self.mouseDownTimer) //cancel
639
- })
640
-
641
- //if (!Modernizr.touch) {
642
- eventLayer['mouseup'](function (event) {
643
- var button = event.button
644
-
645
- self.generateEvent.call(self, 'mouseup', button)
646
- self.mouse_status = 0
647
- event.preventDefault()
648
- })
649
-
650
- eventLayer['mousedown'](function (event) {
651
- var button = event.button
652
-
653
- self.generateEvent.call(self, 'mousedown', button)
654
- self.mouse_status = 1
655
- event.preventDefault()
656
- })
657
-
658
- eventLayer['mousemove'](function (event) {
659
- if (
660
- self.mouse_mode === wdi.SpiceMouseModeTypes.SPICE_MOUSE_MODE_SERVER &&
661
- event.bubbles
662
- )
663
- return // Custom code // TODO refactoring. event.bubbles используется так как если переключить mouseMode на серверную то mousemove срабатывает дважды
664
- var x = event.pageX
665
- var y = event.pageY
666
- // self.generateEvent.call(self, 'mousemove', [
667
- // (x + self.clientOffsetX) * self.pixelRatio,
668
- // (y + self.clientOffsetY) * self.pixelRatio,
669
- // self.mouse_status,
670
- // ])
671
- // Custom code
672
- self.generateEvent.call(self, 'mousemove', [
673
- (x + self.clientOffsetX - self.eventLayer.offsetLeft) * self.pixelRatio,
674
- (y + self.clientOffsetY - self.eventLayer.offsetTop) * self.pixelRatio,
675
- self.mouse_status,
676
- ])
677
- // Custom code End
678
- event.preventDefault()
679
- })
680
-
681
- eventLayer.bind('contextmenu', function (event) {
682
- event.preventDefault()
683
- return false
684
- })
685
- //}
686
-
687
- var mouseEventPause = false
688
-
689
- var fireWheel = _.throttle(function (event, delta) {
690
- var button = delta > 0 ? 3 : 4
691
-
692
- self.generateEvent.call(self, 'mousedown', button)
693
- self.generateEvent.call(self, 'mouseup', button)
694
-
695
- return false
696
- }, 60)
697
-
698
- eventLayer.bind('mousewheel', fireWheel)
699
-
700
- this.fire('eventLayerCreated', eventLayer[0])
701
-
702
- wdi.VirtualMouse.setEventLayer(eventLayer[0], 0, 0, width, height, 1)
703
- return eventLayer[0]
704
- },
705
-
706
- launchRightClick: function (x, y) {
707
- var self = this
708
- this.rightClickTimer = setTimeout(function () {
709
- self.generateEvent.call(self, 'mousedown', 2)
710
- self.generateEvent.call(self, 'mouseup', 2)
711
- self.enabledTouchMove = false
712
- }, 400)
713
- },
714
-
715
- launchMouseDown: function (x, y) {
716
- var self = this
717
- this.mouseDownTimer = setTimeout(function () {
718
- self.isMouseDown = true
719
- self.generateEvent.call(self, 'mousedown', 0)
720
- }, 1500)
721
- },
722
-
723
- showError: function (message) {
724
- wdi.Debug.warn(message)
725
- $('<div/>', {
726
- id: 'error',
727
- })
728
- .html(message)
729
- .css({
730
- 'background-color': '#ff4141',
731
- })
732
- .appendTo('body')
733
-
734
- setTimeout("$('#error').remove()", 2000)
735
- },
736
-
737
- generateEvent: function (event, params) {
738
- if (event === 'mousemove' || event === 'joystick') {
739
- if (this.ack_wait < wdi.SPICE_INPUT_MOTION_ACK_BUNCH) {
740
- this.ack_wait++
741
- this.fire('input', [event, params])
742
- }
743
- } else {
744
- if (event.indexOf('key') > -1) {
745
- // it's a keyEvent
746
- this.stuckKeysHandler.checkSpecialKey(event, params[0]['keyCode'])
747
- if (!this.shouldGenerateKeyEvents(params[0]['keyCode'])) {
748
- // Special keys should not generate keyEvents
749
- return
750
- }
751
- var val = event === 'keypress' ? this.inputManager.getValue() : ''
752
-
753
- event === 'keypress' && $('#inputmanager').val('')
754
-
755
- if (val) {
756
- params = this.inputManager.manageChar(val, params)
757
- }
758
- }
759
- this.fire('input', [event, params])
760
- }
761
- },
762
-
763
- shouldGenerateKeyEvents: function (keyCode) {
764
- return !this.inputManager.isSpecialKey(keyCode)
765
- },
766
-
767
- motion_ack: function () {
768
- this.ack_wait = 0
769
- },
770
-
771
- setMouseMode: function (mode) {
772
- this.mouse_mode = mode
773
- },
774
-
775
- handleKey: function (e) {
776
- e.data[0].generateEvent.call(e.data[0], e.type, [e])
777
-
778
- if (wdi.Keymap.isInKeymap(e.keyCode) && e.type !== 'keypress') {
779
- e.preventDefault()
780
- }
781
- },
782
-
783
- setClientOffset: function (x, y) {
784
- this.clientOffsetX = x
785
- this.clientOffsetY = y
786
- },
787
-
788
- setClipBoardData: function (data) {
789
- //we have received new clipboard data
790
- //show to the user
791
- //TODO: create a new dialog with buttons to copy the data directly
792
- //from the textbox
793
- //prompt("New clipboard data available, press ctrl+c to copy it", data);
794
- navigator.clipboard.writeText(data)
795
- },
796
-
797
- setToLocalClipboard: function (data) {
798
- this.localClipboard.updateClipboardBuffer(data.value)
799
- },
800
-
801
- getStuckKeysHandler: function () {
802
- return this.stuckKeysHandler
803
- },
804
-
805
- initSound: function () {
806
- var self = this
807
- if (!Modernizr.touch) {
808
- this.soundStarted = true
809
- window.setTimeout(function () {
810
- self.fire('startAudio')
811
- }, 100)
812
- } else {
813
- var $button = $('<button>Start</button>', { id: 'startAudio' })
814
- .css({
815
- padding: '10px 25px',
816
- fontSize: '25px',
817
- fontFamily: 'Verdana',
818
- cursor: 'pointer',
819
- margin: '0 auto',
820
- })
821
- .click(function () {
822
- self.soundStarted = true
823
- self.fire('startAudio')
824
- $('#soundButtonContainer').remove()
825
- })
826
-
827
- var $messageContainer = $(
828
- '<div id="messageContainer"><p>Click to start using your virtual session:</p></div>'
829
- ).css({
830
- color: 'white',
831
- textAlign: 'center',
832
- fontSize: '25px',
833
- fontFamily: 'Verdana',
834
- marginTop: '75px',
835
- })
836
-
837
- var $container = $('<div></div>', { id: 'soundButtonContainer' })
838
-
839
- $button.appendTo($messageContainer)
840
- $messageContainer.appendTo($container)
841
- $container.appendTo('body')
842
-
843
- $container.css({
844
- position: 'absolute',
845
- zIndex: 999999999,
846
- top: 0,
847
- left: 0,
848
- width: '100%',
849
- height: document.height,
850
- backgroundColor: 'black',
851
- })
852
- }
853
- },
854
- })
1
+ /*
2
+ Copyright (c) 2016 eyeOS
3
+
4
+ This file is part of Open365.
5
+
6
+ Open365 is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Affero General Public License as
8
+ published by the Free Software Foundation, either version 3 of the
9
+ License, or (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Affero General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Affero General Public License
17
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ wdi.SPICE_INPUT_MOTION_ACK_BUNCH = 8
21
+
22
+ wdi.ClientGui = $.spcExtend(wdi.EventObject.prototype, {
23
+ width: null,
24
+ height: null,
25
+ canvas: null,
26
+ ack_wait: 0,
27
+ mouse_mode: 0,
28
+ mouse_status: 0,
29
+ eventLayer: null,
30
+ counter: 0,
31
+ mainCanvas: 0,
32
+ firstTime: true,
33
+ clientOffsetX: 0,
34
+ clientOffsetY: 0,
35
+ magnifier: null,
36
+ magnifierBackground: null,
37
+ firstMove: true,
38
+ isMagnified: true,
39
+ isMouseDown: false,
40
+ soundStarted: false,
41
+ canvasMarginY: 0,
42
+ canvasMarginX: 0,
43
+ stuckKeysHandler: null,
44
+ isKeyboardEnabled: false,
45
+
46
+ subCanvas: {},
47
+ inputManager: null,
48
+ clipboardEnabled: true,
49
+ layer: null,
50
+ freezeClass: 'freeze',
51
+ app: {},
52
+
53
+ init: function (c) {
54
+ this.time = Date.now()
55
+ this.canvas = {}
56
+ this.contexts = {}
57
+ this.superInit()
58
+ this.magnifier = window
59
+ .$('<canvas/>')
60
+ .attr({
61
+ width: 150,
62
+ height: 150,
63
+ })
64
+ .css({
65
+ position: 'absolute',
66
+ left: '0px',
67
+ top: '0px',
68
+ })
69
+ this.stuckKeysHandler = c.stuckKeysHandler || new wdi.StuckKeysHandler()
70
+ this.settings = c.settings || {}
71
+ this.stuckKeysHandler.addListener(
72
+ 'inputStuck',
73
+ this._sendInput.bind(this),
74
+ this
75
+ )
76
+
77
+ //load magnifier background
78
+ this.magnifierBackground = window.$('<img/>')
79
+ this.magnifierBackground.attr(
80
+ 'src',
81
+ '/spice-console/resources/magnifier.png'
82
+ )
83
+ this.initSound()
84
+ this.inputManager =
85
+ c.inputManager ||
86
+ new wdi.InputManager({
87
+ stuckKeysHandler: this.stuckKeysHandler,
88
+ window: $(window),
89
+ })
90
+ this.inputManager.setCurrentWindow(window)
91
+ this.clipBoardDataParser =
92
+ c.clipBoardDataParser || new wdi.ClipboardDataParser({})
93
+ this.localClipboard =
94
+ c.localClipboard || new wdi.LocalClipboard({ clientGui: this })
95
+ this.app = c.app
96
+
97
+ var self = this
98
+ this.eventHandlers = {
99
+ hide: function () {
100
+ self.stuckKeysHandler.releaseAllKeys()
101
+ },
102
+ }
103
+ window.$(document).on(this.eventHandlers)
104
+ },
105
+
106
+ dispose: function () {
107
+ wdi.Debug.log('Disposing ClientGui')
108
+ $(document).off(this.eventHandlers)
109
+ this.unbindDOM()
110
+ this.removeAllCanvases()
111
+ this.inputManager.dispose()
112
+ this.stuckKeysHandler.dispose()
113
+ this.localClipboard.dispose()
114
+
115
+ this.width = null
116
+ this.height = null
117
+ this.canvas = null
118
+ this.ack_wait = 0
119
+ this.mouse_mode = 0
120
+ this.mouse_status = 0
121
+ this.eventLayer = null
122
+ this.counter = 0
123
+ this.mainCanvas = 0
124
+ this.firstTime = true
125
+ this.clientOffsetX = 0
126
+ this.clientOffsetY = 0
127
+ this.magnifier = null
128
+ this.magnifierBackground = null
129
+ this.firstMove = true
130
+ this.isMagnified = true
131
+ this.isMouseDown = false
132
+ this.soundStarted = false
133
+ this.canvasMarginY = 0
134
+ this.canvasMarginX = 0
135
+ this.stuckKeysHandler = null
136
+ this.subCanvas = {}
137
+ this.inputManager = null
138
+ this.clipboardEnabled = true
139
+ this.layer = null
140
+ clearInterval(self.rightClickTimer) //cancel, this is not a right click
141
+ clearInterval(self.mouseDownTimer) //cancel
142
+ },
143
+
144
+ removeAllCanvases: function () {
145
+ var self = this
146
+ Object.keys(this.canvas).forEach(function (key) {
147
+ $(self.canvas[key]).remove()
148
+ delete self.canvas[key]
149
+ delete self.contexts[key]
150
+ })
151
+ $(this.eventLayer).remove()
152
+ this.eventLayer = null
153
+ },
154
+
155
+ unbindDOM: function () {
156
+ if (this.eventLayer) {
157
+ var events = [
158
+ 'touchstart',
159
+ 'touchmove',
160
+ 'touchend',
161
+ 'mouseup',
162
+ 'mousedown',
163
+ 'mousemove',
164
+ 'contextmenu',
165
+ 'mousewheel',
166
+ ]
167
+ events.forEach(function (event) {
168
+ $(this.eventLayer).unbind(event)
169
+ })
170
+ }
171
+ },
172
+
173
+ freeze: function () {
174
+ if (this.canvas[0]) {
175
+ var image = new Image()
176
+ var cnv = this.canvas[0]
177
+ var $cnv = $(cnv)
178
+ $(image).attr('style', $cnv.attr('style'))
179
+ $(image).attr('class', this.freezeClass)
180
+ image.src = cnv.toDataURL('image/png')
181
+ $cnv.parent().append($(image))
182
+ }
183
+ },
184
+
185
+ cancelFreeze: function () {
186
+ $('.' + this.freezeClass).remove()
187
+ },
188
+
189
+ setLayer: function (layer) {
190
+ this.layer = layer
191
+ },
192
+
193
+ disableClipboard: function () {
194
+ this.clipboardEnabled = false
195
+ },
196
+
197
+ _sendInput: function (params) {
198
+ var data = params
199
+ var type = data[0]
200
+ var event = data[1]
201
+ this.fire('input', [type, event])
202
+ },
203
+
204
+ releaseAllKeys: function () {
205
+ this.stuckKeysHandler.releaseAllKeys()
206
+ },
207
+
208
+ getContext: function (surface_id) {
209
+ return this.contexts[surface_id]
210
+ },
211
+
212
+ getCanvas: function (surface_id) {
213
+ return this.canvas[surface_id]
214
+ },
215
+
216
+ checkFeatures: function () {
217
+ if (!Modernizr.canvas || !Modernizr.websockets) {
218
+ alert(
219
+ 'Your Browser is not compatible with WDI. Visit ... for a list of compatible browsers'
220
+ )
221
+ return false
222
+ }
223
+ return true
224
+ },
225
+
226
+ deleteSubCanvas: function (window) {
227
+ var obj = this.subCanvas[window['hwnd']]
228
+ this.subCanvas[window['hwnd']] = null
229
+ return obj
230
+ },
231
+
232
+ moveSubCanvas: function (window) {
233
+ var obj = this.subCanvas[window['hwnd']]
234
+ obj['info'] = window
235
+ this._fillSubCanvasFromWindow(window)
236
+ return obj
237
+ },
238
+
239
+ resizeSubCanvas: function (window) {
240
+ var obj = this.subCanvas[window['hwnd']]
241
+ $([obj['canvas'], obj['eventLayer']]).attr({
242
+ width: window['width'],
243
+ height: window['height'],
244
+ })
245
+ obj['info'] = window
246
+ this._fillSubCanvasFromWindow(window)
247
+ return obj
248
+ },
249
+
250
+ _fillSubCanvasFromWindow: function (window) {
251
+ var top = parseInt(window.top, 10)
252
+ var left = parseInt(window.left, 10)
253
+ var width = parseInt(window.width, 10)
254
+ var height = parseInt(window.height, 10)
255
+ this.fillSubCanvas({
256
+ top: top,
257
+ left: left,
258
+ right: left + width,
259
+ bottom: top + height,
260
+ })
261
+ },
262
+
263
+ createNewSubCanvas: function (window) {
264
+ var evtlayer = this.createEventLayer(
265
+ window['hwnd'] + '_event',
266
+ window['width'],
267
+ window['height']
268
+ )
269
+ this.subCanvas[window['hwnd']] = {
270
+ canvas: $('<canvas/>')
271
+ .attr({
272
+ width: window['width'],
273
+ height: window['height'],
274
+ })
275
+ .css({
276
+ display: window['iconic'] ? 'none' : 'block',
277
+ })[0],
278
+ eventLayer: evtlayer,
279
+ info: window,
280
+ position: 0,
281
+ }
282
+ //we have the main area drawn?
283
+ if (this.canvas[this.mainCanvas]) {
284
+ this._fillSubCanvasFromWindow(window)
285
+ }
286
+ return [this.subCanvas[window['hwnd']]]
287
+ },
288
+
289
+ fillSubCanvas: function (filterPosition) {
290
+ var canvas = this.canvas[this.mainCanvas]
291
+ var info = null
292
+ for (var i in this.subCanvas) {
293
+ if (
294
+ this.subCanvas[i] != null &&
295
+ this.subCanvas[i] !== undefined &&
296
+ this.subCanvas.hasOwnProperty(i)
297
+ ) {
298
+ info = this.subCanvas[i]['info']
299
+ if (filterPosition != null || filterPosition != undefined) {
300
+ var top = parseInt(info['top'], 10)
301
+ var left = parseInt(info['left'], 10)
302
+ var width = parseInt(info['width'], 10)
303
+ var height = parseInt(info['height'], 10)
304
+ var position = {
305
+ top: top,
306
+ left: left,
307
+ right: left + width,
308
+ bottom: top + height,
309
+ }
310
+ if (
311
+ wdi.CollisionDetector.thereIsBoxCollision(position, filterPosition)
312
+ ) {
313
+ this._doDrawSubCanvas(canvas, this.subCanvas[i], info)
314
+ }
315
+ } else {
316
+ this._doDrawSubCanvas(canvas, this.subCanvas[i], info)
317
+ }
318
+ }
319
+ }
320
+ },
321
+
322
+ _doDrawSubCanvas: function (canvas, subCanvas, info) {
323
+ if (
324
+ this.canvas[this.mainCanvas] == null ||
325
+ this.canvas[this.mainCanvas] == undefined
326
+ ) {
327
+ return
328
+ }
329
+ var destCtx = null
330
+ if (info['iconic'] === 0) {
331
+ var destCanvas = subCanvas['canvas']
332
+ destCtx = destCanvas.getContext('2d')
333
+
334
+ var x = 0
335
+ var y = 0
336
+ var width = +info.width
337
+ var height = +info.height
338
+ var left = +info['left']
339
+ var top = +info['top']
340
+
341
+ if (left < 0) {
342
+ width = width + left
343
+ x = -left
344
+ left = 0
345
+ }
346
+
347
+ if (top < 0) {
348
+ height = height + top
349
+ y = -top
350
+ top = 0
351
+ }
352
+
353
+ try {
354
+ // if width or height are less than 1 or a float
355
+ // drawImage fails in firefox (ERROR: IndexSizeError)
356
+ width = Math.max(1, Math.floor(width))
357
+ height = Math.max(1, Math.floor(height))
358
+ if (width > canvas.width) width = canvas.width
359
+ if (height > canvas.height) height = canvas.height
360
+ destCtx.drawImage(canvas, left, top, width, height, x, y, width, height)
361
+ } catch (err) {
362
+ wdi.Debug.error(err)
363
+ }
364
+ }
365
+ },
366
+
367
+ removeCanvas: function (spiceMessage) {
368
+ var surface = spiceMessage.args
369
+ if (surface.surface_id === this.mainCanvas) {
370
+ $(this.eventLayer).remove()
371
+ this.eventLayer = null
372
+ }
373
+
374
+ this.canvas[surface.surface_id].keepAlive = false
375
+ delete this.canvas[surface.surface_id]
376
+ delete this.contexts[surface.surface_id]
377
+ },
378
+
379
+ drawCanvas: function (spiceMessage) {
380
+ wdi.Debug.log('clientgui time: ', this.time)
381
+ var surface = spiceMessage.args
382
+
383
+ // // Custom code
384
+ // // Проверяем если ширина вм-а меньше ширины окна, вставляем по центру
385
+ // if (surface.width < window.innerWidth) {
386
+ // const x = (window.innerWidth - surface.width) / 2
387
+ // this.setCanvasMargin({
388
+ // x,
389
+ // y: this.canvasMarginY,
390
+ // })
391
+ // this.setClientOffset(-x, this.canvasMarginY)
392
+ // }
393
+ // // Custom code End
394
+
395
+ var cnv = wdi.GlobalPool.create('Canvas')
396
+ cnv.keepAlive = true //prevent this canvas to return to the pool by packetfilter
397
+
398
+ cnv.id = 'canvas_' + surface.surface_id
399
+ cnv.width = surface.width * this.pixelRatio
400
+ cnv.height = surface.height * this.pixelRatio
401
+ cnv.style.position = 'absolute'
402
+ cnv.style.top = this.canvasMarginY + 'px'
403
+ cnv.style.left = this.canvasMarginX + 'px'
404
+ cnv.style.width = surface.width + 'px'
405
+ cnv.style.height = surface.height + 'px'
406
+
407
+ this.canvas[surface.surface_id] = cnv
408
+ this.contexts[surface.surface_id] = cnv.getContext('2d')
409
+
410
+ if (surface.flags && !wdi.SeamlessIntegration) {
411
+ this.mainCanvas = surface.surface_id
412
+
413
+ this.eventLayer = this.createEventLayer(
414
+ 'eventLayer',
415
+ surface.width,
416
+ surface.height
417
+ )
418
+
419
+ var evLayer = $(this.eventLayer).css({
420
+ position: 'absolute',
421
+ top: this.canvasMarginY + 'px',
422
+ left: this.canvasMarginX + 'px',
423
+ })[0]
424
+
425
+ if (this.layer) {
426
+ this.layer.appendChild(cnv)
427
+ this.layer.appendChild(evLayer)
428
+ } else {
429
+ document.body.appendChild(cnv)
430
+ document.body.appendChild(evLayer)
431
+ }
432
+ !this.isKeyboardEnabled && this.enableKeyboard()
433
+ }
434
+
435
+ //this goes here?
436
+ if (this.firstTime && this.clipboardEnabled) {
437
+ var self = this
438
+ var PASTES_PER_SECOND = this.settings.PASTES_PER_SECOND || 5
439
+
440
+ var firePaste = _.throttle(function (data) {
441
+ self.fire('paste', data)
442
+ }, 1000 / PASTES_PER_SECOND)
443
+
444
+ $(document).bind('paste', function (event) {
445
+ self.clipBoardDataParser.parse(
446
+ event.originalEvent.clipboardData,
447
+ firePaste
448
+ )
449
+ })
450
+
451
+ $(document).bind('copy', function (e) {
452
+ self.app.sendShortcut(wdi.keyShortcutsHandled.CTRLC)
453
+ })
454
+
455
+ this.firstTime = false
456
+ }
457
+
458
+ //notify about resolution
459
+ if (surface.flags) {
460
+ this.fire('resolution', [
461
+ this.canvas[surface.surface_id].width,
462
+ this.canvas[surface.surface_id].height,
463
+ ])
464
+ }
465
+ },
466
+
467
+ disableKeyboard: function () {
468
+ var documentDOM = window.$(window.document)
469
+ documentDOM.unbind('keydown', this.handleKey)
470
+ documentDOM.unbind('keyup', this.handleKey)
471
+ documentDOM.unbind('keypress', this.handleKey)
472
+ this.inputManager.disable()
473
+ },
474
+
475
+ enableKeyboard: function () {
476
+ var self = this,
477
+ documentDOM = window.$(window.document)
478
+ documentDOM['keydown']([self], this.handleKey)
479
+ documentDOM['keypress']([self], this.handleKey)
480
+ documentDOM['keyup']([self], this.handleKey)
481
+ this.inputManager.enable()
482
+ !this.isKeyboardEnabled && (this.isKeyboardEnabled = true)
483
+ },
484
+
485
+ setCanvasMargin: function (canvasMargin) {
486
+ this.canvasMarginX = canvasMargin.x
487
+ this.canvasMarginY = canvasMargin.y
488
+ },
489
+
490
+ createEventLayer: function (event_id, width, height) {
491
+ var self = this
492
+
493
+ var eventLayer = $('<canvas/>')
494
+ .css({
495
+ cursor: 'default',
496
+ position: 'absolute',
497
+ })
498
+ .attr({
499
+ id: event_id,
500
+ // width: window.innerWidth,
501
+ // height: window.innerHeight
502
+ // Правильнее слой события делать с размером самого вм-а
503
+ width, // Custom code
504
+ height, // Custom code
505
+ })
506
+
507
+ if (window['bowser']['firefox']) {
508
+ eventLayer.attr('contentEditable', true)
509
+ }
510
+
511
+ eventLayer.bind('touchstart', function (event) {
512
+ event.preventDefault()
513
+ var touch =
514
+ event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]
515
+ var x = touch.pageX
516
+ var y = touch.pageY
517
+ self.generateEvent.call(self, 'mousemove', [
518
+ x + self.clientOffsetX,
519
+ y + self.clientOffsetY,
520
+ self.mouse_status,
521
+ ])
522
+ if (event.originalEvent.touches.length === 1) {
523
+ self.enabledTouchMove = true
524
+ self.launchRightClick.call(self, x, y)
525
+ } else if (event.originalEvent.touches.length === 2) {
526
+ self.touchX = x
527
+ self.touchY = y
528
+ self.enabledTouchMove = false
529
+ } else if (event.originalEvent.touches.length === 3) {
530
+ self.touchY3 = y
531
+ self.enabledTouchMove = false
532
+ }
533
+ })
534
+
535
+ eventLayer.bind('touchmove', function (event) {
536
+ var touch =
537
+ event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]
538
+ var x = touch.pageX
539
+ var y = touch.pageY
540
+ //TODO: ignore first move
541
+ if (event.originalEvent.touches.length === 1 && self.enabledTouchMove) {
542
+ self.isMagnified = true //magnified!
543
+ clearInterval(self.rightClickTimer) //cancel, this is not a right click
544
+
545
+ if (!self.isMouseDown) {
546
+ clearInterval(self.mouseDownTimer) //cancel, not enough time to send mousedown
547
+ self.launchMouseDown() //fire again
548
+ }
549
+
550
+ self.generateEvent.call(self, 'mousemove', [
551
+ x + self.clientOffsetX,
552
+ y + self.clientOffsetY - 80,
553
+ self.mouse_status,
554
+ ])
555
+ var pos = $(this).offset()
556
+ var myX = x - pos.left
557
+ var myY = y - pos.top
558
+
559
+ //draw magnifier
560
+ if (self.firstMove) {
561
+ $('body').append(self.magnifier) //TODO: append to body?
562
+ self.firstMove = false
563
+ }
564
+
565
+ var posX = myX - 75
566
+ var posY = myY - 160
567
+
568
+ self.magnifier.css({
569
+ left: posX,
570
+ top: posY,
571
+ })
572
+
573
+ //fill magnifier
574
+ var ctx = self.magnifier[0].getContext('2d')
575
+ ctx.clearRect(0, 0, 150, 150)
576
+ ctx.save()
577
+ ctx.beginPath()
578
+ ctx.arc(75, 75, 75, 0, 2 * Math.PI, false)
579
+ ctx.clip()
580
+ ctx.drawImage(
581
+ self.getCanvas(0),
582
+ myX - 50, //-50 because we are going to get
583
+ myY - 50 - 80, //100 px and we want the finder to be the center
584
+ //-80 becasue the magnifier is 160px up (160/2)
585
+ //we need to clean all this after the demo
586
+ //is working
587
+ 100,
588
+ 100,
589
+ 0,
590
+ 0,
591
+ 150,
592
+ 150
593
+ )
594
+ // //draw the background
595
+ ctx.drawImage(self.magnifierBackground[0], 0, 0)
596
+ ctx.restore()
597
+ //empty magnifier
598
+ } else if (event.originalEvent.touches.length === 2) {
599
+ var delta = self.touchY - y
600
+ if (Math.abs(delta) > 10) {
601
+ var button = delta > 0 ? 4 : 3
602
+ self.touchX = x
603
+ self.touchY = y
604
+ self.generateEvent.call(self, 'mousedown', button)
605
+ self.generateEvent.call(self, 'mouseup', button)
606
+ }
607
+ } else if (event.originalEvent.touches.length === 3) {
608
+ var delta = self.touchY3 - y
609
+ if (delta > 100) {
610
+ document.getElementById('hiddeninput').select()
611
+ }
612
+ }
613
+ event.preventDefault()
614
+ })
615
+
616
+ eventLayer.bind('touchend', function (event) {
617
+ if (self.enabledTouchMove) {
618
+ var touch =
619
+ event.originalEvent.touches[0] ||
620
+ event.originalEvent.changedTouches[0]
621
+ var x = touch.pageX
622
+ var y = touch.pageY
623
+ if (!self.isMouseDown) {
624
+ self.generateEvent.call(self, 'mousedown', 0)
625
+ }
626
+ self.isMouseDown = false
627
+ self.generateEvent.call(self, 'mouseup', 0)
628
+ var pos = $(this).offset()
629
+
630
+ self.enabledTouchMove = false
631
+ self.firstMove = true
632
+ if (self.isMagnified) {
633
+ self.magnifier.remove()
634
+ }
635
+ self.isMagnified = false
636
+ }
637
+ clearInterval(self.rightClickTimer) //cancel, this is not a right click
638
+ clearInterval(self.mouseDownTimer) //cancel
639
+ })
640
+
641
+ //if (!Modernizr.touch) {
642
+ eventLayer['mouseup'](function (event) {
643
+ var button = event.button
644
+
645
+ self.generateEvent.call(self, 'mouseup', button)
646
+ self.mouse_status = 0
647
+ event.preventDefault()
648
+ })
649
+
650
+ eventLayer['mousedown'](function (event) {
651
+ var button = event.button
652
+
653
+ self.generateEvent.call(self, 'mousedown', button)
654
+ self.mouse_status = 1
655
+ event.preventDefault()
656
+ })
657
+
658
+ eventLayer['mousemove'](function (event) {
659
+ if (
660
+ self.mouse_mode === wdi.SpiceMouseModeTypes.SPICE_MOUSE_MODE_SERVER &&
661
+ event.bubbles
662
+ )
663
+ return // Custom code // TODO refactoring. event.bubbles используется так как если переключить mouseMode на серверную то mousemove срабатывает дважды
664
+ var x = event.pageX
665
+ var y = event.pageY
666
+ // self.generateEvent.call(self, 'mousemove', [
667
+ // (x + self.clientOffsetX) * self.pixelRatio,
668
+ // (y + self.clientOffsetY) * self.pixelRatio,
669
+ // self.mouse_status,
670
+ // ])
671
+ // Custom code
672
+ self.generateEvent.call(self, 'mousemove', [
673
+ (x + self.clientOffsetX - self.eventLayer.offsetLeft) * self.pixelRatio,
674
+ (y + self.clientOffsetY - self.eventLayer.offsetTop) * self.pixelRatio,
675
+ self.mouse_status,
676
+ ])
677
+ // Custom code End
678
+ event.preventDefault()
679
+ })
680
+
681
+ eventLayer.bind('contextmenu', function (event) {
682
+ event.preventDefault()
683
+ return false
684
+ })
685
+ //}
686
+
687
+ var mouseEventPause = false
688
+
689
+ var fireWheel = _.throttle(function (event, delta) {
690
+ var button = delta > 0 ? 3 : 4
691
+
692
+ self.generateEvent.call(self, 'mousedown', button)
693
+ self.generateEvent.call(self, 'mouseup', button)
694
+
695
+ return false
696
+ }, 60)
697
+
698
+ eventLayer.bind('mousewheel', fireWheel)
699
+
700
+ this.fire('eventLayerCreated', eventLayer[0])
701
+
702
+ wdi.VirtualMouse.setEventLayer(eventLayer[0], 0, 0, width, height, 1)
703
+ return eventLayer[0]
704
+ },
705
+
706
+ launchRightClick: function (x, y) {
707
+ var self = this
708
+ this.rightClickTimer = setTimeout(function () {
709
+ self.generateEvent.call(self, 'mousedown', 2)
710
+ self.generateEvent.call(self, 'mouseup', 2)
711
+ self.enabledTouchMove = false
712
+ }, 400)
713
+ },
714
+
715
+ launchMouseDown: function (x, y) {
716
+ var self = this
717
+ this.mouseDownTimer = setTimeout(function () {
718
+ self.isMouseDown = true
719
+ self.generateEvent.call(self, 'mousedown', 0)
720
+ }, 1500)
721
+ },
722
+
723
+ showError: function (message) {
724
+ wdi.Debug.warn(message)
725
+ $('<div/>', {
726
+ id: 'error',
727
+ })
728
+ .html(message)
729
+ .css({
730
+ 'background-color': '#ff4141',
731
+ })
732
+ .appendTo('body')
733
+
734
+ setTimeout("$('#error').remove()", 2000)
735
+ },
736
+
737
+ generateEvent: function (event, params) {
738
+ if (event === 'mousemove' || event === 'joystick') {
739
+ if (this.ack_wait < wdi.SPICE_INPUT_MOTION_ACK_BUNCH) {
740
+ this.ack_wait++
741
+ this.fire('input', [event, params])
742
+ }
743
+ } else {
744
+ if (event.indexOf('key') > -1) {
745
+ // it's a keyEvent
746
+ this.stuckKeysHandler.checkSpecialKey(event, params[0]['keyCode'])
747
+ if (!this.shouldGenerateKeyEvents(params[0]['keyCode'])) {
748
+ // Special keys should not generate keyEvents
749
+ return
750
+ }
751
+ var val = event === 'keypress' ? this.inputManager.getValue() : ''
752
+
753
+ event === 'keypress' && $('#inputmanager').val('')
754
+
755
+ if (val) {
756
+ params = this.inputManager.manageChar(val, params)
757
+ }
758
+ }
759
+ this.fire('input', [event, params])
760
+ }
761
+ },
762
+
763
+ shouldGenerateKeyEvents: function (keyCode) {
764
+ return !this.inputManager.isSpecialKey(keyCode)
765
+ },
766
+
767
+ motion_ack: function () {
768
+ this.ack_wait = 0
769
+ },
770
+
771
+ setMouseMode: function (mode) {
772
+ this.mouse_mode = mode
773
+ },
774
+
775
+ handleKey: function (e) {
776
+ e.data[0].generateEvent.call(e.data[0], e.type, [e])
777
+
778
+ if (wdi.Keymap.isInKeymap(e.keyCode) && e.type !== 'keypress') {
779
+ e.preventDefault()
780
+ }
781
+ },
782
+
783
+ setClientOffset: function (x, y) {
784
+ this.clientOffsetX = x
785
+ this.clientOffsetY = y
786
+ },
787
+
788
+ setClipBoardData: function (data) {
789
+ //we have received new clipboard data
790
+ //show to the user
791
+ //TODO: create a new dialog with buttons to copy the data directly
792
+ //from the textbox
793
+ //prompt("New clipboard data available, press ctrl+c to copy it", data);
794
+ navigator.clipboard.writeText(data)
795
+ },
796
+
797
+ setToLocalClipboard: function (data) {
798
+ this.localClipboard.updateClipboardBuffer(data.value)
799
+ },
800
+
801
+ getStuckKeysHandler: function () {
802
+ return this.stuckKeysHandler
803
+ },
804
+
805
+ initSound: function () {
806
+ var self = this
807
+ if (!Modernizr.touch) {
808
+ this.soundStarted = true
809
+ window.setTimeout(function () {
810
+ self.fire('startAudio')
811
+ }, 100)
812
+ } else {
813
+ var $button = $('<button>Start</button>', { id: 'startAudio' })
814
+ .css({
815
+ padding: '10px 25px',
816
+ fontSize: '25px',
817
+ fontFamily: 'Verdana',
818
+ cursor: 'pointer',
819
+ margin: '0 auto',
820
+ })
821
+ .click(function () {
822
+ self.soundStarted = true
823
+ self.fire('startAudio')
824
+ $('#soundButtonContainer').remove()
825
+ })
826
+
827
+ var $messageContainer = $(
828
+ '<div id="messageContainer"><p>Click to start using your virtual session:</p></div>'
829
+ ).css({
830
+ color: 'white',
831
+ textAlign: 'center',
832
+ fontSize: '25px',
833
+ fontFamily: 'Verdana',
834
+ marginTop: '75px',
835
+ })
836
+
837
+ var $container = $('<div></div>', { id: 'soundButtonContainer' })
838
+
839
+ $button.appendTo($messageContainer)
840
+ $messageContainer.appendTo($container)
841
+ $container.appendTo('body')
842
+
843
+ $container.css({
844
+ position: 'absolute',
845
+ zIndex: 999999999,
846
+ top: 0,
847
+ left: 0,
848
+ width: '100%',
849
+ height: document.height,
850
+ backgroundColor: 'black',
851
+ })
852
+ }
853
+ },
854
+ })