fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

21
node_modules/rtlcss-webpack-plugin/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Wix.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

52
node_modules/rtlcss-webpack-plugin/README.md generated vendored Normal file
View File

@@ -0,0 +1,52 @@
# RtlCss Webpack Plugin [![Build Status](https://img.shields.io/travis/wix/rtlcss-webpack-plugin/master.svg?style=flat-square)](https://travis-ci.org/wix/rtlcss-webpack-plugin) [![npm version](https://img.shields.io/npm/v/rtlcss-webpack-plugin.svg?style=flat-square)](https://www.npmjs.com/package/rtlcss-webpack-plugin) [![npm downloads](https://img.shields.io/npm/dm/rtlcss-webpack-plugin.svg?style=flat-square)](https://www.npmjs.com/package/rtlcss-webpack-plugin)
Webpack plugin to use in addition to [extract-text-webpack-plugin](https://github.com/webpack/extract-text-webpack-plugin) to create a second css bundle, processed to be rtl.
This uses [rtlcss](https://github.com/MohammadYounes/rtlcss) under the hood, please refer to its documentation for supported properties.
This is almost entirely based on work done in [webpack-rtl-plugin](https://github.com/romainberger/webpack-rtl-plugin)
## Installation
```shell
$ npm install rtlcss-webpack-plugin
```
## Usage
Add the plugin to your webpack configuration:
```js
import RtlCssPlugin from 'rtlcss-webpack-plugin';
module.exports = {
entry: path.join(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader'})
}
]
},
plugins: [new ExtractTextPlugin('style.css'), new RtlCssPlugin('style.rtl.css')]
};
```
This will create the normal `style.css` and an additional `style.rtl.css`.
## Options
```
new RtlCssPlugin('[name].rtl.css');
```
```
new RtlCssPlugin({filename: '[name].rtl.css'});
```
* `filename` Name of the result file. May contain [name], [id] and [hash]

94
node_modules/rtlcss-webpack-plugin/dist/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,94 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _path = _interopRequireDefault(require("path"));
var _rtlcss = _interopRequireDefault(require("rtlcss"));
var _webpack = _interopRequireDefault(require("webpack"));
var isWebpack5 = parseInt(_webpack["default"].version, 10) === 5;
var cssOnly = function cssOnly(filename) {
return _path["default"].extname(filename) === '.css';
};
var RtlCssPlugin = /*#__PURE__*/function () {
function RtlCssPlugin(options) {
var _this = this;
(0, _defineProperty2["default"])(this, "processAssets", function (compilation, callback) {
// webpack 5 turned this from an array to a set
var chunks = isWebpack5 ? Array.from(compilation.chunks) : compilation.chunks; // Explore each chunk (build output):
chunks.forEach(function (chunk) {
// Explore each asset filename generated by the chunk:
// webpack 5 turned this from an array to a set
var files = isWebpack5 ? Array.from(chunk.files) : chunk.files;
files.filter(cssOnly).forEach(function (filename) {
// Get the asset source for each file generated by the chunk:
var src = compilation.assets[filename].source();
var dst = _rtlcss["default"].process(src);
var dstFileName = compilation.getPath(_this.options.filename, {
chunk: chunk,
cssFileName: filename
});
if (isWebpack5) {
compilation.assets[dstFileName] = new _webpack["default"].sources.RawSource(dst);
chunk.files.add(dstFileName);
} else {
compilation.assets[dstFileName] = {
source: function source() {
return dst;
},
size: function size() {
return dst.length;
}
};
chunk.files.push(dstFileName);
}
});
});
callback();
});
if (typeof options === 'string') {
options = {
filename: options
};
}
this.options = options || {
filename: '[name].rtl.css'
};
}
var _proto = RtlCssPlugin.prototype;
_proto.apply = function apply(compiler) {
var _this2 = this;
if (isWebpack5) {
compiler.hooks.compilation.tap('RtlCssPlugin', function (compilation) {
compilation.hooks.processAssets.tapAsync({
name: 'TPAStylePlugin.pluginName',
stage: compilation.PROCESS_ASSETS_STAGE_OPTIMIZE
}, function (chunks, callback) {
return _this2.processAssets(compilation, callback);
});
});
} else {
compiler.hooks.emit.tapAsync('RtlCssPlugin', this.processAssets);
}
};
return RtlCssPlugin;
}();
module.exports = RtlCssPlugin;

73
node_modules/rtlcss-webpack-plugin/dist/test/bundle.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.bundle = bundle;
exports.filePath = filePath;
exports.fixture = fixture;
var _path = _interopRequireDefault(require("path"));
var _webpack = _interopRequireDefault(require("webpack"));
var _memoryFs = _interopRequireDefault(require("memory-fs"));
var _src = _interopRequireDefault(require("../src"));
var _miniCssExtractPlugin = _interopRequireDefault(require("mini-css-extract-plugin"));
/* global wallaby */
var workingFolder = typeof wallaby !== 'undefined' ? _path["default"].join(wallaby.localProjectDir, 'test') : __dirname;
function fixture(fileName) {
return _path["default"].join(workingFolder, 'fixtures', fileName);
}
function bundle(options, modifier) {
if (modifier === void 0) {
modifier = function modifier(x) {
return x;
};
}
return new Promise(function (resolve, reject) {
var compiler = (0, _webpack["default"])(modifier({
entry: {
bundle: fixture('index.js')
},
output: {
filename: '[name].js'
},
resolveLoader: {
modules: [_path["default"].resolve(workingFolder, '..', 'node_modules')]
},
module: {
rules: [{
test: /\.css$/,
use: [{
loader: _miniCssExtractPlugin["default"].loader
}, 'css-loader']
}]
},
plugins: [new _miniCssExtractPlugin["default"]({
filename: '[name].css'
}), new _src["default"](options)]
}));
var memoryFileSystem = new _memoryFs["default"]();
compiler.outputFileSystem = memoryFileSystem;
compiler.run(function (err, stats) {
if (err) {
return reject(err);
} else if (stats.hasErrors()) {
return reject(new Error(stats.toString()));
} else {
resolve(memoryFileSystem);
}
});
});
}
function filePath(name) {
return _path["default"].join(process.cwd(), 'dist', name);
}

View File

@@ -0,0 +1 @@
require('./style.css');

View File

@@ -0,0 +1 @@
require('./style2.css');

View File

@@ -0,0 +1,3 @@
.a {
float: left;
}

View File

@@ -0,0 +1,3 @@
.b {
float: left;
}

View File

@@ -0,0 +1,196 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _chai = require("chai");
var _webpack = require("webpack");
var _bundle = require("./bundle");
var _path = require("path");
describe('RtlCss Webpack Plugin', function () {
it('should contain the correct content', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
var fs;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _bundle.bundle)();
case 2:
fs = _context.sent;
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle.css'), 'utf-8')).to.equal('.a {\n float: left;\n}\n\n');
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle.rtl.css'), 'utf-8')).to.equal('.a {\n float: right;\n}\n\n');
case 5:
case "end":
return _context.stop();
}
}
}, _callee);
})));
it('should create bundle per chunk', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
var addChunk, fs;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
addChunk = function addChunk(x) {
return (0, _extends2["default"])({}, x, {
entry: (0, _extends2["default"])({}, x.entry, {
bundle2: (0, _bundle.fixture)('index2.js')
})
});
};
_context2.next = 3;
return (0, _bundle.bundle)(undefined, addChunk);
case 3:
fs = _context2.sent;
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle.rtl.css'), 'utf-8')).to.equal('.a {\n float: right;\n}\n\n');
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle2.rtl.css'), 'utf-8')).to.equal('.b {\n float: right;\n}\n\n');
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
})));
it('should contain the correct content when minimized', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
var minimize, fs;
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
minimize = function minimize(x) {
return (0, _extends2["default"])({}, x, {
plugins: x.plugins.concat(new _webpack.LoaderOptionsPlugin({
minimize: true
}))
});
};
_context3.next = 3;
return (0, _bundle.bundle)(undefined, minimize);
case 3:
fs = _context3.sent;
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle.css'), 'utf-8')).to.equal('.a {\n float: left;\n}\n\n');
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle.rtl.css'), 'utf-8')).to.equal('.a {\n float: right;\n}\n\n');
case 6:
case "end":
return _context3.stop();
}
}
}, _callee3);
})));
it('should set filename according to options as object', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() {
var fs;
return _regenerator["default"].wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return (0, _bundle.bundle)({
filename: 'foo.rtl.css'
});
case 2:
fs = _context4.sent;
// eslint-disable-next-line no-unused-expressions
(0, _chai.expect)(fs.existsSync((0, _bundle.filePath)('foo.rtl.css'))).to.be["true"];
case 4:
case "end":
return _context4.stop();
}
}
}, _callee4);
})));
it('should set filename according to options as string', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5() {
var fs;
return _regenerator["default"].wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_context5.next = 2;
return (0, _bundle.bundle)('foo.rtl.css');
case 2:
fs = _context5.sent;
// eslint-disable-next-line no-unused-expressions
(0, _chai.expect)(fs.existsSync((0, _bundle.filePath)('foo.rtl.css'))).to.be["true"];
case 4:
case "end":
return _context5.stop();
}
}
}, _callee5);
})));
it('should support [hash]', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6() {
var fs, hashedFileName;
return _regenerator["default"].wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
_context6.next = 2;
return (0, _bundle.bundle)('foo.[hash].rtl.css');
case 2:
fs = _context6.sent;
hashedFileName = fs.readdirSync((0, _path.join)(process.cwd(), 'dist')).find(function (s) {
return s.startsWith('foo');
});
(0, _chai.expect)(hashedFileName).not.to.equal('foo.[hash].rtl.css');
(0, _chai.expect)(hashedFileName).to.match(/foo\.\w+\.rtl\.css/);
case 6:
case "end":
return _context6.stop();
}
}
}, _callee6);
})));
it('should support [name]', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7() {
var addChunk, fs;
return _regenerator["default"].wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
addChunk = function addChunk(x) {
return (0, _extends2["default"])({}, x, {
entry: (0, _extends2["default"])({}, x.entry, {
bundle2: (0, _bundle.fixture)('index2.js')
})
});
};
_context7.next = 3;
return (0, _bundle.bundle)('[name]-rtl.css', addChunk);
case 3:
fs = _context7.sent;
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle-rtl.css'), 'utf-8')).to.equal('.a {\n float: right;\n}\n\n');
(0, _chai.expect)(fs.readFileSync((0, _bundle.filePath)('bundle2-rtl.css'), 'utf-8')).to.equal('.b {\n float: right;\n}\n\n');
case 6:
case "end":
return _context7.stop();
}
}
}, _callee7);
})));
});

1
node_modules/rtlcss-webpack-plugin/package.json generated vendored Normal file
View File

@@ -0,0 +1 @@
{"name":"rtlcss-webpack-plugin","version":"4.0.7","license":"MIT","private":false,"author":{"name":"Shahar Talmi","email":"shahar@wix.com"},"main":"dist/src/index.js","files":["dist"],"publishConfig":{"registry":"https://registry.npmjs.org/"},"repository":{"type":"git","url":"https://github.com/wix/rtlcss-webpack-plugin","directory":"."},"scripts":{"start":"yoshi start","precommit":"yoshi lint","pretest":"yoshi build","test":"yoshi test --mocha","posttest":"yoshi lint","release":"yoshi release"},"devDependencies":{"babel-plugin-transform-runtime":"~6.23.0","chai":"~4.1.0","css-loader":"^1.0.0","husky":"~0.14.0","memory-fs":"^0.4.1","mini-css-extract-plugin":"^0.4.2","webpack":"^4.17.1","@wix/yoshi":"^5"},"dependencies":{"babel-runtime":"~6.25.0","rtlcss":"^3.5.0"},"babel":{"presets":["yoshi"]},"eslintConfig":{"extends":"@wix/eslint-config-yoshi"},"gitHead":"6d73d89250f10e13e16f353cadaf1469771aeea2"}