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,212 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createPersistenceInterface = createPersistenceInterface;
exports.withLazySameState = exports.default = void 0;
var _isPlainObject = require("is-plain-object");
var _deepmerge = _interopRequireDefault(require("deepmerge"));
var _default2 = _interopRequireDefault(require("./storage/default"));
var _ = require("../../");
/**
* External dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('../../registry').WPDataRegistry} WPDataRegistry */
/** @typedef {import('../../registry').WPDataPlugin} WPDataPlugin */
/**
* @typedef {Object} WPDataPersistencePluginOptions Persistence plugin options.
*
* @property {Storage} storage Persistent storage implementation. This must
* at least implement `getItem` and `setItem` of
* the Web Storage API.
* @property {string} storageKey Key on which to set in persistent storage.
*/
/**
* Default plugin storage.
*
* @type {Storage}
*/
const DEFAULT_STORAGE = _default2.default;
/**
* Default plugin storage key.
*
* @type {string}
*/
const DEFAULT_STORAGE_KEY = 'WP_DATA';
/**
* Higher-order reducer which invokes the original reducer only if state is
* inequal from that of the action's `nextState` property, otherwise returning
* the original state reference.
*
* @param {Function} reducer Original reducer.
*
* @return {Function} Enhanced reducer.
*/
const withLazySameState = reducer => (state, action) => {
if (action.nextState === state) {
return state;
}
return reducer(state, action);
};
/**
* Creates a persistence interface, exposing getter and setter methods (`get`
* and `set` respectively).
*
* @param {WPDataPersistencePluginOptions} options Plugin options.
*
* @return {Object} Persistence interface.
*/
exports.withLazySameState = withLazySameState;
function createPersistenceInterface(options) {
const {
storage = DEFAULT_STORAGE,
storageKey = DEFAULT_STORAGE_KEY
} = options;
let data;
/**
* Returns the persisted data as an object, defaulting to an empty object.
*
* @return {Object} Persisted data.
*/
function getData() {
if (data === undefined) {
// If unset, getItem is expected to return null. Fall back to
// empty object.
const persisted = storage.getItem(storageKey);
if (persisted === null) {
data = {};
} else {
try {
data = JSON.parse(persisted);
} catch (error) {
// Similarly, should any error be thrown during parse of
// the string (malformed JSON), fall back to empty object.
data = {};
}
}
}
return data;
}
/**
* Merges an updated reducer state into the persisted data.
*
* @param {string} key Key to update.
* @param {*} value Updated value.
*/
function setData(key, value) {
data = {
...data,
[key]: value
};
storage.setItem(storageKey, JSON.stringify(data));
}
return {
get: getData,
set: setData
};
}
/**
* Data plugin to persist store state into a single storage key.
*
* @param {WPDataRegistry} registry Data registry.
* @param {?WPDataPersistencePluginOptions} pluginOptions Plugin options.
*
* @return {WPDataPlugin} Data plugin.
*/
function persistencePlugin(registry, pluginOptions) {
const persistence = createPersistenceInterface(pluginOptions);
/**
* Creates an enhanced store dispatch function, triggering the state of the
* given store name to be persisted when changed.
*
* @param {Function} getState Function which returns current state.
* @param {string} storeName Store name.
* @param {?Array<string>} keys Optional subset of keys to save.
*
* @return {Function} Enhanced dispatch function.
*/
function createPersistOnChange(getState, storeName, keys) {
let getPersistedState;
if (Array.isArray(keys)) {
// Given keys, the persisted state should by produced as an object
// of the subset of keys. This implementation uses combineReducers
// to leverage its behavior of returning the same object when none
// of the property values changes. This allows a strict reference
// equality to bypass a persistence set on an unchanging state.
const reducers = keys.reduce((accumulator, key) => Object.assign(accumulator, {
[key]: (state, action) => action.nextState[key]
}), {});
getPersistedState = withLazySameState((0, _.combineReducers)(reducers));
} else {
getPersistedState = (state, action) => action.nextState;
}
let lastState = getPersistedState(undefined, {
nextState: getState()
});
return () => {
const state = getPersistedState(lastState, {
nextState: getState()
});
if (state !== lastState) {
persistence.set(storeName, state);
lastState = state;
}
};
}
return {
registerStore(storeName, options) {
if (!options.persist) {
return registry.registerStore(storeName, options);
}
// Load from persistence to use as initial state.
const persistedState = persistence.get()[storeName];
if (persistedState !== undefined) {
let initialState = options.reducer(options.initialState, {
type: '@@WP/PERSISTENCE_RESTORE'
});
if ((0, _isPlainObject.isPlainObject)(initialState) && (0, _isPlainObject.isPlainObject)(persistedState)) {
// If state is an object, ensure that:
// - Other keys are left intact when persisting only a
// subset of keys.
// - New keys in what would otherwise be used as initial
// state are deeply merged as base for persisted value.
initialState = (0, _deepmerge.default)(initialState, persistedState, {
isMergeableObject: _isPlainObject.isPlainObject
});
} else {
// If there is a mismatch in object-likeness of default
// initial or persisted state, defer to persisted value.
initialState = persistedState;
}
options = {
...options,
initialState
};
}
const store = registry.registerStore(storeName, options);
store.subscribe(createPersistOnChange(store.getState, storeName, options.persist));
return store;
}
};
}
persistencePlugin.__unstableMigrate = () => {};
var _default = exports.default = persistencePlugin;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _object = _interopRequireDefault(require("./object"));
/**
* Internal dependencies
*/
let storage;
try {
// Private Browsing in Safari 10 and earlier will throw an error when
// attempting to set into localStorage. The test here is intentional in
// causing a thrown error as condition for using fallback object storage.
storage = window.localStorage;
storage.setItem('__wpDataTestLocalStorage', '');
storage.removeItem('__wpDataTestLocalStorage');
} catch (error) {
storage = _object.default;
}
var _default = exports.default = storage;
//# sourceMappingURL=default.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_object","_interopRequireDefault","require","storage","window","localStorage","setItem","removeItem","error","objectStorage","_default","exports","default"],"sources":["@wordpress/data/src/plugins/persistence/storage/default.js"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport objectStorage from './object';\n\nlet storage;\n\ntry {\n\t// Private Browsing in Safari 10 and earlier will throw an error when\n\t// attempting to set into localStorage. The test here is intentional in\n\t// causing a thrown error as condition for using fallback object storage.\n\tstorage = window.localStorage;\n\tstorage.setItem( '__wpDataTestLocalStorage', '' );\n\tstorage.removeItem( '__wpDataTestLocalStorage' );\n} catch ( error ) {\n\tstorage = objectStorage;\n}\n\nexport default storage;\n"],"mappings":";;;;;;;AAGA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AAHA;AACA;AACA;;AAGA,IAAIC,OAAO;AAEX,IAAI;EACH;EACA;EACA;EACAA,OAAO,GAAGC,MAAM,CAACC,YAAY;EAC7BF,OAAO,CAACG,OAAO,CAAE,0BAA0B,EAAE,EAAG,CAAC;EACjDH,OAAO,CAACI,UAAU,CAAE,0BAA2B,CAAC;AACjD,CAAC,CAAC,OAAQC,KAAK,EAAG;EACjBL,OAAO,GAAGM,eAAa;AACxB;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEcT,OAAO","ignoreList":[]}

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
let objectStorage;
const storage = {
getItem(key) {
if (!objectStorage || !objectStorage[key]) {
return null;
}
return objectStorage[key];
},
setItem(key, value) {
if (!objectStorage) {
storage.clear();
}
objectStorage[key] = String(value);
},
clear() {
objectStorage = Object.create(null);
}
};
var _default = exports.default = storage;
//# sourceMappingURL=object.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["objectStorage","storage","getItem","key","setItem","value","clear","String","Object","create","_default","exports","default"],"sources":["@wordpress/data/src/plugins/persistence/storage/object.js"],"sourcesContent":["let objectStorage;\n\nconst storage = {\n\tgetItem( key ) {\n\t\tif ( ! objectStorage || ! objectStorage[ key ] ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn objectStorage[ key ];\n\t},\n\tsetItem( key, value ) {\n\t\tif ( ! objectStorage ) {\n\t\t\tstorage.clear();\n\t\t}\n\n\t\tobjectStorage[ key ] = String( value );\n\t},\n\tclear() {\n\t\tobjectStorage = Object.create( null );\n\t},\n};\n\nexport default storage;\n"],"mappings":";;;;;;AAAA,IAAIA,aAAa;AAEjB,MAAMC,OAAO,GAAG;EACfC,OAAOA,CAAEC,GAAG,EAAG;IACd,IAAK,CAAEH,aAAa,IAAI,CAAEA,aAAa,CAAEG,GAAG,CAAE,EAAG;MAChD,OAAO,IAAI;IACZ;IAEA,OAAOH,aAAa,CAAEG,GAAG,CAAE;EAC5B,CAAC;EACDC,OAAOA,CAAED,GAAG,EAAEE,KAAK,EAAG;IACrB,IAAK,CAAEL,aAAa,EAAG;MACtBC,OAAO,CAACK,KAAK,CAAC,CAAC;IAChB;IAEAN,aAAa,CAAEG,GAAG,CAAE,GAAGI,MAAM,CAAEF,KAAM,CAAC;EACvC,CAAC;EACDC,KAAKA,CAAA,EAAG;IACPN,aAAa,GAAGQ,MAAM,CAACC,MAAM,CAAE,IAAK,CAAC;EACtC;AACD,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEaX,OAAO","ignoreList":[]}