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

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createNewPost = void 0;
/**
* Creates new post.
*
* @param this
* @param options Options to create new post.
*/
async function createNewPost(options = {}) {
const query = new URLSearchParams();
const { postType, title, content, excerpt } = options;
if (postType) {
query.set('post_type', postType);
}
if (title) {
query.set('post_title', title);
}
if (content) {
query.set('content', content);
}
if (excerpt) {
query.set('excerpt', excerpt);
}
await this.visitAdminPage('post-new.php', query.toString());
await this.editor.setPreferences('core/edit-post', {
welcomeGuide: options.showWelcomeGuide ?? false,
fullscreenMode: false,
});
}
exports.createNewPost = createNewPost;
//# sourceMappingURL=create-new-post.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"create-new-post.js","sourceRoot":"","sources":["../../src/admin/create-new-post.ts"],"names":[],"mappings":";;;AAaA;;;;;GAKG;AACI,KAAK,UAAU,aAAa,CAElC,UAA0B,EAAE;IAE5B,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IACpC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAEtD,IAAK,QAAQ,EAAG,CAAC;QAChB,KAAK,CAAC,GAAG,CAAE,WAAW,EAAE,QAAQ,CAAE,CAAC;IACpC,CAAC;IACD,IAAK,KAAK,EAAG,CAAC;QACb,KAAK,CAAC,GAAG,CAAE,YAAY,EAAE,KAAK,CAAE,CAAC;IAClC,CAAC;IACD,IAAK,OAAO,EAAG,CAAC;QACf,KAAK,CAAC,GAAG,CAAE,SAAS,EAAE,OAAO,CAAE,CAAC;IACjC,CAAC;IACD,IAAK,OAAO,EAAG,CAAC;QACf,KAAK,CAAC,GAAG,CAAE,SAAS,EAAE,OAAO,CAAE,CAAC;IACjC,CAAC;IAED,MAAM,IAAI,CAAC,cAAc,CAAE,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAE,CAAC;IAE9D,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAE,gBAAgB,EAAE;QACnD,YAAY,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;QAC/C,cAAc,EAAE,KAAK;KACrB,CAAE,CAAC;AACL,CAAC;AA1BD,sCA0BC"}

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.editPost = void 0;
/**
* Open the post with given ID in the editor.
*
* @param this
* @param postId Post ID to visit.
*/
async function editPost(postId) {
const query = new URLSearchParams();
query.set('post', String(postId));
query.set('action', 'edit');
await this.visitAdminPage('post.php', query.toString());
await this.editor.setPreferences('core/edit-post', {
welcomeGuide: false,
fullscreenMode: false,
});
}
exports.editPost = editPost;
//# sourceMappingURL=edit-post.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"edit-post.js","sourceRoot":"","sources":["../../src/admin/edit-post.ts"],"names":[],"mappings":";;;AAKA;;;;;GAKG;AACI,KAAK,UAAU,QAAQ,CAAe,MAAuB;IACnE,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IAEpC,KAAK,CAAC,GAAG,CAAE,MAAM,EAAE,MAAM,CAAE,MAAM,CAAE,CAAE,CAAC;IACtC,KAAK,CAAC,GAAG,CAAE,QAAQ,EAAE,MAAM,CAAE,CAAC;IAE9B,MAAM,IAAI,CAAC,cAAc,CAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAE,CAAC;IAE1D,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAE,gBAAgB,EAAE;QACnD,YAAY,EAAE,KAAK;QACnB,cAAc,EAAE,KAAK;KACrB,CAAE,CAAC;AACL,CAAC;AAZD,4BAYC"}

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPageError = void 0;
/**
* Regular expression matching a displayed PHP error within a markup string.
*
* @see https://github.com/php/php-src/blob/598175e/main/main.c#L1257-L1297
*/
const REGEXP_PHP_ERROR = /(<b>)?(Fatal error|Recoverable fatal error|Warning|Parse error|Notice|Strict Standards|Deprecated|Unknown error)(<\/b>)?: (.*?) in (.*?) on line (<b>)?\d+(<\/b>)?/;
/**
* Returns a promise resolving to one of either a string or null. A string will
* be resolved if an error message is present in the contents of the page. If no
* error is present, a null value will be resolved instead. This requires the
* environment be configured to display errors.
*
* @see http://php.net/manual/en/function.error-reporting.php
*
* @param this
* @return Promise resolving to a string or null, depending whether a page error is present.
*/
async function getPageError() {
const content = await this.page.content();
const match = content.match(REGEXP_PHP_ERROR);
return match ? match[0] : null;
}
exports.getPageError = getPageError;
//# sourceMappingURL=get-page-error.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"get-page-error.js","sourceRoot":"","sources":["../../src/admin/get-page-error.ts"],"names":[],"mappings":";;;AAKA;;;;GAIG;AACH,MAAM,gBAAgB,GACrB,oKAAoK,CAAC;AAEtK;;;;;;;;;;GAUG;AACI,KAAK,UAAU,YAAY;IACjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAE,gBAAgB,CAAE,CAAC;IAChD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAE,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAJD,oCAIC"}

View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Admin = void 0;
/**
* Internal dependencies
*/
const create_new_post_1 = require("./create-new-post");
const get_page_error_1 = require("./get-page-error");
const visit_admin_page_1 = require("./visit-admin-page");
const edit_post_1 = require("./edit-post");
const visit_site_editor_1 = require("./visit-site-editor");
class Admin {
page;
context;
browser;
pageUtils;
editor;
constructor({ page, pageUtils, editor }) {
this.page = page;
this.context = page.context();
this.browser = this.context.browser();
this.pageUtils = pageUtils;
this.editor = editor;
}
/** @borrows createNewPost as this.createNewPost */
createNewPost = create_new_post_1.createNewPost.bind(this);
/** @borrows editPost as this.editPost */
editPost = edit_post_1.editPost.bind(this);
/** @borrows getPageError as this.getPageError */
getPageError = get_page_error_1.getPageError.bind(this);
/** @borrows visitAdminPage as this.visitAdminPage */
visitAdminPage = visit_admin_page_1.visitAdminPage.bind(this);
/** @borrows visitSiteEditor as this.visitSiteEditor */
visitSiteEditor = visit_site_editor_1.visitSiteEditor.bind(this);
}
exports.Admin = Admin;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":";;;AAKA;;GAEG;AACH,uDAAkD;AAClD,qDAAgD;AAChD,yDAAoD;AACpD,2CAAuC;AACvC,2DAAsD;AAUtD,MAAa,KAAK;IACjB,IAAI,CAAO;IACX,OAAO,CAAiB;IACxB,OAAO,CAAU;IACjB,SAAS,CAAY;IACrB,MAAM,CAAS;IAEf,YAAa,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAyB;QAC9D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAG,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,mDAAmD;IACnD,aAAa,GAAyB,+BAAa,CAAC,IAAI,CAAE,IAAI,CAAE,CAAC;IACjE,yCAAyC;IACzC,QAAQ,GAAoB,oBAAQ,CAAC,IAAI,CAAE,IAAI,CAAE,CAAC;IAClD,iDAAiD;IACjD,YAAY,GAAwB,6BAAY,CAAC,IAAI,CAAE,IAAI,CAAE,CAAC;IAC9D,qDAAqD;IACrD,cAAc,GAA0B,iCAAc,CAAC,IAAI,CAAE,IAAI,CAAE,CAAC;IACpE,uDAAuD;IACvD,eAAe,GAA2B,mCAAe,CAAC,IAAI,CAAE,IAAI,CAAE,CAAC;CACvE;AAzBD,sBAyBC"}

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.visitAdminPage = void 0;
/**
* External dependencies
*/
const path_1 = require("path");
/**
* Visits admin page and handle errors.
*
* @param this
* @param adminPath String to be serialized as pathname.
* @param query String to be serialized as query portion of URL.
*/
async function visitAdminPage(adminPath, query) {
await this.page.goto((0, path_1.join)('wp-admin', adminPath) + (query ? `?${query}` : ''));
// Handle upgrade required screen
if (this.pageUtils.isCurrentURL('wp-admin/upgrade.php')) {
// Click update
await this.page.click('.button.button-large.button-primary');
// Click continue
await this.page.click('.button.button-large');
}
if (this.pageUtils.isCurrentURL('wp-login.php')) {
throw new Error('Not logged in');
}
const error = await this.getPageError();
if (error) {
throw new Error('Unexpected error in page content: ' + error);
}
}
exports.visitAdminPage = visitAdminPage;
//# sourceMappingURL=visit-admin-page.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"visit-admin-page.js","sourceRoot":"","sources":["../../src/admin/visit-admin-page.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,+BAA4B;AAO5B;;;;;;GAMG;AACI,KAAK,UAAU,cAAc,CAEnC,SAAiB,EACjB,KAAc;IAEd,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAA,WAAI,EAAE,UAAU,EAAE,SAAS,CAAE,GAAG,CAAE,KAAK,CAAC,CAAC,CAAC,IAAK,KAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAE,CAC9D,CAAC;IAEF,iCAAiC;IACjC,IAAK,IAAI,CAAC,SAAS,CAAC,YAAY,CAAE,sBAAsB,CAAE,EAAG,CAAC;QAC7D,eAAe;QACf,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAE,qCAAqC,CAAE,CAAC;QAC/D,iBAAiB;QACjB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAE,sBAAsB,CAAE,CAAC;IACjD,CAAC;IAED,IAAK,IAAI,CAAC,SAAS,CAAC,YAAY,CAAE,cAAc,CAAE,EAAG,CAAC;QACrD,MAAM,IAAI,KAAK,CAAE,eAAe,CAAE,CAAC;IACpC,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IACxC,IAAK,KAAK,EAAG,CAAC;QACb,MAAM,IAAI,KAAK,CAAE,oCAAoC,GAAG,KAAK,CAAE,CAAC;IACjE,CAAC;AACF,CAAC;AAzBD,wCAyBC"}

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.visitSiteEditor = void 0;
/**
* Visits the Site Editor main page.
*
* @param this
* @param options Options to visit the site editor.
*/
async function visitSiteEditor(options = {}) {
const { postId, postType, path, canvas } = options;
const query = new URLSearchParams();
if (postId) {
query.set('postId', String(postId));
}
if (postType) {
query.set('postType', postType);
}
if (path) {
query.set('path', path);
}
if (canvas) {
query.set('canvas', canvas);
}
const canvasLoader = this.page.locator(
// Spinner was used instead of the progress bar in an earlier version of
// the site editor.
'.edit-site-canvas-loader, .edit-site-canvas-spinner');
await this.visitAdminPage('site-editor.php', query.toString());
// Try waiting for the canvas loader to appear first, so that the locator
// that waits for it to disappear doesn't resolve prematurely.
await canvasLoader.waitFor().catch(() => { });
/**
* @todo This is a workaround for the fact that the editor canvas is seen as
* ready and visible before the loading spinner is hidden. Ideally, the
* content underneath the loading overlay should be marked inert until the
* loading is done.
*/
await canvasLoader.waitFor({
state: 'hidden',
// Bigger timeout is needed for larger entities, like the Large Post
// HTML fixture that we load for performance tests, which often doesn't
// make it under the default timeout value.
timeout: 60_000,
});
if (!options.showWelcomeGuide) {
await this.editor.setPreferences('core/edit-site', {
welcomeGuide: false,
welcomeGuideStyles: false,
welcomeGuidePage: false,
welcomeGuideTemplate: false,
});
}
}
exports.visitSiteEditor = visitSiteEditor;
//# sourceMappingURL=visit-site-editor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"visit-site-editor.js","sourceRoot":"","sources":["../../src/admin/visit-site-editor.ts"],"names":[],"mappings":";;;AAaA;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CAEpC,UAA6B,EAAE;IAE/B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IAEpC,IAAK,MAAM,EAAG,CAAC;QACd,KAAK,CAAC,GAAG,CAAE,QAAQ,EAAE,MAAM,CAAE,MAAM,CAAE,CAAE,CAAC;IACzC,CAAC;IACD,IAAK,QAAQ,EAAG,CAAC;QAChB,KAAK,CAAC,GAAG,CAAE,UAAU,EAAE,QAAQ,CAAE,CAAC;IACnC,CAAC;IACD,IAAK,IAAI,EAAG,CAAC;QACZ,KAAK,CAAC,GAAG,CAAE,MAAM,EAAE,IAAI,CAAE,CAAC;IAC3B,CAAC;IACD,IAAK,MAAM,EAAG,CAAC;QACd,KAAK,CAAC,GAAG,CAAE,QAAQ,EAAE,MAAM,CAAE,CAAC;IAC/B,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO;IACrC,wEAAwE;IACxE,mBAAmB;IACnB,qDAAqD,CACrD,CAAC;IAEF,MAAM,IAAI,CAAC,cAAc,CAAE,iBAAiB,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAE,CAAC;IAEjE,yEAAyE;IACzE,8DAA8D;IAC9D,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC,KAAK,CAAE,GAAG,EAAE,GAAE,CAAC,CAAE,CAAC;IAE/C;;;;;OAKG;IACH,MAAM,YAAY,CAAC,OAAO,CAAE;QAC3B,KAAK,EAAE,QAAQ;QACf,oEAAoE;QACpE,uEAAuE;QACvE,2CAA2C;QAC3C,OAAO,EAAE,MAAM;KACf,CAAE,CAAC;IAEJ,IAAK,CAAE,OAAO,CAAC,gBAAgB,EAAG,CAAC;QAClC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAE,gBAAgB,EAAE;YACnD,YAAY,EAAE,KAAK;YACnB,kBAAkB,EAAE,KAAK;YACzB,gBAAgB,EAAE,KAAK;YACvB,oBAAoB,EAAE,KAAK;SAC3B,CAAE,CAAC;IACL,CAAC;AACF,CAAC;AAtDD,0CAsDC"}