Skip to content

Commit b92a8ee

Browse files
authored
Merge pull request #17 from exelearning/hotfix/fix-save-in-playground
Fix beforeunload dialog on save and add Playground support
2 parents 20e06bb + dc60014 commit b92a8ee

File tree

6 files changed

+264
-197
lines changed

6 files changed

+264
-197
lines changed

Makefile

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ EDITOR_OUTPUT_DIR := $(CURDIR)/dist/static
2020
EDITOR_REPO_DEFAULT := https://github.com/exelearning/exelearning.git
2121
EDITOR_REF_DEFAULT := main
2222

23-
# Fetch editor source code from remote repository (branch/tag, shallow clone)
23+
# Fetch editor source code from remote repository (clone or update existing)
2424
fetch-editor-source:
2525
@set -e; \
2626
get_env() { \
@@ -36,9 +36,15 @@ fetch-editor-source:
3636
if [ -z "$$REF" ]; then REF="$(EDITOR_REF_DEFAULT)"; fi; \
3737
if [ -z "$$REF_TYPE" ]; then REF_TYPE="auto"; fi; \
3838
echo "Fetching editor source from $$REPO_URL (ref=$$REF, type=$$REF_TYPE)"; \
39-
rm -rf $(EDITOR_SUBMODULE_PATH); \
40-
git init -q $(EDITOR_SUBMODULE_PATH); \
41-
git -C $(EDITOR_SUBMODULE_PATH) remote add origin "$$REPO_URL"; \
39+
if [ -d "$(EDITOR_SUBMODULE_PATH)/.git" ]; then \
40+
echo "Updating existing editor source..."; \
41+
git -C $(EDITOR_SUBMODULE_PATH) remote set-url origin "$$REPO_URL"; \
42+
else \
43+
rm -rf $(EDITOR_SUBMODULE_PATH); \
44+
git init -q $(EDITOR_SUBMODULE_PATH); \
45+
git -C $(EDITOR_SUBMODULE_PATH) remote add origin "$$REPO_URL"; \
46+
fi; \
47+
OLD_HEAD=$$(git -C $(EDITOR_SUBMODULE_PATH) rev-parse HEAD 2>/dev/null || echo "none"); \
4248
case "$$REF_TYPE" in \
4349
tag) \
4450
git -C $(EDITOR_SUBMODULE_PATH) fetch --depth 1 origin "refs/tags/$$REF:refs/tags/$$REF"; \
@@ -62,7 +68,13 @@ fetch-editor-source:
6268
echo "Error: EXELEARNING_EDITOR_REF_TYPE must be one of: auto, branch, tag"; \
6369
exit 1; \
6470
;; \
65-
esac
71+
esac; \
72+
NEW_HEAD=$$(git -C $(EDITOR_SUBMODULE_PATH) rev-parse HEAD); \
73+
if [ "$$OLD_HEAD" = "$$NEW_HEAD" ]; then \
74+
echo "Editor source is already up to date ($$NEW_HEAD)."; \
75+
else \
76+
echo "Editor source updated: $$OLD_HEAD -> $$NEW_HEAD"; \
77+
fi
6678

6779
# Build static version of eXeLearning editor
6880
build-editor: check-bun fetch-editor-source
@@ -75,11 +87,26 @@ build-editor: check-bun fetch-editor-source
7587
mkdir -p $(EDITOR_OUTPUT_DIR); \
7688
cp -R $(EDITOR_SUBMODULE_PATH)/dist/static/* $(EDITOR_OUTPUT_DIR)/; \
7789
fi
90+
@# Save the commit hash used for this build
91+
@git -C $(EDITOR_SUBMODULE_PATH) rev-parse HEAD > $(EDITOR_OUTPUT_DIR)/.build-commit 2>/dev/null || true
7892
@echo ""
7993
@echo "============================================"
8094
@echo " Static editor built at dist/static/"
8195
@echo "============================================"
8296

97+
# Build only if needed: skip when dist/static/ exists and source hasn't changed
98+
build-editor-if-needed: fetch-editor-source
99+
@BUILD_COMMIT=""; \
100+
if [ -f "$(EDITOR_OUTPUT_DIR)/.build-commit" ]; then \
101+
BUILD_COMMIT=$$(cat "$(EDITOR_OUTPUT_DIR)/.build-commit"); \
102+
fi; \
103+
CURRENT_COMMIT=$$(git -C $(EDITOR_SUBMODULE_PATH) rev-parse HEAD 2>/dev/null || echo "unknown"); \
104+
if [ -f "$(EDITOR_OUTPUT_DIR)/index.html" ] && [ "$$BUILD_COMMIT" = "$$CURRENT_COMMIT" ]; then \
105+
echo "Static editor is up to date ($$CURRENT_COMMIT), skipping build."; \
106+
else \
107+
$(MAKE) build-editor; \
108+
fi
109+
83110
# Backward-compatible alias
84111
build-editor-no-update: build-editor
85112

@@ -117,8 +144,26 @@ start-if-not-running:
117144
echo "wp-env is already running, skipping start."; \
118145
fi
119146

120-
# Bring up Docker containers (fetch editor source and rebuild static editor)
121-
up: check-docker build-editor-no-update start-if-not-running
147+
# Bring up Docker containers (build editor if needed)
148+
up: check-docker build-editor-if-needed start-if-not-running
149+
150+
# Start with Playground runtime (no Docker required, for quick testing)
151+
up-playground: build-editor-if-needed
152+
@if [ "$$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8888)" = "000" ]; then \
153+
echo "Starting wp-env with Playground runtime..."; \
154+
npx wp-env start --runtime=playground --update; \
155+
echo "Visit http://localhost:8888/wp-admin/ to access the eXeLearning dashboard (admin/password)."; \
156+
else \
157+
echo "wp-env is already running, skipping start."; \
158+
fi
159+
160+
# Reset the WordPress database (works with both Docker and Playground runtimes)
161+
reset:
162+
@npx wp-env reset development 2>/dev/null || { \
163+
echo ""; \
164+
echo "wp-env reset failed (Playground runtime does not support reset)."; \
165+
echo "Run 'make destroy' followed by 'make up' or 'make up-playground' to start fresh."; \
166+
}
122167

123168
flush-permalinks:
124169
npx wp-env run cli wp rewrite structure '/%postname%/'
@@ -135,13 +180,20 @@ create-user:
135180
down: check-docker
136181
npx wp-env stop
137182

138-
# Clean the environments, the same that running "npx wp-env clean all"
183+
# Stop Playground runtime (no Docker required)
184+
down-playground:
185+
npx wp-env stop
186+
187+
# Clean the environments (reset database and re-activate plugin)
139188
clean:
140-
npx wp-env clean development
141-
npx wp-env clean tests
142-
npx wp-env run cli wp plugin activate exelearning
143-
npx wp-env run cli wp language core install es_ES --activate
144-
npx wp-env run cli wp site switch-language es_ES
189+
@npx wp-env reset development 2>/dev/null && \
190+
npx wp-env run cli wp plugin activate exelearning && \
191+
npx wp-env run cli wp language core install es_ES --activate && \
192+
npx wp-env run cli wp site switch-language es_ES || { \
193+
echo ""; \
194+
echo "wp-env reset failed (Playground runtime does not support reset)."; \
195+
echo "Use 'make destroy' followed by 'make up-playground' to start fresh."; \
196+
}
145197

146198

147199

@@ -402,7 +454,10 @@ help:
402454
@echo ""
403455
@echo "General:"
404456
@echo " up - Fetch source, build static editor, and start Docker containers"
457+
@echo " up-playground - Same as 'up' but using Playground runtime (no Docker required)"
405458
@echo " down - Stop and remove Docker containers"
459+
@echo " down-playground - Stop Playground runtime (no Docker required)"
460+
@echo " reset - Reset the WordPress database"
406461
@echo " logs - Show the docker container logs"
407462
@echo " logs-test - Show logs from test environment"
408463
@echo " clean - Clean up WordPress environment"

assets/js/elp-upload.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@
8484
return;
8585
}
8686

87+
// Prevent the preview iframe from triggering "Leave site?" dialogs.
88+
// Override the setter so scripts inside the iframe cannot set it.
89+
var iframeWin = iframe.contentWindow;
90+
iframeWin.onbeforeunload = null;
91+
try {
92+
Object.defineProperty( iframeWin, 'onbeforeunload', {
93+
get: function() { return null; },
94+
set: function() {},
95+
configurable: true,
96+
} );
97+
} catch ( ignore ) {}
98+
8799
var existing = doc.getElementById( TEACHER_MODE_STYLE_ID );
88100

89101
if ( ! attributes.teacherModeVisible ) {

assets/js/exelearning-editor.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,18 +255,21 @@
255255
}
256256
}
257257

258-
try {
259-
const iframeWindow = this.iframe[0]?.contentWindow;
260-
if ( iframeWindow ) {
261-
iframeWindow.onbeforeunload = null;
262-
}
263-
} catch ( e ) {}
258+
// Replace the iframe with a fresh clone to destroy all event listeners
259+
// (including the editor's beforeunload addEventListener) without
260+
// triggering a "Leave site?" dialog on navigation.
261+
var iframeEl = this.iframe[0];
262+
if ( iframeEl ) {
263+
var newIframe = iframeEl.cloneNode( false );
264+
newIframe.src = 'about:blank';
265+
iframeEl.parentNode.replaceChild( newIframe, iframeEl );
266+
this.iframe = $( newIframe );
267+
}
264268

265269
var wasShowingLoader = this.isSaving || ( skipConfirm === true );
266270
this.modal.hide();
267271
this.isOpen = false;
268272
this.hasUnsavedChanges = false;
269-
this.iframe.attr( 'src', 'about:blank' );
270273
$( 'body' ).removeClass( 'exelearning-editor-open' );
271274
this.currentAttachmentId = null;
272275
this.exportRequestId = null;

0 commit comments

Comments
 (0)