From 93ae7abcc70728e2605bd8ae154f3760d2005c0a Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 14 Nov 2024 22:52:38 -0500 Subject: [PATCH 01/21] working draft of x y tracker --- client/utils/previewEntry.js | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/client/utils/previewEntry.js b/client/utils/previewEntry.js index a361c00476..aa71d5001c 100644 --- a/client/utils/previewEntry.js +++ b/client/utils/previewEntry.js @@ -19,11 +19,13 @@ window.loopProtect = loopProtect; const consoleBuffer = []; const LOGWAIT = 500; + Hook(window.console, (log) => { consoleBuffer.push({ log }); }); + setInterval(() => { if (consoleBuffer.length > 0) { const message = { @@ -61,6 +63,59 @@ function handleMessageEvent(e) { window.addEventListener('message', handleMessageEvent); +// setting up mouse x and y coordinates +// similar to hooking into console? +const canvasMouseBuffer = []; + +function hookIntoCanvas() { + const coordinatesDiv = document.createElement('div'); + + // ideally want this to be updated next to the Preview Header in IDEView eventually + coordinatesDiv.style.position = 'absolute'; + coordinatesDiv.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'; + coordinatesDiv.style.padding = '5px'; + coordinatesDiv.style.border = '1px solid #ccc'; + coordinatesDiv.style.fontSize = '12px'; + coordinatesDiv.style.zIndex = '1000'; + + document.body.appendChild(coordinatesDiv); + + const waitForCanvas = () => { + const canvas = document.getElementById('defaultCanvas0'); + + if (canvas) { + console.log('canvas found, adding mouseover listener'); + + canvas.addEventListener('mousemove', (event) => { + const rect = canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + + // console.log(`mouse coordinates: ${x} and ${y}`); + coordinatesDiv.innerHTML = `Mouse X: ${x}, Mouse Y: ${y}`; + }); + } else { + console.log('canvas not found yet'); + setTimeout(waitForCanvas, LOGWAIT); + } + }; + + waitForCanvas(); +} + +setInterval(() => { + if (canvasMouseBuffer.length > 0) { + const message = { + messages: canvasMouseBuffer, + source: 'sketch' + }; + editor.postMessage(message, editorOrigin); + canvasMouseBuffer.length = 0; + } +}, LOGWAIT); + +document.addEventListener('DOMContentLoaded', hookIntoCanvas); + // catch reference errors, via http://stackoverflow.com/a/12747364/2994108 window.onerror = async function onError( msg, From 24cc5aa3288e26cc2184be8dddb0c6600daf3ad1 Mon Sep 17 00:00:00 2001 From: raclim Date: Mon, 25 Nov 2024 18:38:13 -0500 Subject: [PATCH 02/21] notes --- client/modules/Preview/previewIndex.jsx | 21 +++++++++++++++++++++ client/utils/previewEntry.js | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index fe4b5dc153..807da4dcd2 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -18,6 +18,27 @@ const GlobalStyle = createGlobalStyle` } `; +// editor, nested iframe - intermediary for iframe and editor itself handling preview, nested iframe that is just the rendering +// previewentry is just the inner rendering, catching all the console messages from the sketch that's running +// outer iframe is capturing those and sending it back to the editor, is like this for security reasons, need the sketch to be running in an sandboxed iframe so it can't access +// preview entry is on the innermost iframe +// preview index is handling the rendering and all the messaging back and forth, rendering is done by PreviewEmbedFrame +// embedFrame is assmebling all the html together and creates a frame that is setting the source, renderSketch() is most important +// blobUrl is like a web url but lets you do and store that in the browser memory +// intermediate iframe is routing all messages from the editor and dispatching the messages that is seting the files, when that is set it re-renders +// what i want is a component on the midIframe, which is all running on the previewIndex +// back in previewIndex, will post the message for toggling preferences + +// actions, IDE after hitting play startSketch, startSketch action dispatchesMessage + +// previewIndex, add a new state (can you see coordinates or net, set coordinates) +// will also have state in base editor itself, and in preferences actions file, you'll have to create new function that dispatches a message similar to startSketch, where it dispatches and updates the internal state of the editor (266 - 268 is sending info to previewIndex.jsx) +// in previewIndex, there is code handling receiving that message, will need to add a new messagetype to dispatcher and set the state of setCoordinatesVisible, state passed as paramter to component that will render the mouse position +// dispatcher file is what's handling sending all the messages back and forth, can use it in the editor window and preview iframe + +// dispatcher sets up an eventlistener that listens for message events +// create a new component in preview folder, add eventlistenere for hovermousemove, put that in this component so we can use React stuff, then in that component reference the editorframe by using window.parent, whereas in +// have a ref to the editor frame (i.e window.parent - two nested iframes in rendering of the editor) const App = () => { const [state, dispatch] = useReducer(filesReducer, [], initialState); const [isPlaying, setIsPlaying] = useState(false); diff --git a/client/utils/previewEntry.js b/client/utils/previewEntry.js index aa71d5001c..3f9ab3a1c1 100644 --- a/client/utils/previewEntry.js +++ b/client/utils/previewEntry.js @@ -37,6 +37,7 @@ setInterval(() => { } }, LOGWAIT); +// handling capturing messages from the console function handleMessageEvent(e) { // maybe don't need this?? idk! if (window.origin !== e.origin) return; @@ -65,6 +66,9 @@ window.addEventListener('message', handleMessageEvent); // setting up mouse x and y coordinates // similar to hooking into console? + +// notes from cassie: may want to do sth with the dispatcher? +// this file, previewEntry.js is just for catching console errors const canvasMouseBuffer = []; function hookIntoCanvas() { From f11bbe6830340e3625720db5dfa093ca4ff78231 Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 12:40:38 -0500 Subject: [PATCH 03/21] add translations --- translations/locales/en-US/translations.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json index 31a42c47af..8d4852edcc 100644 --- a/translations/locales/en-US/translations.json +++ b/translations/locales/en-US/translations.json @@ -176,6 +176,9 @@ "WordWrap": "Word Wrap", "LineWrapOnARIA": "linewrap on", "LineWrapOffARIA": "linewrap off", + "Coordinates": "Coordinates", + "CoordinatesOnARIA": "coordinates on", + "CoordinatesOffARIA": "coordinates off", "LineNumbers": "Line numbers", "LineNumbersOnARIA": "line numbers on", "LineNumbersOffARIA": "line numbers off", From 59b12d11b3883a91af80b2839e78ad306a91c8cd Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 12:41:14 -0500 Subject: [PATCH 04/21] create CoordinateTracker --- client/modules/Preview/CoordinateTracker.jsx | 35 ++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 client/modules/Preview/CoordinateTracker.jsx diff --git a/client/modules/Preview/CoordinateTracker.jsx b/client/modules/Preview/CoordinateTracker.jsx new file mode 100644 index 0000000000..c682f0a1ae --- /dev/null +++ b/client/modules/Preview/CoordinateTracker.jsx @@ -0,0 +1,35 @@ +import React, { useEffect, useState } from 'react'; +import styled from 'styled-components'; +import { useCoordinates } from './contexts'; +import { remSize } from '../../theme'; + +const CoordContainer = styled.div` + // font-size: 1rem; + color: ${(props) => props.theme.primaryTextColor}; + z-index: 1000; + // font-size: ${remSize(1)}; + padding: ${remSize(0.1)}; +`; + +const CoordinateTracker = () => { + const { coordinatesRef } = useCoordinates(); + const [coordinates, setCoordinates] = useState(coordinatesRef.current); + + useEffect(() => { + const interval = setInterval(() => { + setCoordinates({ ...coordinatesRef.current }); + }, 100); + + return () => clearInterval(interval); + }, [coordinatesRef]); + + return ( + +

+ X: {coordinates?.xVal || 0} Y: {coordinates?.yVal || 0} +

+
+ ); +}; + +export default CoordinateTracker; From 1dbf4ec21f33700c91f0b1170c66c8cf10b99cae Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 12:42:27 -0500 Subject: [PATCH 05/21] update dispatcher, add coord. to pref UI --- .../IDE/components/Preferences/index.jsx | 34 +++++++++++++++++++ client/utils/dispatcher.js | 3 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/client/modules/IDE/components/Preferences/index.jsx b/client/modules/IDE/components/Preferences/index.jsx index fa5859400e..208738ead0 100644 --- a/client/modules/IDE/components/Preferences/index.jsx +++ b/client/modules/IDE/components/Preferences/index.jsx @@ -28,6 +28,7 @@ export default function Preferences() { fontSize, autosave, linewrap, + coordinates, lineNumbers, lintWarning, textOutput, @@ -334,6 +335,39 @@ export default function Preferences() { +
+

+ {t('Preferences.Coordinates')} +

+
+ dispatch(setLinewrap(true))} + aria-label={t('Preferences.CoordinatesOnARIA')} + name="coordinates" + id="coordinates-on" + className="preference__radio-button" + value="On" + checked={coordinates} + /> + + dispatch(setLinewrap(false))} + aria-label={t('Preferences.CoordinatesOffARIA')} + name="coordinates" + id="coordinates-off" + className="preference__radio-button" + value="Off" + checked={!coordinates} + /> + +
+
diff --git a/client/utils/dispatcher.js b/client/utils/dispatcher.js index 49393121ac..8e744d9ff1 100644 --- a/client/utils/dispatcher.js +++ b/client/utils/dispatcher.js @@ -11,7 +11,8 @@ export const MessageTypes = { FILES: 'FILES', SKETCH: 'SKETCH', REGISTER: 'REGISTER', - EXECUTE: 'EXECUTE' + EXECUTE: 'EXECUTE', + COORDINATES: 'COORDINATES' }; export function registerFrame(newFrame, newOrigin) { From 65f3d8866d3f8d721a37467b62cd35b10769a2b9 Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 12:43:31 -0500 Subject: [PATCH 06/21] remove comments, handle coord data in preview index --- client/modules/Preview/previewIndex.jsx | 58 +++++++++++++------------ 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index 807da4dcd2..6e47b57b55 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -1,6 +1,6 @@ -import React, { useReducer, useState, useEffect } from 'react'; +import React, { useReducer, useState, useEffect, useMemo } from 'react'; import { render } from 'react-dom'; -import { createGlobalStyle } from 'styled-components'; +import { createGlobalStyle, ThemeProvider } from 'styled-components'; import { registerFrame, listen, @@ -9,6 +9,9 @@ import { } from '../../utils/dispatcher'; import { filesReducer, setFiles } from './filesReducer'; import EmbedFrame from './EmbedFrame'; +import CoordinateTracker from './CoordinateTracker'; +import theme from '../../theme'; +import { CoordinatesProvider, useCoordinates } from './contexts'; import getConfig from '../../utils/getConfig'; import { initialState } from '../IDE/reducers/files'; @@ -18,33 +21,16 @@ const GlobalStyle = createGlobalStyle` } `; -// editor, nested iframe - intermediary for iframe and editor itself handling preview, nested iframe that is just the rendering -// previewentry is just the inner rendering, catching all the console messages from the sketch that's running -// outer iframe is capturing those and sending it back to the editor, is like this for security reasons, need the sketch to be running in an sandboxed iframe so it can't access -// preview entry is on the innermost iframe -// preview index is handling the rendering and all the messaging back and forth, rendering is done by PreviewEmbedFrame -// embedFrame is assmebling all the html together and creates a frame that is setting the source, renderSketch() is most important -// blobUrl is like a web url but lets you do and store that in the browser memory -// intermediate iframe is routing all messages from the editor and dispatching the messages that is seting the files, when that is set it re-renders -// what i want is a component on the midIframe, which is all running on the previewIndex -// back in previewIndex, will post the message for toggling preferences - -// actions, IDE after hitting play startSketch, startSketch action dispatchesMessage - -// previewIndex, add a new state (can you see coordinates or net, set coordinates) -// will also have state in base editor itself, and in preferences actions file, you'll have to create new function that dispatches a message similar to startSketch, where it dispatches and updates the internal state of the editor (266 - 268 is sending info to previewIndex.jsx) -// in previewIndex, there is code handling receiving that message, will need to add a new messagetype to dispatcher and set the state of setCoordinatesVisible, state passed as paramter to component that will render the mouse position -// dispatcher file is what's handling sending all the messages back and forth, can use it in the editor window and preview iframe - -// dispatcher sets up an eventlistener that listens for message events -// create a new component in preview folder, add eventlistenere for hovermousemove, put that in this component so we can use React stuff, then in that component reference the editorframe by using window.parent, whereas in -// have a ref to the editor frame (i.e window.parent - two nested iframes in rendering of the editor) const App = () => { const [state, dispatch] = useReducer(filesReducer, [], initialState); const [isPlaying, setIsPlaying] = useState(false); const [basePath, setBasePath] = useState(''); const [textOutput, setTextOutput] = useState(false); const [gridOutput, setGridOutput] = useState(false); + const [coordinatesVisible] = useState(true); + + const { updateCoordinates } = useCoordinates(); + registerFrame(window.parent, getConfig('EDITOR_URL')); function handleMessageEvent(message) { @@ -68,6 +54,9 @@ const App = () => { case MessageTypes.EXECUTE: dispatchMessage(payload); break; + case MessageTypes.COORDINATES: + updateCoordinates(payload); + break; default: break; } @@ -86,24 +75,37 @@ const App = () => { }); } + const memoizedFiles = useMemo(() => addCacheBustingToAssets(state), [ + state, + addCacheBustingToAssets + ]); + useEffect(() => { const unsubscribe = listen(handleMessageEvent); return function cleanup() { unsubscribe(); }; - }); + }, []); + return ( - + + {coordinatesVisible && } - + ); }; -render(, document.getElementById('root')); +const Root = () => ( + + + +); + +render(, document.getElementById('root')); From 25ece5d00c1f823ef78a9771d7999eeb5da1b487 Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 12:44:00 -0500 Subject: [PATCH 07/21] create context to hold coordinate value state --- client/modules/Preview/contexts.jsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 client/modules/Preview/contexts.jsx diff --git a/client/modules/Preview/contexts.jsx b/client/modules/Preview/contexts.jsx new file mode 100644 index 0000000000..e97fc33287 --- /dev/null +++ b/client/modules/Preview/contexts.jsx @@ -0,0 +1,24 @@ +import React, { createContext, useRef, useContext } from 'react'; +import PropTypes from 'prop-types'; + +const CoordinatesContext = createContext(); + +export const useCoordinates = () => useContext(CoordinatesContext); + +export const CoordinatesProvider = ({ children }) => { + const coordinatesRef = useRef({}); + + const updateCoordinates = (newCoordinates) => { + coordinatesRef.current = newCoordinates; + }; + + return ( + + {children} + + ); +}; + +CoordinatesProvider.propTypes = { + children: PropTypes.node.isRequired +}; From 84254dc48fc87d32d379ac9c1c7a6ad1129ddd2d Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 16:49:01 -0500 Subject: [PATCH 08/21] add setting coordinate visibility in preferences --- client/constants.js | 1 + client/modules/IDE/actions/preferences.js | 25 +++++++++++++++++++ .../IDE/components/Preferences/index.jsx | 16 ++++++------ client/modules/IDE/reducers/preferences.js | 7 +++++- server/models/user.js | 3 ++- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/client/constants.js b/client/constants.js index fa6010aed1..e4c904885c 100644 --- a/client/constants.js +++ b/client/constants.js @@ -69,6 +69,7 @@ export const SET_GRID_OUTPUT = 'SET_GRID_OUTPUT'; export const SET_SOUND_OUTPUT = 'SET_SOUND_OUTPUT'; export const SET_AUTOCLOSE_BRACKETS_QUOTES = 'SET_AUTOCLOSE_BRACKETS_QUOTES'; export const SET_AUTOCOMPLETE_HINTER = 'SET_AUTOCOMPLETE_HINTER'; +export const SET_COORDINATES = 'SET_COORDINATES'; export const OPEN_PROJECT_OPTIONS = 'OPEN_PROJECT_OPTIONS'; export const CLOSE_PROJECT_OPTIONS = 'CLOSE_PROJECT_OPTIONS'; diff --git a/client/modules/IDE/actions/preferences.js b/client/modules/IDE/actions/preferences.js index e0473bd995..cb43099274 100644 --- a/client/modules/IDE/actions/preferences.js +++ b/client/modules/IDE/actions/preferences.js @@ -1,6 +1,7 @@ import i18next from 'i18next'; import apiClient from '../../../utils/apiClient'; import * as ActionTypes from '../../../constants'; +import { dispatchMessage, MessageTypes } from '../../../utils/dispatcher'; function updatePreferences(formParams, dispatch) { apiClient @@ -14,6 +15,30 @@ function updatePreferences(formParams, dispatch) { }); } +export function setCoordinates(value) { + return (dispatch, getState) => { + dispatch({ + type: ActionTypes.SET_COORDINATES, + value + }); + + dispatchMessage({ + type: MessageTypes.COORDINATES_VISIBILITY, + payload: value + }); + + const state = getState(); + if (state.user.authenticated) { + const formParams = { + preferences: { + coordinates: value + } + }; + updatePreferences(formParams, dispatch); + } + }; +} + export function setFontSize(value) { return (dispatch, getState) => { // eslint-disable-line diff --git a/client/modules/IDE/components/Preferences/index.jsx b/client/modules/IDE/components/Preferences/index.jsx index 208738ead0..b9de0e7917 100644 --- a/client/modules/IDE/components/Preferences/index.jsx +++ b/client/modules/IDE/components/Preferences/index.jsx @@ -16,7 +16,8 @@ import { setLintWarning, setAutocloseBracketsQuotes, setAutocompleteHinter, - setLinewrap + setLinewrap, + setCoordinates } from '../../actions/preferences'; export default function Preferences() { @@ -342,28 +343,29 @@ export default function Preferences() {
dispatch(setLinewrap(true))} + onChange={() => dispatch(setCoordinates(true))} aria-label={t('Preferences.CoordinatesOnARIA')} name="coordinates" id="coordinates-on" className="preference__radio-button" value="On" - checked={coordinates} + checked={coordinates === true} /> -
diff --git a/client/modules/IDE/reducers/preferences.js b/client/modules/IDE/reducers/preferences.js index 087d927aed..24ecb06deb 100644 --- a/client/modules/IDE/reducers/preferences.js +++ b/client/modules/IDE/reducers/preferences.js @@ -12,7 +12,8 @@ export const initialState = { autorefresh: false, language: 'en-US', autocloseBracketsQuotes: true, - autocompleteHinter: false + autocompleteHinter: false, + coordinates: false }; const preferences = (state = initialState, action) => { @@ -47,6 +48,10 @@ const preferences = (state = initialState, action) => { return Object.assign({}, state, { autocompleteHinter: action.value }); + case ActionTypes.SET_COORDINATES: + return Object.assign({}, state, { + coordinates: action.value + }); default: return state; } diff --git a/server/models/user.js b/server/models/user.js index d1c5e16bf2..901e7692a5 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -74,7 +74,8 @@ const userSchema = new Schema( autorefresh: { type: Boolean, default: false }, language: { type: String, default: 'en-US' }, autocloseBracketsQuotes: { type: Boolean, default: true }, - autocompleteHinter: { type: Boolean, default: false } + autocompleteHinter: { type: Boolean, default: false }, + coordinates: { type: Boolean, default: false } }, totalSize: { type: Number, default: 0 }, cookieConsent: { From 52d0b33e83972f9fe90ab5b97c908ab6dcb03d44 Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 16:49:52 -0500 Subject: [PATCH 09/21] pass theme and coordinate visibility --- client/modules/IDE/actions/ide.js | 3 ++- client/modules/Preview/previewIndex.jsx | 11 ++++++++--- client/utils/dispatcher.js | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/client/modules/IDE/actions/ide.js b/client/modules/IDE/actions/ide.js index 80a43443bc..2f140484de 100644 --- a/client/modules/IDE/actions/ide.js +++ b/client/modules/IDE/actions/ide.js @@ -260,7 +260,8 @@ export function startSketch() { files: state.files, basePath: window.location.pathname, gridOutput: state.preferences.gridOutput, - textOutput: state.preferences.textOutput + textOutput: state.preferences.textOutput, + userTheme: state.preferences.theme } }); dispatchMessage({ diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index 6e47b57b55..189b35e8b8 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -27,7 +27,8 @@ const App = () => { const [basePath, setBasePath] = useState(''); const [textOutput, setTextOutput] = useState(false); const [gridOutput, setGridOutput] = useState(false); - const [coordinatesVisible] = useState(true); + const [userTheme, setUserTheme] = useState('light'); + const [coordinatesVisible, setCoordinatesVisible] = useState(false); const { updateCoordinates } = useCoordinates(); @@ -41,6 +42,7 @@ const App = () => { setBasePath(payload.basePath); setTextOutput(payload.textOutput); setGridOutput(payload.gridOutput); + setUserTheme(payload.userTheme); break; case MessageTypes.START: setIsPlaying(true); @@ -57,6 +59,9 @@ const App = () => { case MessageTypes.COORDINATES: updateCoordinates(payload); break; + case MessageTypes.COORDINATES_VISIBILITY: + setCoordinatesVisible(payload); + break; default: break; } @@ -88,9 +93,9 @@ const App = () => { }, []); return ( - + - {coordinatesVisible && } + {coordinatesVisible && } Date: Wed, 27 Nov 2024 16:50:22 -0500 Subject: [PATCH 10/21] add coordinate to test data --- client/testData/testServerResponses.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/testData/testServerResponses.js b/client/testData/testServerResponses.js index 9675b005b6..d8b240719e 100644 --- a/client/testData/testServerResponses.js +++ b/client/testData/testServerResponses.js @@ -19,7 +19,8 @@ export const userResponse = { autorefresh: false, language: 'en-US', autocloseBracketsQuotes: true, - autocompleteHinter: false + autocompleteHinter: false, + coordinates: false }, apiKeys: [], verified: 'verified', From 683dd86a362b740e924f8b828f0c59721a99df7e Mon Sep 17 00:00:00 2001 From: raclim Date: Wed, 27 Nov 2024 16:52:15 -0500 Subject: [PATCH 11/21] add listener and cleanup function --- client/utils/previewEntry.js | 56 +++++++++++++++--------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/client/utils/previewEntry.js b/client/utils/previewEntry.js index 3f9ab3a1c1..f2a085a3f7 100644 --- a/client/utils/previewEntry.js +++ b/client/utils/previewEntry.js @@ -37,7 +37,6 @@ setInterval(() => { } }, LOGWAIT); -// handling capturing messages from the console function handleMessageEvent(e) { // maybe don't need this?? idk! if (window.origin !== e.origin) return; @@ -65,40 +64,42 @@ function handleMessageEvent(e) { window.addEventListener('message', handleMessageEvent); // setting up mouse x and y coordinates -// similar to hooking into console? - -// notes from cassie: may want to do sth with the dispatcher? -// this file, previewEntry.js is just for catching console errors -const canvasMouseBuffer = []; function hookIntoCanvas() { - const coordinatesDiv = document.createElement('div'); - - // ideally want this to be updated next to the Preview Header in IDEView eventually - coordinatesDiv.style.position = 'absolute'; - coordinatesDiv.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'; - coordinatesDiv.style.padding = '5px'; - coordinatesDiv.style.border = '1px solid #ccc'; - coordinatesDiv.style.fontSize = '12px'; - coordinatesDiv.style.zIndex = '1000'; - - document.body.appendChild(coordinatesDiv); + let isListenerAttached = false; const waitForCanvas = () => { const canvas = document.getElementById('defaultCanvas0'); - if (canvas) { + if (canvas && !isListenerAttached) { console.log('canvas found, adding mouseover listener'); + isListenerAttached = true; - canvas.addEventListener('mousemove', (event) => { + const mouseMoveHandler = (event) => { const rect = canvas.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; - // console.log(`mouse coordinates: ${x} and ${y}`); - coordinatesDiv.innerHTML = `Mouse X: ${x}, Mouse Y: ${y}`; + const message = { + payload: { xVal: x, yVal: y }, + type: 'COORDINATES' + }; + window.parent.postMessage(message, window.parent.location.origin); + }; + + canvas.addEventListener('mousemove', mouseMoveHandler); + + const observer = new MutationObserver(() => { + if (!document.body.contains(canvas)) { + console.log('Canvas removed, cleaning up listener'); + canvas.removeEventListener('mousemove', mouseMoveHandler); + observer.disconnect(); + isListenerAttached = false; + } }); - } else { + + observer.observe(document.body, { childList: true, subtree: true }); + } else if (!canvas) { console.log('canvas not found yet'); setTimeout(waitForCanvas, LOGWAIT); } @@ -107,17 +108,6 @@ function hookIntoCanvas() { waitForCanvas(); } -setInterval(() => { - if (canvasMouseBuffer.length > 0) { - const message = { - messages: canvasMouseBuffer, - source: 'sketch' - }; - editor.postMessage(message, editorOrigin); - canvasMouseBuffer.length = 0; - } -}, LOGWAIT); - document.addEventListener('DOMContentLoaded', hookIntoCanvas); // catch reference errors, via http://stackoverflow.com/a/12747364/2994108 From bbb7276fa53733eb7727671212b22f4c5ba24f9f Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 5 Dec 2024 17:07:19 -0500 Subject: [PATCH 12/21] move canvas listener into CoordinateTracker --- client/modules/Preview/CoordinateTracker.jsx | 64 ++++++++++++++++---- client/utils/previewEntry.js | 47 -------------- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/client/modules/Preview/CoordinateTracker.jsx b/client/modules/Preview/CoordinateTracker.jsx index c682f0a1ae..5f6b189881 100644 --- a/client/modules/Preview/CoordinateTracker.jsx +++ b/client/modules/Preview/CoordinateTracker.jsx @@ -1,32 +1,70 @@ import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; -import { useCoordinates } from './contexts'; import { remSize } from '../../theme'; const CoordContainer = styled.div` - // font-size: 1rem; - color: ${(props) => props.theme.primaryTextColor}; z-index: 1000; - // font-size: ${remSize(1)}; padding: ${remSize(0.1)}; + border-bottom: ${remSize(1)} dashed #a6a6a6; + margin-bottom: ${remSize(4)}; + + p { + font-size: ${remSize(9.5)}; + padding: 0 0 ${remSize(3.5)} ${remSize(3.5)}; + margin: 0; + font-family: Inconsolata, monospace; + font-weight: light; + color: ${(props) => props.theme.Button.primary.default.foreground}; + } `; -const CoordinateTracker = () => { - const { coordinatesRef } = useCoordinates(); - const [coordinates, setCoordinates] = useState(coordinatesRef.current); +const CoordinateTracker = (isPlaying) => { + const [coordinates, setCoordinates] = useState({ x: 0, y: 0 }); useEffect(() => { - const interval = setInterval(() => { - setCoordinates({ ...coordinatesRef.current }); - }, 100); + let isListenerAttached = false; + + const waitForCanvas = () => { + const iFrame = document.getElementById('previewIframe0'); + const canvas = iFrame.contentWindow.document.getElementById( + 'defaultCanvas0' + ); + + if (canvas && !isListenerAttached) { + isListenerAttached = true; + + const mouseMoveHandler = (event) => { + const rect = canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + + setCoordinates({ x, y }); + }; + + canvas.addEventListener('mousemove', mouseMoveHandler); + + const observer = new MutationObserver(() => { + if (!document.body.contains(canvas)) { + canvas.removeEventListener('mousemove', mouseMoveHandler); + observer.disconnect(); + isListenerAttached = false; + } + }); + + observer.observe(document.body, { childList: true, subtree: true }); + } else if (!canvas) { + setTimeout(waitForCanvas, 500); + } + }; - return () => clearInterval(interval); - }, [coordinatesRef]); + waitForCanvas(); + }, [isPlaying]); return (

- X: {coordinates?.xVal || 0} Y: {coordinates?.yVal || 0} + Mouse X: {isPlaying ? coordinates.x : 0} Mouse Y:{' '} + {isPlaying ? coordinates.y : 0}

); diff --git a/client/utils/previewEntry.js b/client/utils/previewEntry.js index f2a085a3f7..aeab13d182 100644 --- a/client/utils/previewEntry.js +++ b/client/utils/previewEntry.js @@ -63,53 +63,6 @@ function handleMessageEvent(e) { window.addEventListener('message', handleMessageEvent); -// setting up mouse x and y coordinates - -function hookIntoCanvas() { - let isListenerAttached = false; - - const waitForCanvas = () => { - const canvas = document.getElementById('defaultCanvas0'); - - if (canvas && !isListenerAttached) { - console.log('canvas found, adding mouseover listener'); - isListenerAttached = true; - - const mouseMoveHandler = (event) => { - const rect = canvas.getBoundingClientRect(); - const x = event.clientX - rect.left; - const y = event.clientY - rect.top; - - const message = { - payload: { xVal: x, yVal: y }, - type: 'COORDINATES' - }; - window.parent.postMessage(message, window.parent.location.origin); - }; - - canvas.addEventListener('mousemove', mouseMoveHandler); - - const observer = new MutationObserver(() => { - if (!document.body.contains(canvas)) { - console.log('Canvas removed, cleaning up listener'); - canvas.removeEventListener('mousemove', mouseMoveHandler); - observer.disconnect(); - isListenerAttached = false; - } - }); - - observer.observe(document.body, { childList: true, subtree: true }); - } else if (!canvas) { - console.log('canvas not found yet'); - setTimeout(waitForCanvas, LOGWAIT); - } - }; - - waitForCanvas(); -} - -document.addEventListener('DOMContentLoaded', hookIntoCanvas); - // catch reference errors, via http://stackoverflow.com/a/12747364/2994108 window.onerror = async function onError( msg, From a3a23eee5a295326492bc24e218f0a5bd9ccfa79 Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 5 Dec 2024 17:08:38 -0500 Subject: [PATCH 13/21] remove contexts --- client/modules/Preview/contexts.jsx | 24 ------------------------ client/modules/Preview/previewIndex.jsx | 18 ++++-------------- 2 files changed, 4 insertions(+), 38 deletions(-) delete mode 100644 client/modules/Preview/contexts.jsx diff --git a/client/modules/Preview/contexts.jsx b/client/modules/Preview/contexts.jsx deleted file mode 100644 index e97fc33287..0000000000 --- a/client/modules/Preview/contexts.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React, { createContext, useRef, useContext } from 'react'; -import PropTypes from 'prop-types'; - -const CoordinatesContext = createContext(); - -export const useCoordinates = () => useContext(CoordinatesContext); - -export const CoordinatesProvider = ({ children }) => { - const coordinatesRef = useRef({}); - - const updateCoordinates = (newCoordinates) => { - coordinatesRef.current = newCoordinates; - }; - - return ( - - {children} - - ); -}; - -CoordinatesProvider.propTypes = { - children: PropTypes.node.isRequired -}; diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index 189b35e8b8..d16a182f72 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -11,7 +11,6 @@ import { filesReducer, setFiles } from './filesReducer'; import EmbedFrame from './EmbedFrame'; import CoordinateTracker from './CoordinateTracker'; import theme from '../../theme'; -import { CoordinatesProvider, useCoordinates } from './contexts'; import getConfig from '../../utils/getConfig'; import { initialState } from '../IDE/reducers/files'; @@ -30,8 +29,6 @@ const App = () => { const [userTheme, setUserTheme] = useState('light'); const [coordinatesVisible, setCoordinatesVisible] = useState(false); - const { updateCoordinates } = useCoordinates(); - registerFrame(window.parent, getConfig('EDITOR_URL')); function handleMessageEvent(message) { @@ -43,12 +40,14 @@ const App = () => { setTextOutput(payload.textOutput); setGridOutput(payload.gridOutput); setUserTheme(payload.userTheme); + setCoordinatesVisible(payload.coordinates); break; case MessageTypes.START: setIsPlaying(true); break; case MessageTypes.STOP: setIsPlaying(false); + setCoordinatesVisible(false); break; case MessageTypes.REGISTER: dispatchMessage({ type: MessageTypes.REGISTER }); @@ -56,9 +55,6 @@ const App = () => { case MessageTypes.EXECUTE: dispatchMessage(payload); break; - case MessageTypes.COORDINATES: - updateCoordinates(payload); - break; case MessageTypes.COORDINATES_VISIBILITY: setCoordinatesVisible(payload); break; @@ -95,7 +91,7 @@ const App = () => { return ( - {coordinatesVisible && } + {coordinatesVisible && } { ); }; -const Root = () => ( - - - -); - -render(, document.getElementById('root')); +render(, document.getElementById('root')); From c1878019bd17a2f5ab8e3a60f6b00ba0f85842f7 Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 5 Dec 2024 17:09:11 -0500 Subject: [PATCH 14/21] add id to iframe for canvas listener --- client/modules/Preview/EmbedFrame.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/modules/Preview/EmbedFrame.jsx b/client/modules/Preview/EmbedFrame.jsx index 4b2ad60d9b..bdac410594 100644 --- a/client/modules/Preview/EmbedFrame.jsx +++ b/client/modules/Preview/EmbedFrame.jsx @@ -315,6 +315,7 @@ function EmbedFrame({ files, isPlaying, basePath, gridOutput, textOutput }) { useEffect(renderSketch, [files, isPlaying]); return ( Date: Thu, 5 Dec 2024 17:09:41 -0500 Subject: [PATCH 15/21] pass user preferences for coordinates --- client/modules/IDE/actions/ide.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/modules/IDE/actions/ide.js b/client/modules/IDE/actions/ide.js index 2f140484de..a995fd25f9 100644 --- a/client/modules/IDE/actions/ide.js +++ b/client/modules/IDE/actions/ide.js @@ -261,7 +261,8 @@ export function startSketch() { basePath: window.location.pathname, gridOutput: state.preferences.gridOutput, textOutput: state.preferences.textOutput, - userTheme: state.preferences.theme + userTheme: state.preferences.theme, + coordinates: state.preferences.coordinates } }); dispatchMessage({ From c9da8417872524679d7cacc886a606a075a8eb94 Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 5 Dec 2024 17:12:26 -0500 Subject: [PATCH 16/21] remove extra spaces --- client/utils/previewEntry.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/utils/previewEntry.js b/client/utils/previewEntry.js index aeab13d182..a361c00476 100644 --- a/client/utils/previewEntry.js +++ b/client/utils/previewEntry.js @@ -19,13 +19,11 @@ window.loopProtect = loopProtect; const consoleBuffer = []; const LOGWAIT = 500; - Hook(window.console, (log) => { consoleBuffer.push({ log }); }); - setInterval(() => { if (consoleBuffer.length > 0) { const message = { From 34febe22b0410c671f1a077667174d5da9b0886d Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 5 Dec 2024 17:48:39 -0500 Subject: [PATCH 17/21] set visiblity if canvas isPlaying --- client/modules/Preview/previewIndex.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index d16a182f72..aa4cdb0f68 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -56,7 +56,7 @@ const App = () => { dispatchMessage(payload); break; case MessageTypes.COORDINATES_VISIBILITY: - setCoordinatesVisible(payload); + if (isPlaying) setCoordinatesVisible(payload); break; default: break; From f5d0338ee310f0eaa91760676d3f27d3cb58ece6 Mon Sep 17 00:00:00 2001 From: raclim Date: Fri, 6 Dec 2024 10:44:47 -0500 Subject: [PATCH 18/21] add media query --- client/modules/Preview/CoordinateTracker.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/modules/Preview/CoordinateTracker.jsx b/client/modules/Preview/CoordinateTracker.jsx index 5f6b189881..f80193fea6 100644 --- a/client/modules/Preview/CoordinateTracker.jsx +++ b/client/modules/Preview/CoordinateTracker.jsx @@ -5,7 +5,7 @@ import { remSize } from '../../theme'; const CoordContainer = styled.div` z-index: 1000; padding: ${remSize(0.1)}; - border-bottom: ${remSize(1)} dashed #a6a6a6; + // border-bottom: ${remSize(1)} dashed #a6a6a6; margin-bottom: ${remSize(4)}; p { @@ -16,6 +16,11 @@ const CoordContainer = styled.div` font-weight: light; color: ${(props) => props.theme.Button.primary.default.foreground}; } + + @media (max-width: 550px) { + // border-bottom: none; + margin-top: ${remSize(10)}; + } `; const CoordinateTracker = (isPlaying) => { From 936a1ad64818f7bf16628f6dee744e2d99fc2379 Mon Sep 17 00:00:00 2001 From: raclim Date: Thu, 30 Jan 2025 22:03:20 -0500 Subject: [PATCH 19/21] remove mutation observer, add logs --- client/modules/Preview/CoordinateTracker.jsx | 40 +++++++++++++------- client/modules/Preview/previewIndex.jsx | 3 ++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/client/modules/Preview/CoordinateTracker.jsx b/client/modules/Preview/CoordinateTracker.jsx index f80193fea6..01b9e3084e 100644 --- a/client/modules/Preview/CoordinateTracker.jsx +++ b/client/modules/Preview/CoordinateTracker.jsx @@ -27,18 +27,22 @@ const CoordinateTracker = (isPlaying) => { const [coordinates, setCoordinates] = useState({ x: 0, y: 0 }); useEffect(() => { + console.log('we here'); let isListenerAttached = false; + let mouseMoveHandler; + let canvas; const waitForCanvas = () => { const iFrame = document.getElementById('previewIframe0'); - const canvas = iFrame.contentWindow.document.getElementById( - 'defaultCanvas0' - ); + canvas = iFrame.contentWindow.document.getElementById('defaultCanvas0'); + console.log('iframe: ', iFrame); if (canvas && !isListenerAttached) { isListenerAttached = true; + console.log('Adding listener'); - const mouseMoveHandler = (event) => { + mouseMoveHandler = (event) => { + console.log('hellooooo'); const rect = canvas.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; @@ -46,23 +50,31 @@ const CoordinateTracker = (isPlaying) => { setCoordinates({ x, y }); }; - canvas.addEventListener('mousemove', mouseMoveHandler); + console.log('mouseMoveHandler', mouseMoveHandler); + console.log('canvas', canvas); - const observer = new MutationObserver(() => { - if (!document.body.contains(canvas)) { - canvas.removeEventListener('mousemove', mouseMoveHandler); - observer.disconnect(); - isListenerAttached = false; - } - }); - - observer.observe(document.body, { childList: true, subtree: true }); + document + .querySelector('#defaultCanvas0') + .addEventListener('mousemove', () => { + console.log('Button clicked!'); + mouseMoveHandler(); + }); + // canvas.addEventListener('mousemove', mouseMoveHandler); } else if (!canvas) { setTimeout(waitForCanvas, 500); } }; waitForCanvas(); + + return () => { + if (canvas && isListenerAttached) { + console.log('Removing listener'); + canvas.removeEventListener('mousemove', mouseMoveHandler); + canvas = null; + isListenerAttached = false; + } + }; }, [isPlaying]); return ( diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index aa4cdb0f68..17bfa08ab6 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -32,6 +32,7 @@ const App = () => { registerFrame(window.parent, getConfig('EDITOR_URL')); function handleMessageEvent(message) { + console.log('message', message); const { type, payload } = message; switch (type) { case MessageTypes.SKETCH: @@ -43,6 +44,7 @@ const App = () => { setCoordinatesVisible(payload.coordinates); break; case MessageTypes.START: + console.log('starting'); setIsPlaying(true); break; case MessageTypes.STOP: @@ -56,6 +58,7 @@ const App = () => { dispatchMessage(payload); break; case MessageTypes.COORDINATES_VISIBILITY: + console.log('coordinates visibility', payload); if (isPlaying) setCoordinatesVisible(payload); break; default: From 2e0c9dbd49119e2c54f7672e041d02b21c19382d Mon Sep 17 00:00:00 2001 From: raclim <43053081+raclim@users.noreply.github.com> Date: Mon, 12 May 2025 19:49:31 -0400 Subject: [PATCH 20/21] fix tracking coordinates on canvas reload --- client/modules/Preview/CoordinateTracker.jsx | 67 ++++++++------------ client/modules/Preview/previewIndex.jsx | 9 ++- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/client/modules/Preview/CoordinateTracker.jsx b/client/modules/Preview/CoordinateTracker.jsx index 01b9e3084e..a7148f81ea 100644 --- a/client/modules/Preview/CoordinateTracker.jsx +++ b/client/modules/Preview/CoordinateTracker.jsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; import styled from 'styled-components'; import { remSize } from '../../theme'; @@ -23,59 +24,42 @@ const CoordContainer = styled.div` } `; -const CoordinateTracker = (isPlaying) => { +const CoordinateTracker = ({ isPlaying, sketchReloaded }) => { const [coordinates, setCoordinates] = useState({ x: 0, y: 0 }); useEffect(() => { - console.log('we here'); - let isListenerAttached = false; - let mouseMoveHandler; let canvas; + let mouseMoveHandler; - const waitForCanvas = () => { + const timeout = setTimeout(() => { const iFrame = document.getElementById('previewIframe0'); - canvas = iFrame.contentWindow.document.getElementById('defaultCanvas0'); - console.log('iframe: ', iFrame); - - if (canvas && !isListenerAttached) { - isListenerAttached = true; - console.log('Adding listener'); - - mouseMoveHandler = (event) => { - console.log('hellooooo'); - const rect = canvas.getBoundingClientRect(); - const x = event.clientX - rect.left; - const y = event.clientY - rect.top; - - setCoordinates({ x, y }); - }; - - console.log('mouseMoveHandler', mouseMoveHandler); - console.log('canvas', canvas); + canvas = iFrame?.contentWindow?.document?.getElementById( + 'defaultCanvas0' + ); - document - .querySelector('#defaultCanvas0') - .addEventListener('mousemove', () => { - console.log('Button clicked!'); - mouseMoveHandler(); - }); - // canvas.addEventListener('mousemove', mouseMoveHandler); - } else if (!canvas) { - setTimeout(waitForCanvas, 500); + if (!canvas) { + console.warn('Canvas not found.'); + return; } - }; - waitForCanvas(); + mouseMoveHandler = (event) => { + const rect = canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + setCoordinates({ x, y }); + }; + + canvas.addEventListener('mousemove', mouseMoveHandler); + }, 500); return () => { - if (canvas && isListenerAttached) { - console.log('Removing listener'); + clearTimeout(timeout); + + if (canvas && mouseMoveHandler) { canvas.removeEventListener('mousemove', mouseMoveHandler); - canvas = null; - isListenerAttached = false; } }; - }, [isPlaying]); + }, [isPlaying, sketchReloaded]); return ( @@ -87,4 +71,9 @@ const CoordinateTracker = (isPlaying) => { ); }; +CoordinateTracker.propTypes = { + isPlaying: PropTypes.bool.isRequired, + sketchReloaded: PropTypes.bool.isRequired +}; + export default CoordinateTracker; diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index 17bfa08ab6..9456d40123 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -28,6 +28,7 @@ const App = () => { const [gridOutput, setGridOutput] = useState(false); const [userTheme, setUserTheme] = useState('light'); const [coordinatesVisible, setCoordinatesVisible] = useState(false); + const [sketchReloaded, setSketchReloaded] = useState(0); registerFrame(window.parent, getConfig('EDITOR_URL')); @@ -42,6 +43,7 @@ const App = () => { setGridOutput(payload.gridOutput); setUserTheme(payload.userTheme); setCoordinatesVisible(payload.coordinates); + setSketchReloaded((prev) => prev + 1); break; case MessageTypes.START: console.log('starting'); @@ -94,7 +96,12 @@ const App = () => { return ( - {coordinatesVisible && } + {coordinatesVisible && ( + + )} Date: Tue, 13 May 2025 13:29:25 -0400 Subject: [PATCH 21/21] remove logs --- client/modules/Preview/previewIndex.jsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/modules/Preview/previewIndex.jsx b/client/modules/Preview/previewIndex.jsx index 9456d40123..a4b123c526 100644 --- a/client/modules/Preview/previewIndex.jsx +++ b/client/modules/Preview/previewIndex.jsx @@ -33,7 +33,6 @@ const App = () => { registerFrame(window.parent, getConfig('EDITOR_URL')); function handleMessageEvent(message) { - console.log('message', message); const { type, payload } = message; switch (type) { case MessageTypes.SKETCH: @@ -46,7 +45,6 @@ const App = () => { setSketchReloaded((prev) => prev + 1); break; case MessageTypes.START: - console.log('starting'); setIsPlaying(true); break; case MessageTypes.STOP: @@ -60,7 +58,6 @@ const App = () => { dispatchMessage(payload); break; case MessageTypes.COORDINATES_VISIBILITY: - console.log('coordinates visibility', payload); if (isPlaying) setCoordinatesVisible(payload); break; default: