|
116 | 116 | Object.extend(Squeak,
|
117 | 117 | "version", {
|
118 | 118 | // system attributes
|
119 |
| - vmVersion: "SqueakJS 1.2.2", |
120 |
| - vmDate: "2024-06-22", // Maybe replace at build time? |
| 119 | + vmVersion: "SqueakJS 1.2.3", |
| 120 | + vmDate: "2024-09-28", // Maybe replace at build time? |
121 | 121 | vmBuild: "unknown", // or replace at runtime by last-modified?
|
122 | 122 | vmPath: "unknown", // Replace at runtime
|
123 | 123 | vmFile: "vm.js",
|
|
10090 | 10090 | clipBoardPromise
|
10091 | 10091 | .then(() => this.vm.popNandPush(1, this.makeStString(this.display.clipboardString)))
|
10092 | 10092 | .catch(() => this.vm.popNandPush(1, this.vm.nilObj))
|
10093 |
| - .finally(() => unfreeze()); |
| 10093 | + .finally(unfreeze); |
10094 | 10094 | } else {
|
10095 | 10095 | if (typeof(this.display.clipboardString) !== 'string') return false;
|
10096 | 10096 | this.vm.popNandPush(1, this.makeStString(this.display.clipboardString));
|
|
10140 | 10140 | this.display.signalInputEvent = function() {
|
10141 | 10141 | this.signalSemaphoreWithIndex(this.inputEventSemaIndex);
|
10142 | 10142 | }.bind(this);
|
10143 |
| - this.display.signalInputEvent(); |
10144 | 10143 | return this.popNIfOK(argCount);
|
10145 | 10144 | },
|
10146 | 10145 | primitiveInputWord: function(argCount) {
|
|
56815 | 56814 | input.setAttribute("autocapitalize", "off");
|
56816 | 56815 | input.setAttribute("spellcheck", "false");
|
56817 | 56816 | input.style.position = "absolute";
|
56818 |
| - input.style.width = "0"; |
56819 |
| - input.style.height = "0"; |
56820 |
| - input.style.opacity = "0"; |
56821 |
| - input.style.pointerEvents = "none"; |
| 56817 | + input.style.left = "-1000px"; |
56822 | 56818 | canvas.parentElement.appendChild(input);
|
56823 | 56819 | // touch-keyboard buttons
|
56824 | 56820 | if ('ontouchstart' in document) {
|
|
56829 | 56825 | canvas.parentElement.appendChild(keyboardButton);
|
56830 | 56826 | keyboardButton.onmousedown = function(evt) {
|
56831 | 56827 | // show on-screen keyboard
|
56832 |
| - input.focus(); |
| 56828 | + input.focus({ preventScroll: true }); |
56833 | 56829 | evt.preventDefault();
|
56834 | 56830 | };
|
56835 | 56831 | keyboardButton.ontouchstart = keyboardButton.onmousedown;
|
|
56863 | 56859 | cmdButton.ontouchcancel = cmdButton.ontouchend;
|
56864 | 56860 | } else {
|
56865 | 56861 | // keep focus on input field
|
56866 |
| - input.onblur = function() { input.focus(); }; |
56867 |
| - input.focus(); |
| 56862 | + input.onblur = function() { input.focus({ preventScroll: true }); }; |
| 56863 | + input.focus({ preventScroll: true }); |
56868 | 56864 | }
|
56869 | 56865 | display.isMac = navigator.userAgent.includes("Mac");
|
56870 | 56866 | // emulate keypress events
|
|
56898 | 56894 | deadChars = deadChars.concat(chars);
|
56899 | 56895 | }
|
56900 | 56896 | }
|
56901 |
| - if (!deadChars.length) input.value = ""; // clear input |
| 56897 | + if (!deadChars.length) resetInput(); |
56902 | 56898 | };
|
56903 | 56899 | input.onkeydown = function(evt) {
|
56904 | 56900 | checkFullscreen();
|
@@ -56961,21 +56957,43 @@
|
56961 | 56957 | if (!display.vm) return true;
|
56962 | 56958 | recordModifiers(evt, display);
|
56963 | 56959 | };
|
| 56960 | + function resetInput() { |
| 56961 | + input.value = "**"; |
| 56962 | + input.selectionStart = 1; |
| 56963 | + input.selectionEnd = 1; |
| 56964 | + } |
| 56965 | + resetInput(); |
| 56966 | + // hack to generate arrow keys when moving the cursor (e.g. via spacebar on iPhone) |
| 56967 | + // we're not getting any events for that but the cursor (selection) changes |
| 56968 | + if ('ontouchstart' in document) { |
| 56969 | + let count = 0; // count how often the interval has run after the first move |
| 56970 | + setInterval(() => { |
| 56971 | + const direction = input.selectionStart - 1; |
| 56972 | + if (direction === 0) { |
| 56973 | + count = 0; |
| 56974 | + return; |
| 56975 | + } |
| 56976 | + // move cursor once, then not for 500ms, then every 250ms |
| 56977 | + if (count === 0 || count > 2) { |
| 56978 | + const key = direction < 1 ? 28 : 29; // arrow left or right |
| 56979 | + recordKeyboardEvent(key, Date.now(), display); |
| 56980 | + } |
| 56981 | + input.selectionStart = 1; |
| 56982 | + input.selectionEnd = 1; |
| 56983 | + count++; |
| 56984 | + }, 250); |
| 56985 | + } |
56964 | 56986 | // more copy/paste
|
56965 | 56987 | if (navigator.clipboard) {
|
56966 | 56988 | // new-style copy/paste (all modern browsers)
|
56967 |
| - display.readFromSystemClipboard = () => navigator.clipboard.readText() |
| 56989 | + display.readFromSystemClipboard = () => display.handlingEvent && |
| 56990 | + navigator.clipboard.readText() |
56968 | 56991 | .then(text => display.clipboardString = text)
|
56969 |
| - .catch(err => { |
56970 |
| - if (!display.handlingEvent) console.warn("reading from clipboard outside event handler"); |
56971 |
| - console.error("readFromSystemClipboard" + err.message); |
56972 |
| - }); |
56973 |
| - display.writeToSystemClipboard = () => navigator.clipboard.writeText(display.clipboardString) |
| 56992 | + .catch(err => console.error("readFromSystemClipboard " + err.message)); |
| 56993 | + display.writeToSystemClipboard = () => display.handlingEvent && |
| 56994 | + navigator.clipboard.writeText(display.clipboardString) |
56974 | 56995 | .then(() => display.clipboardStringChanged = false)
|
56975 |
| - .catch(err => { |
56976 |
| - if (!display.handlingEvent) console.warn("writing to clipboard outside event handler"); |
56977 |
| - console.error("writeToSystemClipboard" + err.message); |
56978 |
| - }); |
| 56996 | + .catch(err => console.error("writeToSystemClipboard " + err.message)); |
56979 | 56997 | } else {
|
56980 | 56998 | // old-style copy/paste
|
56981 | 56999 | document.oncopy = function(evt, key) {
|
|
0 commit comments