mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-22 20:45:55 +08:00
Stop aggressively using the reviver option on JSON.parse, part 1
This commit is contained in:
parent
bad1e27c2f
commit
e529197701
8 changed files with 30 additions and 44 deletions
|
@ -11,7 +11,7 @@ function safeDecode(str) {
|
|||
function _runOnImageNode(node) {
|
||||
if (node.src && node.dataset.nylasFile) {
|
||||
node.addEventListener('error', () => {
|
||||
const file = JSON.parse(safeDecode(node.dataset.nylasFile), Utils.registeredObjectReviver);
|
||||
const file = Utils.convertToModel(JSON.parse(safeDecode(node.dataset.nylasFile)));
|
||||
const initialDisplay = node.style.display;
|
||||
const downloadButton = document.createElement('a');
|
||||
downloadButton.classList.add('inline-download-prompt')
|
||||
|
@ -28,7 +28,7 @@ function _runOnImageNode(node) {
|
|||
});
|
||||
|
||||
node.addEventListener('load', () => {
|
||||
const file = JSON.parse(safeDecode(node.dataset.nylasFile), Utils.registeredObjectReviver);
|
||||
const file = Utils.convertToModel(JSON.parse(safeDecode(node.dataset.nylasFile)));
|
||||
node.addEventListener('dblclick', () => {
|
||||
Actions.fetchAndOpenFile(file);
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ function _runOnImageNode(node) {
|
|||
}
|
||||
|
||||
export function encodedAttributeForFile(file) {
|
||||
return safeEncode(JSON.stringify(file, Utils.registeredObjectReplacer));
|
||||
return safeEncode(JSON.stringify(file));
|
||||
}
|
||||
|
||||
export function addInlineImageListeners(doc) {
|
||||
|
|
|
@ -18,7 +18,7 @@ class Bar extends Foo
|
|||
|
||||
describe 'Utils', ->
|
||||
|
||||
describe "registeredObjectReviver / registeredObjectReplacer", ->
|
||||
describe "modelTypesReviver", ->
|
||||
beforeEach ->
|
||||
@testThread = new Thread
|
||||
id: 'local-1'
|
||||
|
@ -33,18 +33,18 @@ describe 'Utils', ->
|
|||
it "should serialize and de-serialize models correctly", ->
|
||||
expectedString = '[{"client_id":"local-1","account_id":"1","metadata":[],"subject":"Test 1234","participants":[{"client_id":"local-a","account_id":"1","name":"Juan","email":"juan@nylas.com","thirdPartyData":{},"is_search_indexed":false,"id":"local-a"},{"client_id":"local-b","account_id":"1","name":"Ben","email":"ben@nylas.com","thirdPartyData":{},"is_search_indexed":false,"id":"local-b"}],"in_all_mail":true,"is_search_indexed":false,"id":"local-1","__cls":"Thread"}]'
|
||||
|
||||
jsonString = JSON.stringify([@testThread], Utils.registeredObjectReplacer)
|
||||
jsonString = JSON.stringify([@testThread])
|
||||
expect(jsonString).toEqual(expectedString)
|
||||
revived = JSON.parse(jsonString, Utils.registeredObjectReviver)
|
||||
revived = JSON.parse(jsonString, Utils.modelTypesReviver)
|
||||
expect(revived).toEqual([@testThread])
|
||||
|
||||
it "should re-inflate Models in places they're not explicitly declared types", ->
|
||||
b = new JSONBlob({id: "ThreadsToProcess", json: [@testThread]})
|
||||
jsonString = JSON.stringify(b, Utils.registeredObjectReplacer)
|
||||
jsonString = JSON.stringify(b)
|
||||
expectedString = '{"client_id":"ThreadsToProcess","server_id":"ThreadsToProcess","json":[{"client_id":"local-1","account_id":"1","metadata":[],"subject":"Test 1234","participants":[{"client_id":"local-a","account_id":"1","name":"Juan","email":"juan@nylas.com","thirdPartyData":{},"is_search_indexed":false,"id":"local-a"},{"client_id":"local-b","account_id":"1","name":"Ben","email":"ben@nylas.com","thirdPartyData":{},"is_search_indexed":false,"id":"local-b"}],"in_all_mail":true,"is_search_indexed":false,"id":"local-1","__cls":"Thread"}],"id":"ThreadsToProcess","__cls":"JSONBlob"}'
|
||||
|
||||
expect(jsonString).toEqual(expectedString)
|
||||
revived = JSON.parse(jsonString, Utils.registeredObjectReviver)
|
||||
revived = JSON.parse(jsonString, Utils.modelTypesReviver)
|
||||
expect(revived).toEqual(b)
|
||||
expect(revived.json[0] instanceof Thread).toBe(true)
|
||||
expect(revived.json[0].participants[0] instanceof Contact).toBe(true)
|
||||
|
|
|
@ -430,7 +430,7 @@ export default class TokenizingTextField extends React.Component {
|
|||
let items = null;
|
||||
|
||||
try {
|
||||
items = JSON.parse(json, Utils.registeredObjectReviver);
|
||||
items = JSON.parse(json).map(Utils.convertToModel);
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
items = null;
|
||||
|
@ -663,7 +663,7 @@ export default class TokenizingTextField extends React.Component {
|
|||
if (tokens.length === 0) {
|
||||
tokens = [token];
|
||||
}
|
||||
const json = JSON.stringify(tokens, Utils.registeredObjectReplacer);
|
||||
const json = JSON.stringify(tokens);
|
||||
event.dataTransfer.setData('nylas-token-items', json);
|
||||
event.dataTransfer.setData('text/plain', tokens.map(t => t.toString()).join(', '));
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
|
@ -755,7 +755,7 @@ export default class TokenizingTextField extends React.Component {
|
|||
_onAttachToClipboard = (event) => {
|
||||
const text = this.state.selectedKeys.join(', ')
|
||||
if (event.clipboardData) {
|
||||
const json = JSON.stringify(this._selectedTokens(), Utils.registeredObjectReplacer);
|
||||
const json = JSON.stringify(this._selectedTokens());
|
||||
event.clipboardData.setData('text/plain', text);
|
||||
event.clipboardData.setData('nylas-token-items', json);
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ export default class ModelQuery {
|
|||
|
||||
try {
|
||||
return result.map((row) => {
|
||||
const object = JSON.parse(row.data, Utils.registeredObjectReviver)
|
||||
const object = Utils.convertToModel(JSON.parse(row.data));
|
||||
for (const attrName of Object.keys(this._klass.attributes)) {
|
||||
const attr = this._klass.attributes[attrName];
|
||||
if (!attr.needsColumn() || !attr.loadFromColumn) {
|
||||
|
|
|
@ -32,7 +32,7 @@ Utils =
|
|||
html = html.slice(0, maxLength)
|
||||
(new DOMParser()).parseFromString(html, "text/html").body.innerText
|
||||
|
||||
registeredObjectReviver: (k,v) ->
|
||||
modelTypesReviver: (k,v) ->
|
||||
type = v?.__cls
|
||||
return v unless type
|
||||
|
||||
|
@ -40,13 +40,15 @@ Utils =
|
|||
return DatabaseObjectRegistry.deserialize(type, v)
|
||||
|
||||
return v
|
||||
|
||||
registeredObjectReplacer: (k, v) ->
|
||||
if _.isObject(v)
|
||||
type = this[k].constructor.name
|
||||
if DatabaseObjectRegistry.isInRegistry(type)
|
||||
v.__cls = type
|
||||
return v
|
||||
|
||||
convertToModel: (json) ->
|
||||
if not json
|
||||
return null
|
||||
if not json.__cls
|
||||
throw new Error("convertToModel: no __cls found on object.")
|
||||
if not DatabaseObjectRegistry.isInRegistry(json.__cls)
|
||||
throw new Error("convertToModel: __cls is not a known class.")
|
||||
return DatabaseObjectRegistry.deserialize(json.__cls, json)
|
||||
|
||||
fastOmit: (props, without) ->
|
||||
otherProps = Object.assign({}, props)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import Utils from '../models/utils';
|
||||
|
||||
/*
|
||||
DatabaseChangeRecord is the object emitted from the DatabaseStore when it triggers.
|
||||
The DatabaseChangeRecord contains information about what type of model changed,
|
||||
|
@ -8,27 +6,13 @@ change records.
|
|||
*/
|
||||
export default class DatabaseChangeRecord {
|
||||
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
this._objects = options.objects
|
||||
this._objectsString = options.objectsString;
|
||||
this._objects = this._objects || JSON.parse(this._objectsString, Utils.registeredObjectReviver);
|
||||
|
||||
Object.defineProperty(this, 'type', {
|
||||
get: () => options.type,
|
||||
})
|
||||
Object.defineProperty(this, 'objectClass', {
|
||||
get: () => options.objectClass,
|
||||
})
|
||||
Object.defineProperty(this, 'objects', {
|
||||
get: () => {
|
||||
return this._objects;
|
||||
},
|
||||
})
|
||||
constructor({type, objectClass, objects}) {
|
||||
this.objects = objects;
|
||||
this.type = type;
|
||||
this.objectClass = objectClass;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
this._objectsString = this._objectsString || JSON.stringify(this._objects, Utils.registeredObjectReplacer);
|
||||
return {
|
||||
type: this.type,
|
||||
objectClass: this.objectClass,
|
||||
|
|
|
@ -61,10 +61,10 @@ class MailboxPerspective
|
|||
@fromJSON: (json) =>
|
||||
try
|
||||
if json.type is CategoryMailboxPerspective.name
|
||||
categories = JSON.parse(json.serializedCategories, Utils.registeredObjectReviver)
|
||||
categories = JSON.parse(json.serializedCategories).map(Utils.convertToModel)
|
||||
return @forCategories(categories)
|
||||
else if json.type is UnreadMailboxPerspective.name
|
||||
categories = JSON.parse(json.serializedCategories, Utils.registeredObjectReviver)
|
||||
categories = JSON.parse(json.serializedCategories).map(Utils.convertToModel)
|
||||
return @forUnread(categories)
|
||||
else if json.type is StarredMailboxPerspective.name
|
||||
return @forStarred(json.accountIds)
|
||||
|
@ -262,7 +262,7 @@ class CategoryMailboxPerspective extends MailboxPerspective
|
|||
|
||||
toJSON: =>
|
||||
json = super
|
||||
json.serializedCategories = JSON.stringify(@_categories, Utils.registeredObjectReplacer)
|
||||
json.serializedCategories = JSON.stringify(@_categories)
|
||||
json
|
||||
|
||||
isEqual: (other) =>
|
||||
|
|
|
@ -105,7 +105,7 @@ export default class MailsyncProcess extends EventEmitter {
|
|||
sendMessage(json) {
|
||||
if (!Utils) { Utils = require('nylas-exports').Utils; }
|
||||
|
||||
const msg = `${JSON.stringify(json, Utils.registeredObjectReplacer)}\n`;
|
||||
const msg = `${JSON.stringify(json)}\n`;
|
||||
const contentBuffer = Buffer.from(msg);
|
||||
this._proc.stdin.write(contentBuffer);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue