diff --git a/src/engine/target.js b/src/engine/target.js index 166e44369..114dd1276 100644 --- a/src/engine/target.js +++ b/src/engine/target.js @@ -20,9 +20,10 @@ class Target extends EventEmitter { /** * @param {Runtime} runtime Reference to the runtime. * @param {?Blocks} blocks Blocks instance for the blocks owned by this target. + * @param {?Object.<string, *>} comments Array of comments owned by this target. * @constructor */ - constructor (runtime, blocks) { + constructor (runtime, blocks, comments) { super(); if (!blocks) { @@ -55,7 +56,7 @@ class Target extends EventEmitter { * Key is the comment id. * @type {Object.<string,*>} */ - this.comments = {}; + this.comments = comments || {}; /** * Dictionary of custom state for this target. * This can be used to store target-specific custom state for blocks which need it. diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index e4a12e244..d3230cce1 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -15,7 +15,7 @@ class RenderedTarget extends Target { * @constructor */ constructor (sprite, runtime) { - super(runtime, sprite.blocks); + super(runtime, sprite.blocks, sprite.comments); /** * Reference to the sprite that this is a render of. diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js index a38fa129c..243882e63 100644 --- a/src/sprites/sprite.js +++ b/src/sprites/sprite.js @@ -54,6 +54,12 @@ class Sprite { if (this.runtime && this.runtime.audioEngine) { this.soundBank = this.runtime.audioEngine.createBank(); } + /** + * Dictionary of comments for this target. + * Key is the comment id. + * @type {Object.<string.*>} + */ + this.comments = {}; } /** @@ -145,7 +151,12 @@ class Sprite { newSprite.blocks.createBlock(block); }); - + // Logic to handle new sprite retaining the comments from the current sprite + Object.keys(this.comments).forEach(commentId => { + const newComment = this.comments[commentId]; + newSprite.comments[newComment.id] = newComment; + }); + const allNames = this.runtime.targets.map(t => t.sprite.name); newSprite.name = StringUtil.unusedName(this.name, allNames); diff --git a/test/unit/sprites_rendered-target.js b/test/unit/sprites_rendered-target.js index a9823424a..c6400d362 100644 --- a/test/unit/sprites_rendered-target.js +++ b/test/unit/sprites_rendered-target.js @@ -45,6 +45,39 @@ test('blocks get new id on duplicate', t => { }); }); +test('comments are duplicated when duplicating target', t => { + const r = new Runtime(); + const s = new Sprite(null, r); + const rt = new RenderedTarget(s, r); + rt.createComment('testCommentId', null, 'testcomment', 0, 0, 100, 100, false); + return rt.duplicate().then(duplicate => { + // ensure duplicated comment exists + t.equal(Object.keys(duplicate.comments).length, 1); + + // ensure comment was duplicated correctly + const dupComment = duplicate.comments.testCommentId; + t.equal(dupComment.id, 'testCommentId'); + t.equal(dupComment.text, 'testcomment'); + t.equal(dupComment.x, 0); + t.equal(dupComment.y, 0); + t.equal(dupComment.width, 100); + t.equal(dupComment.height, 100); + t.equal(dupComment.minimized, false); + + t.end(); + }); +}); + +test('no comments are duplicated when duplicating target with no comments', t => { + const r = new Runtime(); + const s = new Sprite(null, r); + const rt = new RenderedTarget(s, r); + return rt.duplicate().then(duplicate => { + t.equal(Object.keys(duplicate.comments).length, 0); + t.end(); + }); +}); + test('direction', t => { const r = new Runtime(); const s = new Sprite(null, r);