missed kasm vnc changes
This commit is contained in:
parent
be658061e8
commit
3350bdd36e
194
load.html
194
load.html
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="noVNC_loading">
|
||||
<html lang="en" class="noVNC_loading">
|
||||
<head>
|
||||
|
||||
<!--
|
||||
noVNC example: simple example using default UI
|
||||
Copyright (C) 2018 The noVNC Authors
|
||||
Copyright (C) 2019 The noVNC Authors
|
||||
noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
|
||||
This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
|
||||
|
||||
|
@ -15,11 +15,7 @@
|
|||
-->
|
||||
<title>KasmVNC</title>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
|
||||
Remove this if you use the .htaccess -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!-- Icons (see app/images/icons/Makefile for what the sizes are for) -->
|
||||
<link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/368_kasm_logo_only_16x16.png">
|
||||
|
@ -42,9 +38,9 @@
|
|||
<link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/368_kasm_logo_only_16x16.png">
|
||||
|
||||
<!-- Apple iOS Safari settings -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<!-- Home Screen Icons (favourites and bookmarks use the normal icons) -->
|
||||
<link rel="apple-touch-icon" sizes="60x60" type="image/png" href="app/images/icons/368_kasm_logo_only_60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" type="image/png" href="app/images/icons/368_kasm_logo_only_76x76.png">
|
||||
|
@ -52,39 +48,33 @@
|
|||
<link rel="apple-touch-icon" sizes="152x152" type="image/png" href="app/images/icons/368_kasm_logo_only_152x152.png">
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<!-- <link rel="stylesheet" href="app/styles/base.css" /> -->
|
||||
<link rel="stylesheet" href="app/styles/base.css">
|
||||
|
||||
<!-- this is included as a normal file in order to catch script-loading errors as well -->
|
||||
<!-- <script type="text/javascript" src="app/error-handler.js"></script> -->
|
||||
<script src="app/error-handler.js"></script>
|
||||
|
||||
<!-- begin scripts -->
|
||||
<!-- promise polyfills promises for IE11 -->
|
||||
<!-- <script src="vendor/promise.js"></script> -->
|
||||
<!-- ES2015/ES6 modules polyfill -->
|
||||
<!-- <script type="module">
|
||||
window._noVNC_has_module_support = true;
|
||||
</script> -->
|
||||
<!-- <script>
|
||||
window.addEventListener("load", function() {
|
||||
if (window._noVNC_has_module_support) return;
|
||||
var loader = document.createElement("script");
|
||||
loader.src = "vendor/browser-es-module-loader/dist/browser-es-module-loader.js";
|
||||
document.head.appendChild(loader);
|
||||
});
|
||||
<script>
|
||||
let isInsideKasmVDI = false;
|
||||
try {
|
||||
isInsideKasmVDI = (window.self !== window.top);
|
||||
} catch (e) {
|
||||
isInsideKasmVDI = true;
|
||||
}
|
||||
|
||||
if (!isInsideKasmVDI) {
|
||||
window.addEventListener("load", function() {
|
||||
document.getElementById("noVNC_connect_button").click();
|
||||
});
|
||||
</script> -->
|
||||
<!-- actual script modules -->
|
||||
<!-- <script type="module" crossorigin='use-credentials' src="app/ui.js"></script> -->
|
||||
<!-- end scripts -->
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="module" crossorigin="use-credentials" src="app/ui.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="noVNC_fallback_error" class="noVNC_center">
|
||||
<div>
|
||||
<div>Kasm encountered an error:</div>
|
||||
<div>noVNC encountered an error:</div>
|
||||
<br>
|
||||
<div id="noVNC_fallback_errormsg"></div>
|
||||
</div>
|
||||
|
@ -105,106 +95,91 @@
|
|||
<h1 class="noVNC_logo"><img src="app/images/icons/368_kasm_logo_only_24x24.png" /></h1>
|
||||
|
||||
<!-- Drag/Pan the viewport -->
|
||||
<img alt="viewport drag" src="app/images/drag.svg"
|
||||
<input type="image" alt="Drag" src="app/images/drag.svg"
|
||||
id="noVNC_view_drag_button" class="noVNC_button noVNC_hidden"
|
||||
title="Move/Drag Viewport" />
|
||||
title="Move/Drag Viewport">
|
||||
|
||||
<!--noVNC Touch Device only buttons-->
|
||||
<div id="noVNC_mobile_buttons">
|
||||
<img alt="No mousebutton" src="app/images/mouse_none.svg"
|
||||
id="noVNC_mouse_button0" class="noVNC_button"
|
||||
title="Active Mouse Button"/>
|
||||
<img alt="Left mousebutton" src="app/images/mouse_left.svg"
|
||||
id="noVNC_mouse_button1" class="noVNC_button"
|
||||
title="Active Mouse Button"/>
|
||||
<img alt="Middle mousebutton" src="app/images/mouse_middle.svg"
|
||||
id="noVNC_mouse_button2" class="noVNC_button"
|
||||
title="Active Mouse Button"/>
|
||||
<img alt="Right mousebutton" src="app/images/mouse_right.svg"
|
||||
id="noVNC_mouse_button4" class="noVNC_button"
|
||||
title="Active Mouse Button"/>
|
||||
<img alt="Keyboard" src="app/images/keyboard.svg"
|
||||
id="noVNC_keyboard_button" class="noVNC_button"
|
||||
value="Keyboard" title="Show Keyboard" />
|
||||
<input type="image" alt="Keyboard" src="app/images/keyboard.svg"
|
||||
id="noVNC_keyboard_button" class="noVNC_button" title="Show Keyboard">
|
||||
</div>
|
||||
|
||||
<!-- Extra manual keys -->
|
||||
<div id="noVNC_extra_keys">
|
||||
<img alt="Extra keys" src="app/images/toggleextrakeys.svg"
|
||||
<input type="image" alt="Extra keys" src="app/images/toggleextrakeys.svg"
|
||||
id="noVNC_toggle_extra_keys_button" class="noVNC_button"
|
||||
title="Show Extra Keys"/>
|
||||
title="Show Extra Keys">
|
||||
<div class="noVNC_vcenter">
|
||||
<div id="noVNC_modifiers" class="noVNC_panel">
|
||||
<img alt="Ctrl" src="app/images/ctrl.svg"
|
||||
<input type="image" alt="Ctrl" src="app/images/ctrl.svg"
|
||||
id="noVNC_toggle_ctrl_button" class="noVNC_button"
|
||||
title="Toggle Ctrl"/>
|
||||
<img alt="Alt" src="app/images/alt.svg"
|
||||
title="Toggle Ctrl">
|
||||
<input type="image" alt="Alt" src="app/images/alt.svg"
|
||||
id="noVNC_toggle_alt_button" class="noVNC_button"
|
||||
title="Toggle Alt"/>
|
||||
<img alt="Windows" src="app/images/windows.svg"
|
||||
title="Toggle Alt">
|
||||
<input type="image" alt="Windows" src="app/images/windows.svg"
|
||||
id="noVNC_toggle_windows_button" class="noVNC_button"
|
||||
title="Toggle Windows"/>
|
||||
<img alt="Tab" src="app/images/tab.svg"
|
||||
title="Toggle Windows">
|
||||
<input type="image" alt="Tab" src="app/images/tab.svg"
|
||||
id="noVNC_send_tab_button" class="noVNC_button"
|
||||
title="Send Tab"/>
|
||||
<img alt="Esc" src="app/images/esc.svg"
|
||||
title="Send Tab">
|
||||
<input type="image" alt="Esc" src="app/images/esc.svg"
|
||||
id="noVNC_send_esc_button" class="noVNC_button"
|
||||
title="Send Escape"/>
|
||||
<img alt="Ctrl+Alt+Del" src="app/images/ctrlaltdel.svg"
|
||||
title="Send Escape">
|
||||
<input type="image" alt="Ctrl+Alt+Del" src="app/images/ctrlaltdel.svg"
|
||||
id="noVNC_send_ctrl_alt_del_button" class="noVNC_button"
|
||||
title="Send Ctrl-Alt-Del" />
|
||||
</div>
|
||||
title="Send Ctrl-Alt-Del">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shutdown/Reboot -->
|
||||
<img alt="Shutdown/Reboot" src="app/images/power.svg"
|
||||
<input type="image" alt="Shutdown/Reboot" src="app/images/power.svg"
|
||||
id="noVNC_power_button" class="noVNC_button"
|
||||
title="Shutdown/Reboot..." />
|
||||
title="Shutdown/Reboot...">
|
||||
<div class="noVNC_vcenter">
|
||||
<div id="noVNC_power" class="noVNC_panel">
|
||||
<div class="noVNC_heading">
|
||||
<img src="app/images/power.svg"> Power
|
||||
<img alt="" src="app/images/power.svg"> Power
|
||||
</div>
|
||||
<input type="button" id="noVNC_shutdown_button" value="Shutdown" />
|
||||
<input type="button" id="noVNC_reboot_button" value="Reboot" />
|
||||
<input type="button" id="noVNC_reset_button" value="Reset" />
|
||||
<input type="button" id="noVNC_shutdown_button" value="Shutdown">
|
||||
<input type="button" id="noVNC_reboot_button" value="Reboot">
|
||||
<input type="button" id="noVNC_reset_button" value="Reset">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Clipboard -->
|
||||
<img alt="Clipboard" src="app/images/clipboard.svg"
|
||||
<input type="image" alt="Clipboard" src="app/images/clipboard.svg"
|
||||
id="noVNC_clipboard_button" class="noVNC_button"
|
||||
title="Clipboard" />
|
||||
title="Clipboard">
|
||||
<div class="noVNC_vcenter">
|
||||
<div id="noVNC_clipboard" class="noVNC_panel">
|
||||
<div class="noVNC_heading">
|
||||
<img src="app/images/clipboard.svg"> Clipboard
|
||||
<img alt="" src="app/images/clipboard.svg"> Clipboard
|
||||
</div>
|
||||
<textarea id="noVNC_clipboard_text" rows=5></textarea>
|
||||
<br />
|
||||
<br>
|
||||
<input id="noVNC_clipboard_clear_button" type="button"
|
||||
value="Clear" class="noVNC_submit" />
|
||||
value="Clear" class="noVNC_submit">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toggle fullscreen -->
|
||||
<img alt="Fullscreen" src="app/images/fullscreen.svg"
|
||||
<input type="image" alt="Fullscreen" src="app/images/fullscreen.svg"
|
||||
id="noVNC_fullscreen_button" class="noVNC_button noVNC_hidden"
|
||||
title="Fullscreen" />
|
||||
title="Fullscreen">
|
||||
|
||||
<!-- Settings -->
|
||||
<img alt="Settings" src="app/images/settings.svg"
|
||||
<input type="image" alt="Settings" src="app/images/settings.svg"
|
||||
id="noVNC_settings_button" class="noVNC_button"
|
||||
title="Settings" />
|
||||
title="Settings">
|
||||
<div class="noVNC_vcenter">
|
||||
<div id="noVNC_settings" class="noVNC_panel">
|
||||
<ul>
|
||||
<li class="noVNC_heading">
|
||||
<img src="app/images/settings.svg"> Settings
|
||||
<img alt="" src="app/images/settings.svg"> Settings
|
||||
</li>
|
||||
<li>
|
||||
<label><input id="noVNC_setting_shared" type="checkbox" /> Shared Mode</label>
|
||||
<label><input id="noVNC_setting_shared" type="checkbox"> Shared Mode</label>
|
||||
</li>
|
||||
<li>
|
||||
<label><input id="noVNC_setting_view_only" type="checkbox" /> View Only</label></li>
|
||||
|
@ -238,7 +213,7 @@
|
|||
</li>
|
||||
<li><hr></li>
|
||||
<li>
|
||||
<label><input id="noVNC_setting_view_clip" type="checkbox" /> Clip to Window</label>
|
||||
<label><input id="noVNC_setting_view_clip" type="checkbox"> Clip to Window</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_resize">Scaling Mode:</label>
|
||||
|
@ -252,41 +227,50 @@
|
|||
<li>
|
||||
<div class="noVNC_expander">Advanced</div>
|
||||
<div><ul>
|
||||
<li>
|
||||
<label for="noVNC_setting_quality">Quality:</label>
|
||||
<input id="noVNC_setting_quality" type="range" min="0" max="9" value="6">
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_compression">Compression level:</label>
|
||||
<input id="noVNC_setting_compression" type="range" min="0" max="9" value="2">
|
||||
</li>
|
||||
<li><hr></li>
|
||||
<li>
|
||||
<label for="noVNC_setting_repeaterID">Repeater ID:</label>
|
||||
<input id="noVNC_setting_repeaterID" type="input" value="" />
|
||||
<input id="noVNC_setting_repeaterID" type="text" value="">
|
||||
</li>
|
||||
<li>
|
||||
<div class="noVNC_expander">WebSocket</div>
|
||||
<div><ul>
|
||||
<li>
|
||||
<label><input id="noVNC_setting_encrypt" type="checkbox" /> Encrypt</label>
|
||||
<label><input id="noVNC_setting_encrypt" type="checkbox"> Encrypt</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_host">Host:</label>
|
||||
<input id="noVNC_setting_host" />
|
||||
<input id="noVNC_setting_host">
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_port">Port:</label>
|
||||
<input id="noVNC_setting_port" type="number" />
|
||||
<input id="noVNC_setting_port" type="number">
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_path">Path:</label>
|
||||
<input id="noVNC_setting_path" type="input" value="websockify" />
|
||||
<input id="noVNC_setting_path" type="text" value="websockify">
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li><hr></li>
|
||||
<li>
|
||||
<label><input id="noVNC_setting_reconnect" type="checkbox" /> Automatic Reconnect</label>
|
||||
<label><input id="noVNC_setting_reconnect" type="checkbox"> Automatic Reconnect</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_reconnect_delay">Reconnect Delay (ms):</label>
|
||||
<input id="noVNC_setting_reconnect_delay" type="number" />
|
||||
<input id="noVNC_setting_reconnect_delay" type="number">
|
||||
</li>
|
||||
<li><hr></li>
|
||||
<li>
|
||||
<label><input id="noVNC_setting_show_dot" type="checkbox" /> Show Dot when No Cursor</label>
|
||||
<label><input id="noVNC_setting_show_dot" type="checkbox"> Show Dot when No Cursor</label>
|
||||
</li>
|
||||
<li><hr></li>
|
||||
<!-- Logging selection dropdown -->
|
||||
|
@ -298,14 +282,19 @@
|
|||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="noVNC_version_separator"><hr></li>
|
||||
<li class="noVNC_version_wrapper">
|
||||
<span>Version:</span>
|
||||
<span class="noVNC_version"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Connection Controls -->
|
||||
<img alt="Disconnect" src="app/images/disconnect.svg"
|
||||
<input type="image" alt="Disconnect" src="app/images/disconnect.svg"
|
||||
id="noVNC_disconnect_button" class="noVNC_button"
|
||||
title="Disconnect" />
|
||||
title="Disconnect">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -322,21 +311,25 @@
|
|||
<div id="noVNC_connect_dlg">
|
||||
<!--div class="noVNC_logo" translate="no"><span>no</span>VNC</div-->
|
||||
<div id="noVNC_connect_button"><div>
|
||||
<img src="app/images/connect.svg"> Connect
|
||||
<img alt="" src="app/images/connect.svg"> Connect
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Password Dialog -->
|
||||
<div class="noVNC_center noVNC_connect_layer">
|
||||
<div id="noVNC_password_dlg" class="noVNC_panel"><form>
|
||||
<div id="noVNC_credentials_dlg" class="noVNC_panel"><form>
|
||||
<ul>
|
||||
<li>
|
||||
<li id="noVNC_username_block">
|
||||
<label>Username:</label>
|
||||
<input id="noVNC_username_input">
|
||||
</li>
|
||||
<li id="noVNC_password_block">
|
||||
<label>Password:</label>
|
||||
<input id="noVNC_password_input" type="password" />
|
||||
<input id="noVNC_password_input" type="password">
|
||||
</li>
|
||||
<li>
|
||||
<input id="noVNC_password_button" type="submit" value="Send Password" class="noVNC_submit" />
|
||||
<input id="noVNC_credentials_button" type="submit" value="Send Credentials" class="noVNC_submit">
|
||||
</li>
|
||||
</ul>
|
||||
</form></div>
|
||||
|
@ -346,7 +339,7 @@
|
|||
<div id="noVNC_transition">
|
||||
<div id="noVNC_transition_text"></div>
|
||||
<div>
|
||||
<input type="button" id="noVNC_cancel_reconnect_button" value="Cancel" class="noVNC_submit" />
|
||||
<input type="button" id="noVNC_cancel_reconnect_button" value="Cancel" class="noVNC_submit">
|
||||
</div>
|
||||
<div class="noVNC_spinner"></div>
|
||||
</div>
|
||||
|
@ -358,8 +351,7 @@
|
|||
on-screen keyboard. Let's hope Chrome implements the ime-mode
|
||||
style for example -->
|
||||
<textarea id="noVNC_keyboardinput" autocapitalize="off"
|
||||
autocorrect="off" autocomplete="off" spellcheck="false"
|
||||
mozactionhint="Enter" tabindex="-1"></textarea>
|
||||
autocomplete="off" spellcheck="false" tabindex="-1"></textarea>
|
||||
</div>
|
||||
|
||||
<audio id="noVNC_bell">
|
||||
|
|
38
package.json
38
package.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@novnc/novnc",
|
||||
"name": "@kasmtech/novnc",
|
||||
"version": "1.2.0",
|
||||
"description": "An HTML5 VNC client",
|
||||
"browser": "lib/rfb",
|
||||
|
@ -21,26 +21,27 @@
|
|||
"scripts": {
|
||||
"lint": "eslint app core po/po2js po/xgettext-html tests utils",
|
||||
"test": "karma start karma.conf.js",
|
||||
"prepublish": "node ./utils/use_require.js --clean"
|
||||
"prepublish": "node ./utils/use_require.js --as commonjs --clean",
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"build-production": "cross-env NODE_ENV=production webpack --config webpack.config.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/novnc/noVNC.git"
|
||||
"url": "git+https://github.com/kasmtech/noVNC.git"
|
||||
},
|
||||
"author": "Joel Martin <github@martintribe.org> (https://github.com/kanaka)",
|
||||
"author": "Kasm Technologies (https://www.kasmweb.com)",
|
||||
"contributors": [
|
||||
"Solly Ross <sross@redhat.com> (https://github.com/directxman12)",
|
||||
"Peter Åstrand <astrand@cendio.se> (https://github.com/astrand)",
|
||||
"Samuel Mannehed <samuel@cendio.se> (https://github.com/samhed)",
|
||||
"Pierre Ossman <ossman@cendio.se> (https://github.com/CendioOssman)"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/novnc/noVNC/issues"
|
||||
"url": "https://github.com/kasmtech/noVNC/issues"
|
||||
},
|
||||
"homepage": "https://github.com/novnc/noVNC",
|
||||
"homepage": "https://github.com/kasmtech/noVNC",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/preset-env": "^7.12.11",
|
||||
"@babel/core": "*",
|
||||
"babel-loader": "^8.2.2",
|
||||
"@babel/plugin-syntax-dynamic-import": "*",
|
||||
"@babel/plugin-transform-modules-commonjs": "*",
|
||||
"@babel/preset-env": "*",
|
||||
|
@ -50,10 +51,17 @@
|
|||
"babelify": "*",
|
||||
"core-js": "*",
|
||||
"chai": "*",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"commander": "*",
|
||||
"css-loader": "^5.0.1",
|
||||
"css-minimizer-webpack-plugin": "^1.1.5",
|
||||
"es-module-loader": "*",
|
||||
"eslint": "*",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "*",
|
||||
"html-loader": "^1.3.2",
|
||||
"html-webpack-inline-svg-plugin": "^2.3.0",
|
||||
"html-webpack-plugin": "^4.5.0",
|
||||
"jsdom": "*",
|
||||
"karma": "*",
|
||||
"karma-mocha": "*",
|
||||
|
@ -65,14 +73,22 @@
|
|||
"karma-safari-launcher": "*",
|
||||
"karma-script-launcher": "*",
|
||||
"karma-sinon-chai": "*",
|
||||
"mini-css-extract-plugin": "^1.3.3",
|
||||
"mocha": "*",
|
||||
"node-getopt": "*",
|
||||
"po2json": "*",
|
||||
"postcss-loader": "^4.1.0",
|
||||
"preload-webpack-plugin": "^3.0.0-beta.4",
|
||||
"requirejs": "*",
|
||||
"rollup": "*",
|
||||
"rollup-plugin-node-resolve": "*",
|
||||
"sass": "^1.30.0",
|
||||
"sass-loader": "^10.1.0",
|
||||
"sinon": "*",
|
||||
"sinon-chai": "*"
|
||||
"sinon-chai": "^2.8.0",
|
||||
"svg-sprite-html-webpack": "^2.3.0",
|
||||
"webpack": "^4.29.6",
|
||||
"webpack-cli": "^3.2.3"
|
||||
},
|
||||
"dependencies": {},
|
||||
"keywords": [
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/* Copyright (c) 2014 Taylor Hakes
|
||||
* Copyright (c) 2014 Forbes Lindesay
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
(function (root) {
|
||||
|
||||
// Store setTimeout reference so promise-polyfill will be unaffected by
|
||||
// other code modifying setTimeout (like sinon.useFakeTimers())
|
||||
var setTimeoutFunc = setTimeout;
|
||||
|
||||
function noop() {}
|
||||
|
||||
// Polyfill for Function.prototype.bind
|
||||
function bind(fn, thisArg) {
|
||||
return function () {
|
||||
fn.apply(thisArg, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function Promise(fn) {
|
||||
if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new');
|
||||
if (typeof fn !== 'function') throw new TypeError('not a function');
|
||||
this._state = 0;
|
||||
this._handled = false;
|
||||
this._value = undefined;
|
||||
this._deferreds = [];
|
||||
|
||||
doResolve(fn, this);
|
||||
}
|
||||
|
||||
function handle(self, deferred) {
|
||||
while (self._state === 3) {
|
||||
self = self._value;
|
||||
}
|
||||
if (self._state === 0) {
|
||||
self._deferreds.push(deferred);
|
||||
return;
|
||||
}
|
||||
self._handled = true;
|
||||
Promise._immediateFn(function () {
|
||||
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
|
||||
if (cb === null) {
|
||||
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
|
||||
return;
|
||||
}
|
||||
var ret;
|
||||
try {
|
||||
ret = cb(self._value);
|
||||
} catch (e) {
|
||||
reject(deferred.promise, e);
|
||||
return;
|
||||
}
|
||||
resolve(deferred.promise, ret);
|
||||
});
|
||||
}
|
||||
|
||||
function resolve(self, newValue) {
|
||||
try {
|
||||
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
|
||||
if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.');
|
||||
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
|
||||
var then = newValue.then;
|
||||
if (newValue instanceof Promise) {
|
||||
self._state = 3;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
return;
|
||||
} else if (typeof then === 'function') {
|
||||
doResolve(bind(then, newValue), self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self._state = 1;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
} catch (e) {
|
||||
reject(self, e);
|
||||
}
|
||||
}
|
||||
|
||||
function reject(self, newValue) {
|
||||
self._state = 2;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
}
|
||||
|
||||
function finale(self) {
|
||||
if (self._state === 2 && self._deferreds.length === 0) {
|
||||
Promise._immediateFn(function() {
|
||||
if (!self._handled) {
|
||||
Promise._unhandledRejectionFn(self._value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0, len = self._deferreds.length; i < len; i++) {
|
||||
handle(self, self._deferreds[i]);
|
||||
}
|
||||
self._deferreds = null;
|
||||
}
|
||||
|
||||
function Handler(onFulfilled, onRejected, promise) {
|
||||
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
|
||||
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
|
||||
this.promise = promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a potentially misbehaving resolver function and make sure
|
||||
* onFulfilled and onRejected are only called once.
|
||||
*
|
||||
* Makes no guarantees about asynchrony.
|
||||
*/
|
||||
function doResolve(fn, self) {
|
||||
var done = false;
|
||||
try {
|
||||
fn(function (value) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
resolve(self, value);
|
||||
}, function (reason) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, reason);
|
||||
});
|
||||
} catch (ex) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, ex);
|
||||
}
|
||||
}
|
||||
|
||||
Promise.prototype['catch'] = function (onRejected) {
|
||||
return this.then(null, onRejected);
|
||||
};
|
||||
|
||||
Promise.prototype.then = function (onFulfilled, onRejected) {
|
||||
var prom = new (this.constructor)(noop);
|
||||
|
||||
handle(this, new Handler(onFulfilled, onRejected, prom));
|
||||
return prom;
|
||||
};
|
||||
|
||||
Promise.all = function (arr) {
|
||||
var args = Array.prototype.slice.call(arr);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (args.length === 0) return resolve([]);
|
||||
var remaining = args.length;
|
||||
|
||||
function res(i, val) {
|
||||
try {
|
||||
if (val && (typeof val === 'object' || typeof val === 'function')) {
|
||||
var then = val.then;
|
||||
if (typeof then === 'function') {
|
||||
then.call(val, function (val) {
|
||||
res(i, val);
|
||||
}, reject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
args[i] = val;
|
||||
if (--remaining === 0) {
|
||||
resolve(args);
|
||||
}
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
res(i, args[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Promise.resolve = function (value) {
|
||||
if (value && typeof value === 'object' && value.constructor === Promise) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.reject = function (value) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.race = function (values) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
for (var i = 0, len = values.length; i < len; i++) {
|
||||
values[i].then(resolve, reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Use polyfill for setImmediate for performance gains
|
||||
Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) ||
|
||||
function (fn) {
|
||||
setTimeoutFunc(fn, 0);
|
||||
};
|
||||
|
||||
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
|
||||
if (typeof console !== 'undefined' && console) {
|
||||
console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the immediate function to execute callbacks
|
||||
* @param fn {function} Function to execute
|
||||
* @deprecated
|
||||
*/
|
||||
Promise._setImmediateFn = function _setImmediateFn(fn) {
|
||||
Promise._immediateFn = fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the function to execute on unhandled rejection
|
||||
* @param {function} fn Function to execute on unhandled rejection
|
||||
* @deprecated
|
||||
*/
|
||||
Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {
|
||||
Promise._unhandledRejectionFn = fn;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Promise;
|
||||
} else if (!root.Promise) {
|
||||
root.Promise = Promise;
|
||||
}
|
||||
|
||||
})(this);
|
Loading…
Reference in New Issue