Skip to content

Commit

Permalink
MBS-12615: Fix compactEntityJson for other-document data (#2656)
Browse files Browse the repository at this point in the history
`compactEntityJson` is used to minify the relationship editor state
before putting it into sessionStorage during submission.

If you create a new entity from an autocomplete search, the returned
entity object's constructor will be from a different document (the
iframe), so we can't compare it by reference to our `Object`.  To
determine if something is a plain object, we need another way.  The
simplest is to check if the constructor function converted to a string
matches our `Object` converted to a string.
  • Loading branch information
mwiencek committed Sep 22, 2022
1 parent 72a927a commit 258db26
Show file tree
Hide file tree
Showing 4 changed files with 348 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import linkedEntities from '../../common/linkedEntities.mjs';
import bracketed from '../../common/utility/bracketed.js';
import clean from '../../common/utility/clean.js';
import {uniqueId} from '../../common/utility/numbers.js';
import {kebabCase} from '../../common/utility/strings.js';
import useRangeSelectionHandler from '../hooks/useRangeSelectionHandler.js';
import type {
DialogAttributesStateT,
Expand Down Expand Up @@ -396,7 +397,11 @@ const DialogAttributes = (React.memo<PropsT>(({

return (
<div
className={'attribute-container ' + attribute.control}
className={
'attribute-container ' +
attribute.control + ' ' +
kebabCase(attribute.type.name)
}
key={attribute.key}
>
{attributeElement}
Expand Down
51 changes: 32 additions & 19 deletions root/utility/compactEntityJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
* -> [{"1": 2}, "key", "value"]
*/

const functionToString: () => string =
// $FlowIgnore[method-unbinding]
Function.prototype.toString;
const objectCtorString: string = functionToString.call(Object);

function _indexValue(
value: mixed,
indexCache: Map<mixed, number>,
Expand Down Expand Up @@ -54,27 +59,35 @@ function _indexValue(
),
);
}
} else if (value.constructor === Object) {
compactValue = {};
for (const objectKey in value) {
if (hasOwnProp(value, objectKey)) {
const compactObjectKey = _indexValue(
objectKey,
indexCache,
result,
);
const compactObjectValue = _indexValue(
value[objectKey],
indexCache,
result,
);
compactValue[compactObjectKey] = compactObjectValue;
} else {
const prototype = Object.getPrototypeOf(value);
if (
prototype &&
// $FlowIgnore[prop-missing]
typeof prototype.constructor === 'function' &&
functionToString.call(prototype.constructor) === objectCtorString
) {
compactValue = {};
for (const objectKey in value) {
if (hasOwnProp(value, objectKey)) {
const compactObjectKey = _indexValue(
objectKey,
indexCache,
result,
);
const compactObjectValue = _indexValue(
value[objectKey],
indexCache,
result,
);
compactValue[compactObjectKey] = compactObjectValue;
}
}
} else {
throw new Error(
'Only plain objects and arrays can be converted into JSON',
);
}
} else {
throw new Error(
'Only plain objects and arrays can be converted into JSON',
);
}
} else {
compactValue = null;
Expand Down
4 changes: 4 additions & 0 deletions t/selenium.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,10 @@ const seleniumTests = [
name: 'Series_Relationship_Editor.json5',
login: true,
},
{
name: 'Artist_Edit_Form.json5',
login: true,
},
{
name: 'Genre_Edit_Form.json5',
login: true,
Expand Down
Loading

0 comments on commit 258db26

Please sign in to comment.