mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Implement a new strategy for importing JSON, where it is imported into the item itself, not its children list, if the class match.
This commit is contained in:
parent
70ae7486e9
commit
c76dae5b06
2 changed files with 40 additions and 28 deletions
|
@ -390,46 +390,51 @@ Base.inject(/** @lends Base# */{
|
|||
* deserializable types through Base.exports, and the values following
|
||||
* in the array are the arguments to their initialize function.
|
||||
* Any other value is passed on unmodified.
|
||||
* The passed data is recoursively traversed and converted, leaves first
|
||||
* The passed json data is recoursively traversed and converted, leaves
|
||||
* first
|
||||
*/
|
||||
deserialize: function(obj, data) {
|
||||
var res = obj;
|
||||
// A data side-car to deserialize that can hold any kind of 'global'
|
||||
// data across a deserialization. It's currently just used to hold
|
||||
// dictionary definitions.
|
||||
data = data || {};
|
||||
if (Array.isArray(obj)) {
|
||||
deserialize: function(json, target, _data) {
|
||||
var res = json;
|
||||
// A _data side-car to deserialize that can hold any kind of
|
||||
// 'global' data across a deserialization. It's currently only used
|
||||
// to hold dictionary definitions.
|
||||
_data = _data || {};
|
||||
if (Array.isArray(json)) {
|
||||
// See if it's a serialized type. If so, the rest of the array
|
||||
// are the arguments to #initialize(). Either way, we simply
|
||||
// deserialize all elements of the array.
|
||||
var type = obj[0],
|
||||
var type = json[0],
|
||||
// Handle stored dictionary specially, since we need to
|
||||
// keep is a lookup table to retrieve referenced items from.
|
||||
isDictionary = type === 'dictionary';
|
||||
if (!isDictionary) {
|
||||
// First see if this is perhaps a dictionary reference, and
|
||||
// if so return its definition instead.
|
||||
if (data.dictionary && obj.length == 1 && /^#/.test(type))
|
||||
return data.dictionary[type];
|
||||
if (_data.dictionary && json.length == 1 && /^#/.test(type))
|
||||
return _data.dictionary[type];
|
||||
type = Base.exports[type];
|
||||
}
|
||||
res = [];
|
||||
// Skip first type entry for arguments
|
||||
for (var i = type ? 1 : 0, l = obj.length; i < l; i++)
|
||||
res.push(Base.deserialize(obj[i], data));
|
||||
for (var i = type ? 1 : 0, l = json.length; i < l; i++)
|
||||
res.push(Base.deserialize(json[i], null, _data));
|
||||
if (isDictionary) {
|
||||
data.dictionary = res[0];
|
||||
_data.dictionary = res[0];
|
||||
} else if (type) {
|
||||
// Create serialized type and pass collected arguments to
|
||||
// constructor().
|
||||
var args = res;
|
||||
res = Base.create(type.prototype);
|
||||
// If a target is provided and its of the right type,
|
||||
// import right into it.
|
||||
res = target instanceof type
|
||||
? target
|
||||
: Base.create(type.prototype);
|
||||
type.apply(res, args);
|
||||
}
|
||||
} else if (Base.isPlainObject(obj)) {
|
||||
} else if (Base.isPlainObject(json)) {
|
||||
res = {};
|
||||
for (var key in obj)
|
||||
res[key] = Base.deserialize(obj[key], data);
|
||||
for (var key in json)
|
||||
res[key] = Base.deserialize(json[key], null, _data);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
@ -438,9 +443,9 @@ Base.inject(/** @lends Base# */{
|
|||
return JSON.stringify(Base.serialize(obj, options));
|
||||
},
|
||||
|
||||
importJSON: function(json) {
|
||||
importJSON: function(json, target) {
|
||||
return Base.deserialize(
|
||||
typeof json === 'string' ? JSON.parse(json) : json);
|
||||
typeof json === 'string' ? JSON.parse(json) : json, target);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1306,9 +1306,9 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
// Insert is true by default.
|
||||
if (insert || insert === undefined)
|
||||
copy.insertAbove(this);
|
||||
// Only copy over these fields if they are actually defined in 'this'
|
||||
// TODO: Consider moving this to Base once it's useful in more than one
|
||||
// place
|
||||
// Only copy over these fields if they are actually defined in 'this',
|
||||
// meaning the default value has been overwritten (default is on
|
||||
// prototype).
|
||||
var keys = ['_locked', '_visible', '_blendMode', '_opacity',
|
||||
'_clipMask', '_guide'];
|
||||
for (var i = 0, l = keys.length; i < l; i++) {
|
||||
|
@ -1649,15 +1649,22 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
*/
|
||||
|
||||
/**
|
||||
* Imports (deserializes) the stored JSON data into this item's
|
||||
* {@link Item#children} list.
|
||||
* Note that the item is not cleared first. You can call
|
||||
* {@link Item#removeChildren()} to do so.
|
||||
* Imports (deserializes) the stored JSON data into this item. If the data
|
||||
* describes an item of the same class or a parent class of the item, the
|
||||
* data is imported into the item itself. If not, the imported item is added
|
||||
* to this item's {@link Item#children} list. Note that not all type of
|
||||
* items can have children.
|
||||
*
|
||||
* @param {String} json the JSON data to import from.
|
||||
*/
|
||||
importJSON: function(json) {
|
||||
return this.addChild(Base.importJSON(json));
|
||||
// Try importing into `this`. If another item is returned, try adding
|
||||
// it as a child (this won't be successful on some classes, returning
|
||||
// null).
|
||||
var res = Base.importJSON(json, this);
|
||||
return res !== this
|
||||
? this.addChild(res)
|
||||
: res;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue