From e52477fc9e453b218b3d0b463b6c449bd0fce2cf Mon Sep 17 00:00:00 2001 From: Marko Stijak Date: Tue, 31 Mar 2026 12:55:47 +0200 Subject: [PATCH 1/2] Add legacy app warning to all apps --- legacy/fiddle/app/components/CodeMirror.scss | 4 - legacy/fiddle/app/components/Preview.js | 9 +- legacy/fiddle/app/components/index.scss | 8 +- legacy/fiddle/app/core/addImports.js | 9 +- legacy/fiddle/app/index.html | 14 +- legacy/fiddle/app/index.scss | 34 +- .../fiddle/app/routes/default/Controller.js | 2 +- legacy/fiddle/app/routes/default/index.scss | 2 + legacy/fiddle/app/routes/index.js | 22 +- .../fiddle/app/routes/preview/Controller.js | 2 +- legacy/fiddle/app/variables.scss | 4 + legacy/fiddle/webpack.config.js | 379 +++++++++--------- legacy/misc/components/SideNav.scss | 6 +- legacy/misc/layout/index.scss | 38 +- legacy/misc/layout/index.tsx | 14 + legacy/misc/layout/variables.scss | 1 + packages/cx/src/util/innerTextTrim.ts | 2 +- 17 files changed, 305 insertions(+), 245 deletions(-) create mode 100644 legacy/fiddle/app/variables.scss diff --git a/legacy/fiddle/app/components/CodeMirror.scss b/legacy/fiddle/app/components/CodeMirror.scss index 8bff45271..99171ea74 100644 --- a/legacy/fiddle/app/components/CodeMirror.scss +++ b/legacy/fiddle/app/components/CodeMirror.scss @@ -9,7 +9,3 @@ box-sizing: border-box; } } - -.cxe-codemirror-input { - @include cxe-field-input($cx-besm, $cx-input-state-style-map); -} diff --git a/legacy/fiddle/app/components/Preview.js b/legacy/fiddle/app/components/Preview.js index 15158b01c..e3d29db63 100644 --- a/legacy/fiddle/app/components/Preview.js +++ b/legacy/fiddle/app/components/Preview.js @@ -4,7 +4,14 @@ import { Store } from "cx/data"; import deepEqual from "deep-equal"; import casualData from "app/components/casual"; -import * as Cx from "cx/index"; +import * as CxUI from "cx/ui"; +import * as CxWidgets from "cx/widgets"; +import * as CxData from "cx/data"; +import * as CxUtil from "cx/util"; +import * as CxSVG from "cx/svg"; +import * as CxCharts from "cx/charts"; + +const Cx = { ui: CxUI, widgets: CxWidgets, data: CxData, util: CxUtil, svg: CxSVG, charts: CxCharts }; export class Preview extends HtmlElement { declareData() { diff --git a/legacy/fiddle/app/components/index.scss b/legacy/fiddle/app/components/index.scss index 77460d11b..bfec8b15d 100644 --- a/legacy/fiddle/app/components/index.scss +++ b/legacy/fiddle/app/components/index.scss @@ -1,4 +1,4 @@ -@import "OpenDialog"; -@import "CodeMirror"; -@import "Preview"; -@import "toolbar"; \ No newline at end of file +@use "OpenDialog" as open-dialog; +@use "CodeMirror" as codemirror; +@use "Preview" as preview; +@use "toolbar" as toolbar; diff --git a/legacy/fiddle/app/core/addImports.js b/legacy/fiddle/app/core/addImports.js index 4219e6125..e2b5a69ff 100644 --- a/legacy/fiddle/app/core/addImports.js +++ b/legacy/fiddle/app/core/addImports.js @@ -1,4 +1,11 @@ -import * as Cx from 'cx'; +import * as CxUI from "cx/ui"; +import * as CxWidgets from "cx/widgets"; +import * as CxData from "cx/data"; +import * as CxUtil from "cx/util"; +import * as CxSVG from "cx/svg"; +import * as CxCharts from "cx/charts"; + +const Cx = { ui: CxUI, widgets: CxWidgets, data: CxData, util: CxUtil, svg: CxSVG, charts: CxCharts }; import { rewriteImports, getImportedNames } from './groupImports'; //let Cx = {}; diff --git a/legacy/fiddle/app/index.html b/legacy/fiddle/app/index.html index b59a05abc..5be71c136 100644 --- a/legacy/fiddle/app/index.html +++ b/legacy/fiddle/app/index.html @@ -1,4 +1,4 @@ - + @@ -21,14 +21,18 @@ rel="stylesheet" type="text/css" /> - <%= htmlWebpackPlugin.options.reactScripts %> - <%= htmlWebpackPlugin.files.webpackManifest %>
<%= htmlWebpackPlugin.options.gtmb %> - - + + diff --git a/legacy/fiddle/app/index.scss b/legacy/fiddle/app/index.scss index 67785e1af..a403af950 100644 --- a/legacy/fiddle/app/index.scss +++ b/legacy/fiddle/app/index.scss @@ -1,4 +1,18 @@ -@use "sass:math"; +// Forward variables first so downstream @use picks them up +@forward "./variables"; + +// Load misc styles +@use "../../misc/layout/index" as misc-layout; +@use "../../misc/components/index" as misc-components; + +// Load theme (use overrides to avoid double-config of variables) +@use "cx-theme-aquamarine/src/overrides.scss" as theme; + +// Load fiddle styles +@use "components/index" as components; +@use "routes/login/index" as login; +@use "routes/default/index" as default-route; +@use "routes/preview/index" as preview; html { height: 100%; @@ -19,24 +33,6 @@ a { text-decoration: none; } -@import "../../misc/layout"; -@import "../../misc/components"; - -$cx-theme-primary-color: $master-theme-color; - -@import "~cx-theme-aquamarine/src/variables.scss"; - -@function cx-divide($a, $b) { - @return math.div($a, $b); -} - -@import "~cx-theme-aquamarine/src/index.scss"; - -@import "components/index"; -@import "routes/login/index"; -@import "routes/default/index"; -@import "routes/preview/index"; - .cxb-submenu { .cxb-menu { min-width: 150px; diff --git a/legacy/fiddle/app/routes/default/Controller.js b/legacy/fiddle/app/routes/default/Controller.js index e15f106c4..f4311b1ff 100644 --- a/legacy/fiddle/app/routes/default/Controller.js +++ b/legacy/fiddle/app/routes/default/Controller.js @@ -6,7 +6,7 @@ import { reformatCode } from "app/core/reformatCode"; import { createFiddle, updateFiddle, deleteFiddle } from "app/api/fiddles"; import { openOpenDialog } from "app/components/OpenDialog"; -import Route from "route-parser"; +import Route from "route-parser-ts"; import { getToken } from "app/api/token"; import { getFiddle } from "app/api/fiddles"; import { getFiddleStar } from "app/api/stars"; diff --git a/legacy/fiddle/app/routes/default/index.scss b/legacy/fiddle/app/routes/default/index.scss index 2eb3b6ca9..2a031215f 100644 --- a/legacy/fiddle/app/routes/default/index.scss +++ b/legacy/fiddle/app/routes/default/index.scss @@ -1,3 +1,5 @@ +@use "../../../../misc/layout/variables" as *; + $header-line-height: 20px; $header-padding: 0px; $toolbar-height: 20px; diff --git a/legacy/fiddle/app/routes/index.js b/legacy/fiddle/app/routes/index.js index 7496297e7..bccf45a69 100644 --- a/legacy/fiddle/app/routes/index.js +++ b/legacy/fiddle/app/routes/index.js @@ -2,32 +2,32 @@ import { Route, HtmlElement, PureContainer, - enableAllInternalDependencies + enableAllInternalDependencies, } from "cx/widgets"; -import {FirstVisibleChildLayout} from "cx/ui"; +import { FirstVisibleChildLayout } from "cx/ui"; import Default from "./default/"; import Preview from "./preview/"; -import {WaitScreen} from "./login/"; -import {PickAuthProviderPage} from "./login/PickAuthProviderPage"; +import { WaitScreen } from "./login/"; +import { PickAuthProviderPage } from "./login/PickAuthProviderPage"; enableAllInternalDependencies(); export const App = ( - + - + - + - + - + - - + + ); diff --git a/legacy/fiddle/app/routes/preview/Controller.js b/legacy/fiddle/app/routes/preview/Controller.js index a1695b85e..a0f9eee8e 100644 --- a/legacy/fiddle/app/routes/preview/Controller.js +++ b/legacy/fiddle/app/routes/preview/Controller.js @@ -6,7 +6,7 @@ import {reformatCode} from 'app/core/reformatCode'; import {createFiddle, updateFiddle, deleteFiddle} from 'app/api/fiddles'; import {openOpenDialog} from 'app/components/OpenDialog'; -import Route from 'route-parser'; +import Route from 'route-parser-ts'; import {getToken} from 'app/api/token'; import {getFiddle} from 'app/api/fiddles'; import {getFiddleStar} from 'app/api/stars'; diff --git a/legacy/fiddle/app/variables.scss b/legacy/fiddle/app/variables.scss new file mode 100644 index 000000000..fcc33596f --- /dev/null +++ b/legacy/fiddle/app/variables.scss @@ -0,0 +1,4 @@ +@forward "../../misc/layout/variables"; +@forward "cx-theme-aquamarine/src/variables" with ( + $cx-theme-primary-color: #4f7aea !default +); diff --git a/legacy/fiddle/webpack.config.js b/legacy/fiddle/webpack.config.js index 16569550c..6bf03af65 100644 --- a/legacy/fiddle/webpack.config.js +++ b/legacy/fiddle/webpack.config.js @@ -1,214 +1,213 @@ const webpack = require("webpack"), - MiniCssExtractPlugin = require("mini-css-extract-plugin"), - HtmlWebpackPlugin = require("html-webpack-plugin"), - CopyWebpackPlugin = require("copy-webpack-plugin"), - { CleanWebpackPlugin } = require("clean-webpack-plugin"), - BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin, - { merge } = require("webpack-merge"), - path = require("path"), - gtm = require("../misc/tracking/gtm.js"), - reactScriptsProd = require("../misc/reactScripts"), - reactScriptsDev = require("../misc/reactScripts.dev"); + MiniCssExtractPlugin = require("mini-css-extract-plugin"), + HtmlWebpackPlugin = require("html-webpack-plugin"), + CopyWebpackPlugin = require("copy-webpack-plugin"), + { CleanWebpackPlugin } = require("clean-webpack-plugin"), + BundleAnalyzerPlugin = + require("webpack-bundle-analyzer").BundleAnalyzerPlugin, + { merge } = require("webpack-merge"), + path = require("path"), + gtm = require("../misc/tracking/gtm.js"), + reactScriptsProd = require("../misc/reactScripts"), + reactScriptsDev = require("../misc/reactScripts.dev"); let root = process.env.npm_lifecycle_event.indexOf(":root") != -1; let production = process.env.npm_lifecycle_event.indexOf("build") == 0; var common = { - mode: production ? "production" : "development", - target: ["web", "es5"], - resolve: { - alias: { - fiddle: __dirname, - app: path.join(__dirname, "app/"), - config: path.join(__dirname, "app/config/dev/"), - path: "path-browserify", - }, - fallback: { - fs: false, - //module: false, - net: false, - util: false, - buffer: false, - "safe-buffer": false, - }, - fullySpecified: false, - }, + mode: production ? "production" : "development", + target: ["web", "es5"], + resolve: { + extensions: [".js", ".tsx", ".ts", ".json"], + alias: { + fiddle: __dirname, + app: path.join(__dirname, "app/"), + config: path.join(__dirname, "app/config/dev/"), + path: "path-browserify", + }, + fallback: { + fs: false, + //module: false, + net: false, + util: false, + buffer: false, + "safe-buffer": false, + }, + fullySpecified: false, + }, - module: { - rules: [ - { - test: /\.(js)$/, - include: [ - path.resolve(__dirname, "./app"), - path.resolve(__dirname, "../misc"), - /node_modules[\\\/](cx|cx-react)[\\\/]/, + module: { + rules: [ + { + test: /\.(js|tsx?)$/, + include: [ + path.resolve(__dirname, "./app"), + path.resolve(__dirname, "../misc"), + /node_modules[\\\/](cx|cx-react)[\\\/]/, + ], + //include: /[\\\/](app|cx-react|prettier|babel|@babel)/, + loader: "babel-loader", + options: { + cacheDirectory: true, + presets: [ + ["@babel/preset-typescript"], + [ + "cx-env", + { + targets: { + chrome: 96, + }, + modules: false, + loose: true, + corejs: 3, + useBuiltIns: "usage", + cx: { + imports: true, + }, + }, ], - //include: /[\\\/](app|cx-react|prettier|babel|@babel)/, - loader: "babel-loader", - options: { - cacheDirectory: true, - presets: [ - [ - "cx-env", - { - targets: { - chrome: 45, - //ie: 11, - firefox: 30, - edge: 12, - safari: 9, - }, - modules: false, - loose: true, - corejs: 3, - useBuiltIns: "usage", - cx: { - imports: true, - }, - }, - ], - ], - plugins: [], - }, - }, - { - test: /\.(png|jpg|svg)/, - loader: "file-loader", - options: { - name: "[name].ltc.[hash].[ext]", - }, - }, - ], - }, - // node: { - // fs: "empty", - // module: "empty", - // net: "empty", - // }, - entry: { - app: __dirname + "/app/index.js", - }, - externals: { - react: "React", - "react-dom": "ReactDOM", - }, - output: { - path: __dirname, - //publicPath: '/', - filename: "[name].js", - }, - plugins: [ - new HtmlWebpackPlugin({ - template: path.join(__dirname, "app/index.html"), - gtmh: gtm.head, - gtmb: gtm.body, - reactScripts: production ? reactScriptsProd : reactScriptsDev, - }), - new webpack.ProvidePlugin({ - process: "process/browser", - Buffer: ["buffer", "Buffer"], - }), - ], - cache: { - // 1. Set cache type to filesystem - type: "filesystem", + ], + plugins: [], + }, + }, + { + test: /\.(png|jpg|svg)/, + loader: "file-loader", + options: { + name: "[name].ltc.[hash].[ext]", + }, + }, + ], + }, + // node: { + // fs: "empty", + // module: "empty", + // net: "empty", + // }, + entry: { + app: __dirname + "/app/index.js", + }, + // externals: { + // react: "React", + // "react-dom": "ReactDOM", + // }, + output: { + path: __dirname, + //publicPath: '/', + filename: "[name].js", + }, + plugins: [ + new HtmlWebpackPlugin({ + template: path.join(__dirname, "app/index.html"), + gtmh: gtm.head, + gtmb: gtm.body, + reactScripts: production ? reactScriptsProd : reactScriptsDev, + }), + new webpack.ProvidePlugin({ + process: "process/browser", + Buffer: ["buffer", "Buffer"], + }), + ], + cache: { + // 1. Set cache type to filesystem + type: "filesystem", - buildDependencies: { - // 2. Add your config as buildDependency to get cache invalidation on config change - config: [__filename], + buildDependencies: { + // 2. Add your config as buildDependency to get cache invalidation on config change + config: [__filename], - // 3. If you have other things the build depends on you can add them here - // Note that webpack, loaders and all modules referenced from your config are automatically added - }, - }, + // 3. If you have other things the build depends on you can add them here + // Note that webpack, loaders and all modules referenced from your config are automatically added + }, + }, }; var specific; if (production) { - specific = { - resolve: { - alias: { - config: path.join(__dirname, "app/config/prod/"), - }, - }, - - module: { - rules: [ - { - test: /\.scss$/, - use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], - }, - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], - }, - ], + specific = { + resolve: { + alias: { + config: path.join(__dirname, "app/config/prod/"), }, + }, - plugins: [ - new webpack.DefinePlugin({ - "process.env.NODE_ENV": JSON.stringify("production"), - }), - new MiniCssExtractPlugin({ - filename: "app.ltc.[chunkhash].css", - chunkFilename: "[id].ltc.[chunkhash].css", - }), - new CopyWebpackPlugin({ - patterns: [ - { - from: path.join(__dirname, "assets"), - to: path.join(__dirname, "dist/assets"), - }, - { - from: path.resolve(__dirname, "./netlify.redirects"), - to: "_redirects", - toType: "file", - }, - { - from: path.resolve(__dirname, "../misc/netlify.headers"), - to: "_headers", - toType: "file", - }, - ], - }), - new CleanWebpackPlugin(), - //new BundleAnalyzerPlugin() + module: { + rules: [ + { + test: /\.scss$/, + use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"], + }, ], + }, - output: { - path: path.join(__dirname, "dist"), - publicPath: "/", - filename: "[name].ltc.[chunkhash].js", - chunkFilename: "[name].ltc.[chunkhash].js", - hashDigestLength: 5, - }, + plugins: [ + new webpack.DefinePlugin({ + "process.env.NODE_ENV": JSON.stringify("production"), + }), + new MiniCssExtractPlugin({ + filename: "app.ltc.[chunkhash].css", + chunkFilename: "[id].ltc.[chunkhash].css", + }), + new CopyWebpackPlugin({ + patterns: [ + { + from: path.join(__dirname, "assets"), + to: path.join(__dirname, "dist/assets"), + }, + { + from: path.resolve(__dirname, "./netlify.redirects"), + to: "_redirects", + toType: "file", + }, + { + from: path.resolve(__dirname, "../misc/netlify.headers"), + to: "_headers", + toType: "file", + }, + ], + }), + new CleanWebpackPlugin(), + //new BundleAnalyzerPlugin() + ], - optimization: { - splitChunks: false, - }, - }; + output: { + path: path.join(__dirname, "dist"), + publicPath: "/", + filename: "[name].ltc.[chunkhash].js", + chunkFilename: "[name].ltc.[chunkhash].js", + hashDigestLength: 5, + }, + + optimization: { + splitChunks: false, + }, + }; } else { - specific = { - module: { - rules: [ - { - test: /\.scss$/, - use: ["style-loader", "css-loader", "sass-loader"], - }, - { - test: /\.css$/, - use: ["style-loader", "css-loader"], - }, - ], - }, - devtool: "eval", - devServer: { - hot: true, - port: 8089, - historyApiFallback: true, - }, - }; + specific = { + module: { + rules: [ + { + test: /\.scss$/, + use: ["style-loader", "css-loader", "sass-loader"], + }, + { + test: /\.css$/, + use: ["style-loader", "css-loader"], + }, + ], + }, + devtool: "eval", + devServer: { + hot: true, + port: 8089, + historyApiFallback: true, + }, + }; } module.exports = merge(common, specific); diff --git a/legacy/misc/components/SideNav.scss b/legacy/misc/components/SideNav.scss index 7a7af2700..0a172f1c9 100644 --- a/legacy/misc/components/SideNav.scss +++ b/legacy/misc/components/SideNav.scss @@ -11,8 +11,8 @@ color: $master-sidenav-link-color; &.sticky { - top: 90px; - height: calc(100vh - 148px); + top: 90px + $master-banner-height; + height: calc(100vh - 148px - $master-banner-height); @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { position: static; @@ -22,7 +22,7 @@ } &.extended { - height: calc(100vh - 90px); + height: calc(100vh - 90px - $master-banner-height); } &.gray { diff --git a/legacy/misc/layout/index.scss b/legacy/misc/layout/index.scss index b7f0d6095..7a69ea561 100644 --- a/legacy/misc/layout/index.scss +++ b/legacy/misc/layout/index.scss @@ -18,6 +18,36 @@ } } +.master_banner { + background: #f0f0f0; + color: #555; + text-align: center; + padding: 4px 16px; + font-size: 12px; + border-bottom: 1px solid #ddd; + + a { + color: #333; + font-weight: 600; + } + + .master_banner_short { + display: none; + } +} + +@media screen and (max-width: $master-desktop-screen-width) { + .master_banner { + .master_banner_full { + display: none; + } + + .master_banner_short { + display: inline; + } + } +} + .master_topbar { font-family: $master-font-family; display: flex; @@ -76,7 +106,7 @@ background: $master-brand-background; color: $master-brand-color; min-height: 105px; - padding-top: $master-header-height; + padding-top: $master-header-height + $master-banner-height; box-shadow: 0 0 5px rgba(black, 0.3); z-index: 1500; position: relative; @@ -150,7 +180,7 @@ .master_sidedrawer { position: fixed; left: -250px; - top: $master-header-height !important; + top: $master-header-height + $master-banner-height !important; bottom: 0; width: 250px; background: white; @@ -201,7 +231,7 @@ flex-direction: row; &.fullheight { - height: calc(100vh - 147px); + height: calc(100vh - 147px - $master-banner-height); } } } @@ -221,7 +251,7 @@ .master_content { &.fullheight { - height: calc(100vh - 120px); + height: calc(100vh - 120px - $master-banner-height); } } diff --git a/legacy/misc/layout/index.tsx b/legacy/misc/layout/index.tsx index 6977603a9..1b4d8ff3f 100644 --- a/legacy/misc/layout/index.tsx +++ b/legacy/misc/layout/index.tsx @@ -43,6 +43,20 @@ export const MasterLayout = createFunctionalComponent(
+
+ + You're viewing the legacy site. Visit{" "} + cxjs.io/docs{" "} + for the latest documentation. + + + Legacy site. Visit{" "} + cxjs.io/docs{" "} + for new docs. + +
Date: Wed, 1 Apr 2026 15:16:31 +0200 Subject: [PATCH 2/2] Complete fiddle --- homedocs/astro.config.mjs | 3 + legacy/fiddle/app/components/CodeMirror.js | 61 +++++++++++---------- legacy/fiddle/app/components/Preview.js | 28 +++++++--- legacy/fiddle/app/components/icons.js | 12 ++-- legacy/fiddle/app/routes/default/index.scss | 2 +- legacy/fiddle/webpack.config.js | 5 +- packages/cx/package.json | 2 +- yarn.lock | 10 ++-- 8 files changed, 71 insertions(+), 52 deletions(-) diff --git a/homedocs/astro.config.mjs b/homedocs/astro.config.mjs index a5bdb0956..00067642e 100644 --- a/homedocs/astro.config.mjs +++ b/homedocs/astro.config.mjs @@ -10,6 +10,9 @@ import llmsTxt from "./src/integrations/llms-txt"; // https://astro.build/config export default defineConfig({ site: "https://cxjs.io", + redirects: { + "/docs": "/docs/intro/what-is-cxjs", + }, integrations: [ cxjs(), react(), diff --git a/legacy/fiddle/app/components/CodeMirror.js b/legacy/fiddle/app/components/CodeMirror.js index d2a1ddff6..dca2994db 100644 --- a/legacy/fiddle/app/components/CodeMirror.js +++ b/legacy/fiddle/app/components/CodeMirror.js @@ -1,5 +1,5 @@ -import { Widget, VDOM, CSS } from 'cx/ui'; -import codemirror from 'codemirror'; +import { Widget, VDOM, CSS } from "cx/ui"; +import codemirror from "codemirror"; import "codemirror/lib/codemirror.css"; import "codemirror/mode/jsx/jsx"; import "codemirror/mode/javascript/javascript"; @@ -7,31 +7,35 @@ import "codemirror/mode/css/css"; import "codemirror/addon/edit/matchtags"; import "codemirror/addon/edit/closetag"; - export class CodeMirror extends Widget { - declareData() { return super.declareData(...arguments, { - code: undefined + code: undefined, }); } render(context, instance, key) { - return + return ; } } -CodeMirror.prototype.baseClass = 'codemirror'; +CodeMirror.prototype.baseClass = "codemirror"; CodeMirror.prototype.styled = true; class Component extends VDOM.Component { render() { - var {data, widget} = this.props.instance; - return
-