diff --git a/src/extensionsIntegrated/Phoenix/phoenix-tour.js b/src/extensionsIntegrated/Phoenix/phoenix-tour.js
index cbd137a563..2a0f156960 100644
--- a/src/extensionsIntegrated/Phoenix/phoenix-tour.js
+++ b/src/extensionsIntegrated/Phoenix/phoenix-tour.js
@@ -123,6 +123,8 @@ define(function (require, exports, module) {
function _setText(text) {
if ($overlay) {
+ // `text` may include `\n` for multi-line steps; CSS uses
+ // `white-space: pre-line` to render those line breaks.
$overlay.find(".phoenix-tour-text").text(text);
}
}
diff --git a/src/htmlContent/about-dialog.html b/src/htmlContent/about-dialog.html
index 81f495c252..021c3ade52 100644
--- a/src/htmlContent/about-dialog.html
+++ b/src/htmlContent/about-dialog.html
@@ -16,9 +16,10 @@
{{APP_NAME_ABOUT_BOX}}
{{/BUILD_TIMESTAMP}}
{{{Strings.ABOUT_RELEASE_CREDITS}}}
+ Arun Bose,
+ Charly P Abraham,
Devansh Agarwal,
- Arun Bose,
- Charly P Abraham
+ Krrish Parmar
Copyright 2021 - present Core.ai and its licensors. All rights reserved.
diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js
index 0d95aa809b..96d5ef9558 100644
--- a/src/nls/root/strings.js
+++ b/src/nls/root/strings.js
@@ -1670,7 +1670,7 @@ define({
"GUIDED_LIVE_PREVIEW_POPOUT": "Click this button to popout live preview to a new tab. ok",
// Phoenix onboarding tour (one-shot, app-lifetime)
"PHOENIX_TOUR_DESIGN_MODE": "Click here to enter Design Mode. Go full-screen and edit your page visually.",
- "PHOENIX_TOUR_AI_PANEL": "Click here to open the AI panel",
+ "PHOENIX_TOUR_AI_PANEL": "Design layouts, fix bugs, and build faster with AI. Click here to open the AI panel",
"PHOENIX_TOUR_NEW_PROJECT": "Open or create a new project from here",
"PHOENIX_TOUR_STEP_OF": "{0} of {1}",
"PHOENIX_TOUR_NEXT_BTN": "Next",
diff --git a/src/styles/Extn-PhoenixTour.less b/src/styles/Extn-PhoenixTour.less
index 79eecdbfa5..88ce05e8ff 100644
--- a/src/styles/Extn-PhoenixTour.less
+++ b/src/styles/Extn-PhoenixTour.less
@@ -117,6 +117,7 @@
.phoenix-tour-text {
display: block;
+ white-space: pre-line;
}
.phoenix-tour-actions {
diff --git a/src/view/CentralControlBar.js b/src/view/CentralControlBar.js
index 2d85c5c3f2..228992236b 100644
--- a/src/view/CentralControlBar.js
+++ b/src/view/CentralControlBar.js
@@ -271,7 +271,25 @@ define(function (require, exports, module) {
}
_applyCollapsedLayout();
} else {
- _restoreExpandedLayout(skipToolbarRestore);
+ // If live preview was NOT open before we entered design mode,
+ // exit into pure-code mode by closing it again. Snapshot the
+ // entry state before _restoreExpandedLayout resets it.
+ // skipToolbarRestore is already the LP-just-closed path, so
+ // don't double-close in that case. opts.keepLivePreviewOpen
+ // is the "intercepted #toolbar-go-live click" path — caller
+ // wants LP to stay regardless of entry state. _restoreExpandedLayout
+ // runs first so our !important geometry overrides are cleared
+ // before WorkspaceManager resizes #main-toolbar to the no-panel
+ // state.
+ const keepLivePreviewOpen = !!(opts && opts.keepLivePreviewOpen);
+ const shouldCloseLivePreview = !skipToolbarRestore &&
+ !keepLivePreviewOpen &&
+ !livePreviewWasOpen &&
+ _isLivePreviewOpen();
+ _restoreExpandedLayout(shouldCloseLivePreview ? true : skipToolbarRestore);
+ if (shouldCloseLivePreview) {
+ CommandManager.execute(Commands.FILE_LIVE_FILE_PREVIEW);
+ }
}
}
@@ -324,6 +342,25 @@ define(function (require, exports, module) {
$("#ccbUndoBtn").attr("title", Strings.CMD_UNDO);
$("#ccbRedoBtn").attr("title", Strings.CMD_REDO);
$("#ccbSaveBtn").attr("title", Strings.CMD_FILE_SAVE);
+
+ // Intercept clicks on #toolbar-go-live while in design mode: instead
+ // of letting the live-preview module hide LP (the default toggle
+ // behaviour), we exit design mode and keep LP visible. Outside
+ // design mode the button continues to toggle LP normally — we only
+ // act when `editorCollapsed` is true. Capture phase + stopImmediate-
+ // Propagation guarantees we run before the live-preview module's
+ // jQuery click handler.
+ const goLiveBtn = document.getElementById("toolbar-go-live");
+ if (goLiveBtn) {
+ goLiveBtn.addEventListener("click", function (e) {
+ if (!editorCollapsed) {
+ return;
+ }
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ _setEditorCollapsed(false, { keepLivePreviewOpen: true });
+ }, true /* useCapture */);
+ }
_syncLeftPositions();
// While the sidebar is being dragged we only reposition CCB / main-toolbar.
diff --git a/test/spec/CentralControlBar-integ-test.js b/test/spec/CentralControlBar-integ-test.js
index 104e3377f0..3fe377a13d 100644
--- a/test/spec/CentralControlBar-integ-test.js
+++ b/test/spec/CentralControlBar-integ-test.js
@@ -570,11 +570,19 @@ define(function (require, exports, module) {
"sidebar to settle at baseline 200px", 2000);
});
- it("should leave Live Preview open after exit", async function () {
+ it("should leave Live Preview open after exit when LP was already open at entry", async function () {
+ // Mirror of the "LP was opened by the toggle" test below: when
+ // the user already had LP open, exiting design mode must keep
+ // LP visible and main-toolbar at a real LP-panel width (well
+ // above the icon-bar width).
await openLivePreview();
await enterDesignMode();
await exitDesignMode();
+
expect(livePanel().isVisible()).toBe(true);
+ const iconsW = _$("#plugin-icons-bar").outerWidth();
+ const toolbarW = _$("#main-toolbar").outerWidth();
+ expect(toolbarW).toBeGreaterThan(iconsW + 50);
});
it("should fit sidebar + CCB + toolbar + a reasonable editor area in the window after exit", async function () {
@@ -591,17 +599,20 @@ define(function (require, exports, module) {
expect(testWindow.innerWidth - total).toBeGreaterThan(100);
});
- it("should use the innerWidth/2.5 default for toolbar when LP was opened by the toggle itself", async function () {
- // LP is closed on entry — the toggle opens it.
+ it("should close Live Preview and shrink toolbar to the icon-bar width when LP was opened by the toggle itself", async function () {
+ // LP is closed on entry — the toggle opens it. On exit we
+ // restore the original "pure code" layout: LP closes again
+ // and main-toolbar shrinks to the icon-bar width.
await enterDesignMode();
+ expect(livePanel().isVisible()).toBe(true);
await exitDesignMode();
- expect(livePanel().isVisible()).toBe(true);
- const expectedDefault = Math.floor(testWindow.innerWidth / 2.5);
- // `_restoreExpandedLayout` may trim a bit to honour the MIN_EDITOR clamp
- // on narrow viewports, so compare with a generous tolerance.
- const toolbar = _$("#main-toolbar").outerWidth();
- expect(Math.abs(toolbar - expectedDefault)).toBeLessThan(30);
+ await awaitsFor(function () { return !livePanel().isVisible(); },
+ "live preview to close on exit", 5000);
+
+ const iconsW = _$("#plugin-icons-bar").outerWidth();
+ const toolbarW = _$("#main-toolbar").outerWidth();
+ expect(Math.abs(toolbarW - iconsW)).toBeLessThan(3);
});
it("should not let the sidebar snap wider than the rendered (capped) width after exit even if user dragged past the cap in design mode", async function () {
@@ -643,27 +654,41 @@ define(function (require, exports, module) {
});
});
- describe("6. Exit triggered by hiding live preview", function () {
+ describe("6. #toolbar-go-live click in design mode", function () {
- it("should exit design mode, hide LP, and shrink main-toolbar to the icon-bar width when #toolbar-go-live is clicked in design mode", async function () {
+ it("should exit design mode and keep Live Preview visible when #toolbar-go-live is clicked in design mode", async function () {
await openLivePreview();
await enterDesignMode();
expect(WorkspaceManager.isInDesignMode()).toBe(true);
expect(livePanel().isVisible()).toBe(true);
- _$("#toolbar-go-live").trigger("click");
+ // Native click — CCB intercepts via a capture-phase listener,
+ // which jQuery's `.trigger("click")` would not exercise.
+ _$("#toolbar-go-live")[0].click();
- // LP hides → visible to the user.
- await awaitsFor(function () { return !livePanel().isVisible(); },
- "live preview to hide", 5000);
- // And the editor chrome comes back — design mode ends.
+ // Design mode ends — editor chrome comes back.
await awaitsFor(function () { return !WorkspaceManager.isInDesignMode(); },
- "design mode to deactivate after LP close", 5000);
+ "design mode to deactivate after toolbar-go-live click", 5000);
+ // LP should remain open — the click in design mode must NOT hide it.
+ expect(livePanel().isVisible()).toBe(true);
- // Main-toolbar should end up at the icon-bar-only width (its no-panel state).
+ // Main-toolbar should be at a real LP-panel width (well above
+ // just the icon-bar width).
const iconsW = _$("#plugin-icons-bar").outerWidth();
const toolbarW = _$("#main-toolbar").outerWidth();
- expect(Math.abs(toolbarW - iconsW)).toBeLessThan(3);
+ expect(toolbarW).toBeGreaterThan(iconsW + 50);
+ });
+
+ it("should toggle Live Preview off normally when #toolbar-go-live is clicked outside design mode", async function () {
+ await openLivePreview();
+ expect(WorkspaceManager.isInDesignMode()).toBe(false);
+ expect(livePanel().isVisible()).toBe(true);
+
+ _$("#toolbar-go-live")[0].click();
+
+ await awaitsFor(function () { return !livePanel().isVisible(); },
+ "live preview to hide on toolbar-go-live click", 5000);
+ expect(WorkspaceManager.isInDesignMode()).toBe(false);
});
});
diff --git a/tracking-repos.json b/tracking-repos.json
index d9af866619..cfaa8e742a 100644
--- a/tracking-repos.json
+++ b/tracking-repos.json
@@ -1,5 +1,5 @@
{
"phoenixPro": {
- "commitID": "35a5652662376d7149a1a9b7cf6d4f5ad9cf3cd5"
+ "commitID": "335648a9525b6ba669b311af3f102b3a73de2664"
}
}