diff --git a/.github/workflows/playwright-chromium-integ.yml b/.github/workflows/playwright-chromium-integ.yml index edcb94cc5..2dde8b53c 100644 --- a/.github/workflows/playwright-chromium-integ.yml +++ b/.github/workflows/playwright-chromium-integ.yml @@ -4,7 +4,7 @@ on: branches: [ main ] jobs: test: - timeout-minutes: 60 + timeout-minutes: 90 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -16,14 +16,21 @@ jobs: run: npx playwright install --with-deps - name: Run Playwright integration tests in Chromium Attempt 1 - timeout-minutes: 30 id: attemptC1 + timeout-minutes: 20 continue-on-error: true run: npm run testIntegChromium - name: Run Playwright integration tests in Chromium Attempt 2 - if: steps.attemptC1.outcome == 'failure' id: attemptC2 + if: steps.attemptC1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true + run: npm run testIntegChromium + + - name: Run Playwright integration tests in Chromium Attempt 3 + id: attemptC3 + if: steps.attemptC2.outcome == 'failure' run: npm run testIntegChromium - uses: actions/upload-artifact@v3 diff --git a/.github/workflows/playwright-chromium.yml b/.github/workflows/playwright-chromium.yml index 2ab4a6006..d9f667b4a 100644 --- a/.github/workflows/playwright-chromium.yml +++ b/.github/workflows/playwright-chromium.yml @@ -14,8 +14,25 @@ jobs: run: npm run build - name: Install Playwright Browsers run: npx playwright install --with-deps - - name: Run Playwright tests in chromium + + - name: Run Playwright unit tests in Chromium Attempt 1 + id: attemptC1 + timeout-minutes: 20 + continue-on-error: true run: npm run testChromium + + - name: Run Playwright unit tests in Chromium Attempt 2 + id: attemptC2 + if: steps.attemptC1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true + run: npm run testChromium + + - name: Run Playwright unit tests in Chromium Attempt 3 + id: attemptC3 + if: steps.attemptC2.outcome == 'failure' + run: npm run testChromium + - uses: actions/upload-artifact@v3 if: always() with: diff --git a/.github/workflows/playwright-firefox-integ.yml b/.github/workflows/playwright-firefox-integ.yml index 447aad4ff..4e5ba59cf 100644 --- a/.github/workflows/playwright-firefox-integ.yml +++ b/.github/workflows/playwright-firefox-integ.yml @@ -4,7 +4,7 @@ on: branches: [ main ] jobs: test: - timeout-minutes: 60 + timeout-minutes: 90 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -14,15 +14,23 @@ jobs: run: npm run build - name: Install Playwright Browsers run: npx playwright install --with-deps + - name: Run Playwright integration tests in firefox Attempt 1 - timeout-minutes: 30 id: attempt1 + timeout-minutes: 20 continue-on-error: true run: npm run testIntegFirefox - name: Run Playwright integration tests in firefox Attempt 2 - if: steps.attempt1.outcome == 'failure' id: attempt2 + if: steps.attempt1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true + run: npm run testIntegFirefox + + - name: Run Playwright integration tests in firefox Attempt 3 + id: attempt3 + if: steps.attempt2.outcome == 'failure' run: npm run testIntegFirefox - uses: actions/upload-artifact@v3 diff --git a/.github/workflows/playwright-firefox.yml b/.github/workflows/playwright-firefox.yml index 07eb53994..d3a28be15 100644 --- a/.github/workflows/playwright-firefox.yml +++ b/.github/workflows/playwright-firefox.yml @@ -14,8 +14,25 @@ jobs: run: npm run build - name: Install Playwright Browsers run: npx playwright install --with-deps - - name: Run Playwright tests in firefox + + - name: Run Playwright unit tests in firefox Attempt 1 + id: attempt1 + timeout-minutes: 20 + continue-on-error: true run: npm run testFirefox + + - name: Run Playwright unit tests in firefox Attempt 2 + id: attempt2 + if: steps.attempt1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true + run: npm run testFirefox + + - name: Run Playwright unit tests in firefox Attempt 3 + id: attempt3 + if: steps.attempt2.outcome == 'failure' + run: npm run testFirefox + - uses: actions/upload-artifact@v3 if: always() with: diff --git a/.github/workflows/playwright-on-push.yml b/.github/workflows/playwright-on-push.yml index d5b563084..cdfef2e04 100644 --- a/.github/workflows/playwright-on-push.yml +++ b/.github/workflows/playwright-on-push.yml @@ -24,11 +24,26 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - - name: Run Playwright unit tests in Firefox + - name: Run Playwright unit tests in firefox Attempt 1 + id: attempt1 + timeout-minutes: 20 + continue-on-error: true + run: npm run testFirefox + + - name: Run Playwright unit tests in firefox Attempt 2 + id: attempt2 + if: steps.attempt1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true + run: npm run testFirefox + + - name: Run Playwright unit tests in firefox Attempt 3 + id: attempt3 + if: steps.attempt2.outcome == 'failure' run: npm run testFirefox testFirefoxInteg: - timeout-minutes: 60 + timeout-minutes: 90 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -50,9 +65,16 @@ jobs: - name: Run Playwright integration tests in firefox Attempt 2 if: steps.attempt1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true id: attempt2 run: npm run testIntegFirefox + - name: Run Playwright integration tests in firefox Attempt 3 + if: steps.attempt2.outcome == 'failure' + id: attempt3 + run: npm run testIntegFirefox + testChromiumUnit: timeout-minutes: 60 runs-on: ubuntu-latest @@ -68,11 +90,26 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - - name: Run Playwright unit tests in Chromium + - name: Run Playwright unit tests in Chromium Attempt 1 + id: attemptC1 + timeout-minutes: 20 + continue-on-error: true + run: npm run testChromium + + - name: Run Playwright unit tests in Chromium Attempt 2 + id: attemptC2 + if: steps.attemptC1.outcome == 'failure' + timeout-minutes: 30 + continue-on-error: true + run: npm run testChromium + + - name: Run Playwright unit tests in Chromium Attempt 3 + id: attemptC3 + if: steps.attemptC2.outcome == 'failure' run: npm run testChromium testChromiumInteg: - timeout-minutes: 60 + timeout-minutes: 90 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -93,10 +130,17 @@ jobs: run: npm run testIntegChromium - name: Run Playwright integration tests in Chromium Attempt 2 + timeout-minutes: 30 + continue-on-error: true if: steps.attemptC1.outcome == 'failure' id: attemptC2 run: npm run testIntegChromium + - name: Run Playwright integration tests in Chromium Attempt 3 + if: steps.attemptC2.outcome == 'failure' + id: attemptC3 + run: npm run testIntegChromium + raiseIssue: needs: [ testFirefoxUnit, testFirefoxInteg, testChromiumUnit, testChromiumInteg] runs-on: ubuntu-latest diff --git a/src-node/package.json b/src-node/package.json index 6c36618b6..aa664a75b 100644 --- a/src-node/package.json +++ b/src-node/package.json @@ -8,6 +8,7 @@ "homepage": "https://github.com/phcode-dev/phoenix", "license": "GNU-AGPL3.0", "scripts": { + "_watch_src-node": "cd .. && npm run _watch_src-node" }, "engines": { "node": "18" diff --git a/src/assets/new-project/assets/js/code-editor.js b/src/assets/new-project/assets/js/code-editor.js index 685eafdcf..435524e56 100644 --- a/src/assets/new-project/assets/js/code-editor.js +++ b/src/assets/new-project/assets/js/code-editor.js @@ -77,15 +77,13 @@ function getDisplayLocation(projectPath) { return Strings.PROJECT_FROM_BROWSER; } -const DEFAULT_PROJECT_PATH = '/fs/local/default project'; - function _updateProjectCards() { let recentProjectList = $(document.getElementById('recentProjectList')); recentProjectList.empty(); let recentProjects = recentProjectExtension.getRecentProjects(); let tabIndex = 1; - let defaultProjects = [DEFAULT_PROJECT_PATH, '/fs/local/explore'], - omitProjectsInListing = ['/fs/local/explore'], + let defaultProjects = [newProjectExtension.getWelcomeProjectPath(), newProjectExtension.getExploreProjectPath()], + omitProjectsInListing = [newProjectExtension.getExploreProjectPath()], showRecentProjects = false; for(let recentProject of recentProjects){ if(!defaultProjects.includes(recentProject)){ diff --git a/src/assets/new-project/assets/js/new-project-more.js b/src/assets/new-project/assets/js/new-project-more.js index 051b9c24c..969f0fffc 100644 --- a/src/assets/new-project/assets/js/new-project-more.js +++ b/src/assets/new-project/assets/js/new-project-more.js @@ -30,7 +30,8 @@ function _getIconURL(iconURL) { return 'images/Bootstrap_logo.svg'; } else if(iconURL === 'appLogo'){ return 'images/logo.png'; - } else if(iconURL && (iconURL.startsWith("https://") || iconURL.startsWith("http://") || iconURL.startsWith("tauri://"))){ + } else if(iconURL && (iconURL.startsWith("https://") || iconURL.startsWith("http://") + || iconURL.startsWith("tauri://") || iconURL.startsWith("asset://"))){ return iconURL; } return 'images/tab-img2.png'; // HTML icon diff --git a/src/extensibility/Package.js b/src/extensibility/Package.js index 23ef7afab..491c3b06c 100644 --- a/src/extensibility/Package.js +++ b/src/extensibility/Package.js @@ -176,7 +176,7 @@ define(function (require, exports, module) { ExtensionLoader.loadExtension(result.name, { // On Windows, it looks like Node converts Unix-y paths to backslashy paths. // We need to convert them back. - baseUrl: window.fsServerUrl.slice(0, -1) + result.installedTo + baseUrl: window.Phoenix.VFS.getVirtualServingURLForPath(result.installedTo) }, "main").then(function () { d.resolve(result); }, function () { @@ -241,11 +241,12 @@ define(function (require, exports, module) { d.reject(Errors.MALFORMED_URL); return d.promise(); } - if (!(parsed.protocol === "http:" || parsed.protocol === "https:" || parsed.protocol === "tauri:")) { + if (!(parsed.protocol === "http:" || parsed.protocol === "https:" + || parsed.protocol === "tauri:" || parsed.protocol === "asset:")) { d.reject(Errors.UNSUPPORTED_PROTOCOL); return d.promise(); } - + parsed.filename = FileUtils.convertWindowsPathToUnixPath(parsed.filename); const urlInfo = { url: url, parsed: parsed, filenameHint: parsed.filename, destinationDirectory }; githubURLFilter(urlInfo); diff --git a/src/extensions/default/DebugCommands/main.js b/src/extensions/default/DebugCommands/main.js index 3d2590b4b..01dd525cc 100644 --- a/src/extensions/default/DebugCommands/main.js +++ b/src/extensions/default/DebugCommands/main.js @@ -715,7 +715,11 @@ define(function (require, exports, module) { } function _openVirtualServer() { - Phoenix.app.openURLInPhoenixWindow(window.fsServerUrl, { + const virtualServingURL = Phoenix.VFS.getVirtualServingURLForPath("/"); + if(!virtualServingURL) { + throw new Error("Unable to find virtual server!"); + } + Phoenix.app.openURLInPhoenixWindow(virtualServingURL, { preferTabs: true }); } @@ -775,13 +779,20 @@ define(function (require, exports, module) { menu.addMenuItem(DEBUG_LIVE_PREVIEW_LOGGING); menu.addMenuDivider(); menu.addMenuItem(DEBUG_OPEN_VFS); - menu.addMenuItem(DEBUG_OPEN_VIRTUAL_SERVER); + menu.addMenuItem(DEBUG_OPEN_VIRTUAL_SERVER, undefined, undefined, undefined, { + hideWhenCommandDisabled: true + }); menu.addMenuDivider(); menu.addMenuItem(DEBUG_OPEN_PREFERENCES_IN_SPLIT_VIEW); // this command will enable defaultPreferences and brackets preferences to be open side by side in split view. menu.addMenuItem(Commands.FILE_OPEN_KEYMAP); // this command is defined in core, but exposed only in Debug menu for now CommandManager.get(DEBUG_UNLOAD_CURRENT_EXTENSION) .setEnabled(extensionDevelopment.isProjectLoadedAsExtension()); + if(window.__TAURI__) { + // in tauri, virtual server doesnt exist, extensions are served by tauri asset urls. + CommandManager.get(DEBUG_OPEN_VIRTUAL_SERVER) + .setEnabled(false); + } _updateLogToConsoleMenuItemChecked(); // exposed for convenience, but not official API exports._runUnitTests = _runUnitTests; diff --git a/src/extensions/default/HTMLCodeHints/HTMLJumpToDef.js b/src/extensions/default/HTMLCodeHints/HTMLJumpToDef.js index 8b5a8e957..71de6b2b0 100644 --- a/src/extensions/default/HTMLCodeHints/HTMLJumpToDef.js +++ b/src/extensions/default/HTMLCodeHints/HTMLJumpToDef.js @@ -58,7 +58,8 @@ define(function (require, exports, module) { }; function _openFile(fileRelativePath, mainDocPath) { - if(fileRelativePath.startsWith("http://") || fileRelativePath.startsWith("https://")){ + if(fileRelativePath.startsWith("http://") || fileRelativePath.startsWith("https://") + || fileRelativePath.startsWith("tauri://") || fileRelativePath.startsWith("asset://")){ return FileViewController.openAndSelectDocument(fileRelativePath, FileViewController.PROJECT_MANAGER); } const targetPath = path.resolve(mainDocPath, fileRelativePath); diff --git a/src/extensions/default/Phoenix-live-preview/main.js b/src/extensions/default/Phoenix-live-preview/main.js index 8759d6082..4305711e6 100644 --- a/src/extensions/default/Phoenix-live-preview/main.js +++ b/src/extensions/default/Phoenix-live-preview/main.js @@ -66,7 +66,7 @@ define(function (require, exports, module) { `; diff --git a/src/extensions/default/Phoenix-live-preview/panel.html b/src/extensions/default/Phoenix-live-preview/panel.html index 000fe7170..a16af77b0 100644 --- a/src/extensions/default/Phoenix-live-preview/panel.html +++ b/src/extensions/default/Phoenix-live-preview/panel.html @@ -18,7 +18,7 @@
diff --git a/src/extensions/default/Phoenix/newly-added-features.js b/src/extensions/default/Phoenix/newly-added-features.js index 1ede11221..296af3957 100644 --- a/src/extensions/default/Phoenix/newly-added-features.js +++ b/src/extensions/default/Phoenix/newly-added-features.js @@ -93,7 +93,9 @@ define(function (require, exports, module) { if(!Phoenix.firstBoot && !window.testEnvironment){ _showNewUpdatesIfPresent(); } - Metrics.countEvent(Metrics.EVENT_TYPE.PLATFORM, "cache", "doRefresh"); - window.refreshServiceWorkerCache(_cacheUpdatedCB); + if(!Phoenix.browser.isTauri) { + Metrics.countEvent(Metrics.EVENT_TYPE.PLATFORM, "cache", "doRefresh"); + window.refreshServiceWorkerCache(_cacheUpdatedCB); + } }; }); diff --git a/src/extensions/default/QuickView/ImagePreviewProvider.js b/src/extensions/default/QuickView/ImagePreviewProvider.js index d8372ee9d..f4eafaab1 100644 --- a/src/extensions/default/QuickView/ImagePreviewProvider.js +++ b/src/extensions/default/QuickView/ImagePreviewProvider.js @@ -41,7 +41,7 @@ define(function (require, exports, module) { extensionlessImagePreview; // Whether to try and preview extensionless URLs // List of protocols which we will support for image preview urls - let validProtocols = ["data:", "http:", "https:", "tauri:", "ftp:", "file:"]; + let validProtocols = ["data:", "http:", "https:", "tauri:", "asset:", "ftp:", "file:"]; prefs = PreferencesManager.getExtensionPrefs("quickview"); diff --git a/src/extensions/default/RecentProjects/main.js b/src/extensions/default/RecentProjects/main.js index 627d19ada..27db65f17 100644 --- a/src/extensions/default/RecentProjects/main.js +++ b/src/extensions/default/RecentProjects/main.js @@ -19,6 +19,8 @@ * */ +/*global Phoenix*/ + define(function (require, exports, module) { @@ -347,23 +349,17 @@ define(function (require, exports, module) { /** * Parses the path and returns an object with the full path, the folder name and the path without the folder. - * @param {string} path The full path to the folder. + * @param {string} fullPath The full path to the folder. * @return {{path: string, folder: string, rest: string}} */ - function parsePath(path) { - var lastSlash = path.lastIndexOf("/"), folder, rest; - if (lastSlash === path.length - 1) { - lastSlash = path.slice(0, path.length - 1).lastIndexOf("/"); - } - if (lastSlash >= 0) { - rest = " - " + (lastSlash ? path.slice(0, lastSlash) : "/"); - folder = path.slice(lastSlash + 1); - } else { - rest = "/"; - folder = path; + function renderPath(fullPath) { + let parentDirPath = window.path.dirname(fullPath); + if(parentDirPath.startsWith(Phoenix.VFS.getTauriDir())) { + parentDirPath = window.fs.getTauriPlatformPath(parentDirPath); } + const rest = " - " + parentDirPath; - return {path: path, folder: folder, rest: rest}; + return {path: fullPath, folder: window.path.basename(fullPath), rest: rest}; } /** @@ -382,7 +378,7 @@ define(function (require, exports, module) { recentProjects.forEach(function (root) { if (root !== currentProject) { - templateVars.projectList.push(parsePath(root)); + templateVars.projectList.push(renderPath(root)); } }); diff --git a/src/extensions/default/RemoteFileAdapter/main.js b/src/extensions/default/RemoteFileAdapter/main.js index f82f54ee3..d124daa63 100644 --- a/src/extensions/default/RemoteFileAdapter/main.js +++ b/src/extensions/default/RemoteFileAdapter/main.js @@ -32,9 +32,10 @@ define(function (require, exports, module) { MainViewManager = brackets.getModule("view/MainViewManager"), Menus = brackets.getModule("command/Menus"); - var HTTP_PROTOCOL = "http:", + const HTTP_PROTOCOL = "http:", HTTPS_PROTOCOL = "https:", - TAURI_PROTOCOL = "tauri:"; + TAURI_PROTOCOL = "tauri:", + TAURI_ASSET_PROTOCOL = "asset:"; ExtensionUtils.loadStyleSheet(module, "styles.css"); @@ -51,6 +52,10 @@ define(function (require, exports, module) { return "tauri"; } + if (data.fullPath.startsWith("asset://")) { + return "asset"; + } + return ""; } @@ -129,7 +134,7 @@ define(function (require, exports, module) { }, match: function (query) { var protocol = PathUtils.parseUrl(query).protocol; - return [HTTP_PROTOCOL, HTTPS_PROTOCOL, TAURI_PROTOCOL].indexOf(protocol) !== -1; + return [HTTP_PROTOCOL, HTTPS_PROTOCOL, TAURI_PROTOCOL, TAURI_ASSET_PROTOCOL].indexOf(protocol) !== -1; }, itemFocus: function (query) { // no op diff --git a/src/filesystem/FileSystem.js b/src/filesystem/FileSystem.js index 66df955d9..41b3c8f23 100644 --- a/src/filesystem/FileSystem.js +++ b/src/filesystem/FileSystem.js @@ -1229,7 +1229,8 @@ define(function (require, exports, module) { // attach remote file handlers var HTTP_PROTOCOL = "http:", HTTPS_PROTOCOL = "https:", - TAURI_PROTOCOL = "tauri:"; + TAURI_PROTOCOL = "tauri:", + TAURI_ASSET_PROTOCOL = "asset:"; var protocolAdapter = { priority: 0, // Default priority @@ -1243,4 +1244,5 @@ define(function (require, exports, module) { registerProtocolAdapter(HTTP_PROTOCOL, protocolAdapter); registerProtocolAdapter(HTTPS_PROTOCOL, protocolAdapter); registerProtocolAdapter(TAURI_PROTOCOL, protocolAdapter); + registerProtocolAdapter(TAURI_ASSET_PROTOCOL, protocolAdapter); }); diff --git a/src/index.html b/src/index.html index ce6e4248a..40d4c80cd 100644 --- a/src/index.html +++ b/src/index.html @@ -26,9 +26,12 @@ + content="default-src 'self' 'unsafe-inline' 'unsafe-eval' data: asset: https://asset.localhost localhost:* ws://localhost:* https://storage.googleapis.com https://platform.twitter.com https://buttons.github.io https://unpkg.com/@aicore/ https://www.googletagmanager.com; + img-src * data: localhost:* asset: https://asset.localhost ; + media-src * data: localhost:* asset: https://asset.localhost ; + font-src * data: localhost:* asset: https://asset.localhost ; + frame-src * localhost:* asset: https://asset.localhost ; + connect-src * localhost:* asset: https://asset.localhost ;"> @@ -39,8 +42,32 @@