mirror of
https://github.com/google/blockly.git
synced 2025-12-16 06:10:12 +01:00
fix: create and delete events, and the trashcan (#5425)
* fix: create and delete events with JSON serialization * fix: trashcan with JSON serialization * fix: build * fix: tests * fix: PR comments * fix: types * fix: tests
This commit is contained in:
committed by
alschmiedt
parent
17f9f4f689
commit
84514efb09
@@ -18,9 +18,9 @@ const Block = goog.requireType('Blockly.Block');
|
||||
const BlockBase = goog.require('Blockly.Events.BlockBase');
|
||||
const Events = goog.require('Blockly.Events');
|
||||
const Xml = goog.require('Blockly.Xml');
|
||||
const blocks = goog.require('Blockly.serialization.blocks');
|
||||
const object = goog.require('Blockly.utils.object');
|
||||
const registry = goog.require('Blockly.registry');
|
||||
const xml = goog.require('Blockly.utils.xml');
|
||||
|
||||
|
||||
/**
|
||||
@@ -40,12 +40,15 @@ const BlockCreate = function(opt_block) {
|
||||
this.recordUndo = false;
|
||||
}
|
||||
|
||||
if (opt_block.workspace.rendered) {
|
||||
this.xml = Xml.blockToDomWithXY(opt_block);
|
||||
} else {
|
||||
this.xml = Xml.blockToDom(opt_block);
|
||||
}
|
||||
this.xml = Xml.blockToDomWithXY(opt_block);
|
||||
this.ids = Events.getDescendantIds(opt_block);
|
||||
|
||||
/**
|
||||
* JSON representation of the block that was just created.
|
||||
* @type {!blocks.State}
|
||||
*/
|
||||
this.json = /** @type {!blocks.State} */ (blocks.save(
|
||||
opt_block, {addCoordinates: true}));
|
||||
};
|
||||
object.inherits(BlockCreate, BlockBase);
|
||||
|
||||
@@ -63,6 +66,7 @@ BlockCreate.prototype.toJson = function() {
|
||||
const json = BlockCreate.superClass_.toJson.call(this);
|
||||
json['xml'] = Xml.domToText(this.xml);
|
||||
json['ids'] = this.ids;
|
||||
json['json'] = this.json;
|
||||
if (!this.recordUndo) {
|
||||
json['recordUndo'] = this.recordUndo;
|
||||
}
|
||||
@@ -77,6 +81,7 @@ BlockCreate.prototype.fromJson = function(json) {
|
||||
BlockCreate.superClass_.fromJson.call(this, json);
|
||||
this.xml = Xml.textToDom(json['xml']);
|
||||
this.ids = json['ids'];
|
||||
this.json = /** @type {!blocks.State} */ (json['json']);
|
||||
if (json['recordUndo'] !== undefined) {
|
||||
this.recordUndo = json['recordUndo'];
|
||||
}
|
||||
@@ -89,9 +94,7 @@ BlockCreate.prototype.fromJson = function(json) {
|
||||
BlockCreate.prototype.run = function(forward) {
|
||||
const workspace = this.getEventWorkspace_();
|
||||
if (forward) {
|
||||
const xmlEl = xml.createElement('xml');
|
||||
xmlEl.appendChild(this.xml);
|
||||
Xml.domToWorkspace(xmlEl, workspace);
|
||||
blocks.load(this.json, workspace);
|
||||
} else {
|
||||
for (let i = 0; i < this.ids.length; i++) {
|
||||
const id = this.ids[i];
|
||||
|
||||
@@ -18,9 +18,9 @@ const Block = goog.requireType('Blockly.Block');
|
||||
const BlockBase = goog.require('Blockly.Events.BlockBase');
|
||||
const Events = goog.require('Blockly.Events');
|
||||
const Xml = goog.require('Blockly.Xml');
|
||||
const blocks = goog.require('Blockly.serialization.blocks');
|
||||
const object = goog.require('Blockly.utils.object');
|
||||
const registry = goog.require('Blockly.registry');
|
||||
const xml = goog.require('Blockly.utils.xml');
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,12 +43,21 @@ const BlockDelete = function(opt_block) {
|
||||
this.recordUndo = false;
|
||||
}
|
||||
|
||||
if (opt_block.workspace.rendered) {
|
||||
this.oldXml = Xml.blockToDomWithXY(opt_block);
|
||||
} else {
|
||||
this.oldXml = Xml.blockToDom(opt_block);
|
||||
}
|
||||
this.oldXml = Xml.blockToDomWithXY(opt_block);
|
||||
this.ids = Events.getDescendantIds(opt_block);
|
||||
|
||||
/**
|
||||
* Was the block that was just deleted a shadow?
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.wasShadow = opt_block.isShadow();
|
||||
|
||||
/**
|
||||
* JSON representation of the block that was just deleted.
|
||||
* @type {!blocks.State}
|
||||
*/
|
||||
this.oldJson = /** @type {!blocks.State} */ (blocks.save(
|
||||
opt_block, {addCoordinates: true}));
|
||||
};
|
||||
object.inherits(BlockDelete, BlockBase);
|
||||
|
||||
@@ -66,6 +75,8 @@ BlockDelete.prototype.toJson = function() {
|
||||
const json = BlockDelete.superClass_.toJson.call(this);
|
||||
json['oldXml'] = Xml.domToText(this.oldXml);
|
||||
json['ids'] = this.ids;
|
||||
json['wasShadow'] = this.wasShadow;
|
||||
json['oldJson'] = this.oldJson;
|
||||
if (!this.recordUndo) {
|
||||
json['recordUndo'] = this.recordUndo;
|
||||
}
|
||||
@@ -80,6 +91,9 @@ BlockDelete.prototype.fromJson = function(json) {
|
||||
BlockDelete.superClass_.fromJson.call(this, json);
|
||||
this.oldXml = Xml.textToDom(json['oldXml']);
|
||||
this.ids = json['ids'];
|
||||
this.wasShadow =
|
||||
json['wasShadow'] || this.oldXml.tagName.toLowerCase() == 'shadow';
|
||||
this.oldJson = /** @type {!blocks.State} */ (json['oldJson']);
|
||||
if (json['recordUndo'] !== undefined) {
|
||||
this.recordUndo = json['recordUndo'];
|
||||
}
|
||||
@@ -103,9 +117,7 @@ BlockDelete.prototype.run = function(forward) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const xmlEl = xml.createElement('xml');
|
||||
xmlEl.appendChild(this.oldXml);
|
||||
Xml.domToWorkspace(xmlEl, workspace);
|
||||
blocks.load(this.oldJson, workspace);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
100
core/trashcan.js
100
core/trashcan.js
@@ -36,7 +36,8 @@ const Size = goog.require('Blockly.utils.Size');
|
||||
const Svg = goog.require('Blockly.utils.Svg');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg');
|
||||
const Xml = goog.require('Blockly.Xml');
|
||||
/* eslint-disable-next-line no-unused-vars */
|
||||
const blocks = goog.requireType('Blockly.serialization.blocks');
|
||||
const browserEvents = goog.require('Blockly.browserEvents');
|
||||
const dom = goog.require('Blockly.utils.dom');
|
||||
const internalConstants = goog.require('Blockly.internalConstants');
|
||||
@@ -73,7 +74,7 @@ const Trashcan = function(workspace) {
|
||||
this.id = 'trashcan';
|
||||
|
||||
/**
|
||||
* A list of XML (stored as strings) representing blocks in the trashcan.
|
||||
* A list of JSON (stored as strings) representing blocks in the trashcan.
|
||||
* @type {!Array<string>}
|
||||
* @private
|
||||
*/
|
||||
@@ -393,8 +394,10 @@ Trashcan.prototype.openFlyout = function() {
|
||||
if (this.contentsIsOpen()) {
|
||||
return;
|
||||
}
|
||||
const xml = this.contents_.map(Xml.textToDom);
|
||||
this.flyout.show(xml);
|
||||
const contents = this.contents_.map(function(string) {
|
||||
return JSON.parse(string);
|
||||
});
|
||||
this.flyout.show(contents);
|
||||
this.fireUiEvent_(true);
|
||||
};
|
||||
|
||||
@@ -669,14 +672,12 @@ Trashcan.prototype.onDelete_ = function(event) {
|
||||
if (this.workspace_.options.maxTrashcanContents <= 0) {
|
||||
return;
|
||||
}
|
||||
// Must check that the tagName exists since oldXml can be a DocumentFragment.
|
||||
if (event.type == Events.BLOCK_DELETE && event.oldXml.tagName &&
|
||||
event.oldXml.tagName.toLowerCase() != 'shadow') {
|
||||
const cleanedXML = this.cleanBlockXML_(event.oldXml);
|
||||
if (this.contents_.indexOf(cleanedXML) != -1) {
|
||||
if (event.type == Events.BLOCK_DELETE && !event.wasShadow) {
|
||||
const cleanedJson = this.cleanBlockJson_(event.oldJson);
|
||||
if (this.contents_.indexOf(cleanedJson) != -1) {
|
||||
return;
|
||||
}
|
||||
this.contents_.unshift(cleanedXML);
|
||||
this.contents_.unshift(cleanedJson);
|
||||
while (this.contents_.length >
|
||||
this.workspace_.options.maxTrashcanContents) {
|
||||
this.contents_.pop();
|
||||
@@ -687,52 +688,51 @@ Trashcan.prototype.onDelete_ = function(event) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts XML representing a block into text that can be stored in the
|
||||
* content array.
|
||||
* @param {!Element} xml An XML tree defining the block and any
|
||||
* connected child blocks.
|
||||
* @return {string} Text representing the XML tree, cleaned of all unnecessary
|
||||
* attributes.
|
||||
* Converts JSON representing a block into text that can be stored in the
|
||||
* content array.
|
||||
* @param {!blocks.State} json A JSON representation of
|
||||
* a block's state.
|
||||
* @return {string} Text representing the JSON, cleaned of all unnecessary
|
||||
* attributes.
|
||||
* @private
|
||||
*/
|
||||
Trashcan.prototype.cleanBlockXML_ = function(xml) {
|
||||
const xmlBlock = xml.cloneNode(true);
|
||||
let node = xmlBlock;
|
||||
while (node) {
|
||||
// Things like text inside tags are still treated as nodes, but they
|
||||
// don't have attributes (or the removeAttribute function) so we can
|
||||
// skip removing attributes from them.
|
||||
if (node.removeAttribute) {
|
||||
node.removeAttribute('x');
|
||||
node.removeAttribute('y');
|
||||
node.removeAttribute('id');
|
||||
node.removeAttribute('disabled');
|
||||
if (node.nodeName == 'comment') { // Future proof just in case.
|
||||
node.removeAttribute('h');
|
||||
node.removeAttribute('w');
|
||||
node.removeAttribute('pinned');
|
||||
}
|
||||
Trashcan.prototype.cleanBlockJson_ = function(json) {
|
||||
// Create a deep copy.
|
||||
json = /** @type {!blocks.State} */(JSON.parse(JSON.stringify(json)));
|
||||
|
||||
function cleanRec(json) {
|
||||
if (!json) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to go down the tree
|
||||
let nextNode = node.firstChild || node.nextSibling;
|
||||
// If we can't go down, try to go back up the tree.
|
||||
if (!nextNode) {
|
||||
nextNode = node.parentNode;
|
||||
while (nextNode) {
|
||||
// We are valid again!
|
||||
if (nextNode.nextSibling) {
|
||||
nextNode = nextNode.nextSibling;
|
||||
break;
|
||||
}
|
||||
// Try going up again. If parentNode is null that means we have
|
||||
// reached the top, and we will break out of both loops.
|
||||
nextNode = nextNode.parentNode;
|
||||
}
|
||||
delete json['id'];
|
||||
delete json['x'];
|
||||
delete json['y'];
|
||||
delete json['enabled'];
|
||||
|
||||
if (json['icons'] && json['icons']['comment']) {
|
||||
const comment = json['icons']['comment'];
|
||||
delete comment['height'];
|
||||
delete comment['width'];
|
||||
delete comment['pinned'];
|
||||
}
|
||||
|
||||
const inputs = json['inputs'];
|
||||
for (var name in inputs) {
|
||||
const input = inputs[name];
|
||||
cleanRec(input['block']);
|
||||
cleanRec(input['shadow']);
|
||||
}
|
||||
if (json['next']) {
|
||||
const next = json['next'];
|
||||
cleanRec(next['block']);
|
||||
cleanRec(next['shadow']);
|
||||
}
|
||||
node = nextNode;
|
||||
}
|
||||
return Xml.domToText(xmlBlock);
|
||||
|
||||
cleanRec(json);
|
||||
json['kind'] = 'BLOCK';
|
||||
return JSON.stringify(json);
|
||||
};
|
||||
|
||||
exports = Trashcan;
|
||||
|
||||
@@ -40,8 +40,8 @@ goog.addDependency('../../core/events/events.js', ['Blockly.Events'], ['Blockly.
|
||||
goog.addDependency('../../core/events/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_base.js', ['Blockly.Events.BlockBase'], ['Blockly.Events.Abstract', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_change.js', ['Blockly.Events.BlockChange'], ['Blockly.Events', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_create.js', ['Blockly.Events.BlockCreate'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_delete.js', ['Blockly.Events.BlockDelete'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_create.js', ['Blockly.Events.BlockCreate'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.serialization.blocks', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_delete.js', ['Blockly.Events.BlockDelete'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.serialization.blocks', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_drag.js', ['Blockly.Events.BlockDrag'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_move.js', ['Blockly.Events.BlockMove'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.connectionTypes', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_bubble_open.js', ['Blockly.Events.BubbleOpen'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
@@ -217,7 +217,7 @@ goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem']
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.common', 'Blockly.utils.deprecation', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.internalConstants', 'Blockly.utils.global', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.Options', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.Options', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.internalConstants', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.idGenerator', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.svgPaths', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], [], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], ['Blockly.internalConstants'], {'lang': 'es6', 'module': 'goog'});
|
||||
|
||||
@@ -40,8 +40,8 @@ goog.addDependency('../../core/events/events.js', ['Blockly.Events'], ['Blockly.
|
||||
goog.addDependency('../../core/events/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_base.js', ['Blockly.Events.BlockBase'], ['Blockly.Events.Abstract', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_change.js', ['Blockly.Events.BlockChange'], ['Blockly.Events', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_create.js', ['Blockly.Events.BlockCreate'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_delete.js', ['Blockly.Events.BlockDelete'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_create.js', ['Blockly.Events.BlockCreate'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.serialization.blocks', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_delete.js', ['Blockly.Events.BlockDelete'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.serialization.blocks', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_drag.js', ['Blockly.Events.BlockDrag'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_block_move.js', ['Blockly.Events.BlockMove'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.connectionTypes', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/events/events_bubble_open.js', ['Blockly.Events.BubbleOpen'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
@@ -217,7 +217,7 @@ goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem']
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.common', 'Blockly.utils.deprecation', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.internalConstants', 'Blockly.utils.global', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.Options', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.Options', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.internalConstants', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.idGenerator', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.svgPaths', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], [], {'lang': 'es6', 'module': 'goog'});
|
||||
goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], ['Blockly.internalConstants'], {'lang': 'es6', 'module': 'goog'});
|
||||
|
||||
@@ -437,48 +437,118 @@ suite('Events', function() {
|
||||
viewLeft: 0, scale: 1.2, oldScale: 1})},
|
||||
];
|
||||
var blockEventTestCases = [
|
||||
{title: 'Block change', class: Blockly.Events.BlockChange,
|
||||
{
|
||||
title: 'Block change',
|
||||
class: Blockly.Events.BlockChange,
|
||||
getArgs: (thisObj) => [thisObj.block, 'collapsed', null, false, true],
|
||||
getExpectedJson: (thisObj) => ({type: 'change',
|
||||
blockId: thisObj.block.id, element: 'collapsed', oldValue: false,
|
||||
newValue: true})},
|
||||
{title: 'Block create', class: Blockly.Events.BlockCreate,
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'change',
|
||||
blockId: thisObj.block.id,
|
||||
element: 'collapsed',
|
||||
oldValue: false,
|
||||
newValue: true
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Block create',
|
||||
class: Blockly.Events.BlockCreate,
|
||||
getArgs: (thisObj) => [thisObj.block],
|
||||
getExpectedJson: (thisObj) => ({type: 'create',
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'create',
|
||||
blockId: thisObj.block.id,
|
||||
xml: '<block xmlns="https://developers.google.com/blockly/xml"' +
|
||||
' type="simple_test_block" id="testBlockId1"></block>',
|
||||
ids: [thisObj.block.id]})},
|
||||
{title: 'Block create (shadow)', class: Blockly.Events.BlockCreate,
|
||||
' type="simple_test_block" id="testBlockId1" x="0" y="0">' +
|
||||
'</block>',
|
||||
ids: [thisObj.block.id],
|
||||
json: {
|
||||
'type': 'simple_test_block',
|
||||
'id': 'testBlockId1',
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Block create (shadow)',
|
||||
class: Blockly.Events.BlockCreate,
|
||||
getArgs: (thisObj) => [thisObj.shadowBlock],
|
||||
getExpectedJson: (thisObj) => ({type: 'create',
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'create',
|
||||
blockId: thisObj.shadowBlock.id,
|
||||
xml: '<shadow xmlns="https://developers.google.com/blockly/xml"' +
|
||||
' type="simple_test_block" id="testBlockId2"></shadow>',
|
||||
ids: [thisObj.shadowBlock.id], recordUndo: false})},
|
||||
{title: 'Block delete', class: Blockly.Events.BlockDelete,
|
||||
' type="simple_test_block" id="testBlockId2" x="0" y="0">' +
|
||||
'</shadow>',
|
||||
ids: [thisObj.shadowBlock.id],
|
||||
json: {
|
||||
'type': 'simple_test_block',
|
||||
'id': 'testBlockId2',
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
},
|
||||
recordUndo: false
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Block delete',
|
||||
class: Blockly.Events.BlockDelete,
|
||||
getArgs: (thisObj) => [thisObj.block],
|
||||
getExpectedJson: (thisObj) => ({type: 'delete',
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'delete',
|
||||
blockId: thisObj.block.id,
|
||||
oldXml: '<block xmlns="https://developers.google.com/blockly/xml"' +
|
||||
' type="simple_test_block" id="testBlockId1"></block>',
|
||||
ids: [thisObj.block.id]})},
|
||||
{title: 'Block delete (shadow)', class: Blockly.Events.BlockDelete,
|
||||
' type="simple_test_block" id="testBlockId1" x="0" y="0">' +
|
||||
'</block>',
|
||||
ids: [thisObj.block.id],
|
||||
wasShadow: false,
|
||||
oldJson: {
|
||||
'type': 'simple_test_block',
|
||||
'id': 'testBlockId1',
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Block delete (shadow)',
|
||||
class: Blockly.Events.BlockDelete,
|
||||
getArgs: (thisObj) => [thisObj.shadowBlock],
|
||||
getExpectedJson: (thisObj) => ({type: 'delete',
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'delete',
|
||||
blockId: thisObj.shadowBlock.id,
|
||||
oldXml: '<shadow xmlns="https://developers.google.com/blockly/xml"' +
|
||||
' type="simple_test_block" id="testBlockId2"></shadow>',
|
||||
ids: [thisObj.shadowBlock.id], recordUndo: false})},
|
||||
' type="simple_test_block" id="testBlockId2" x="0" y="0">' +
|
||||
'</shadow>',
|
||||
ids: [thisObj.shadowBlock.id],
|
||||
wasShadow: true,
|
||||
oldJson: {
|
||||
'type': 'simple_test_block',
|
||||
'id': 'testBlockId2',
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
},
|
||||
recordUndo: false
|
||||
})
|
||||
},
|
||||
// TODO(#4577) Test serialization of move event coordinate properties.
|
||||
{title: 'Block move', class: Blockly.Events.BlockMove,
|
||||
{
|
||||
title: 'Block move',
|
||||
class: Blockly.Events.BlockMove,
|
||||
getArgs: (thisObj) => [thisObj.block],
|
||||
getExpectedJson: (thisObj) => ({type: 'move',
|
||||
blockId: thisObj.block.id})},
|
||||
{title: 'Block move (shadow)', class: Blockly.Events.BlockMove,
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'move',
|
||||
blockId: thisObj.block.id
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Block move (shadow)',
|
||||
class: Blockly.Events.BlockMove,
|
||||
getArgs: (thisObj) => [thisObj.shadowBlock],
|
||||
getExpectedJson: (thisObj) => ({type: 'move',
|
||||
blockId: thisObj.shadowBlock.id, recordUndo: false})},
|
||||
getExpectedJson: (thisObj) => ({
|
||||
type: 'move',
|
||||
blockId: thisObj.shadowBlock.id,
|
||||
recordUndo: false
|
||||
})
|
||||
},
|
||||
];
|
||||
var workspaceEventTestCases = [
|
||||
{title: 'Finished Loading', class: Blockly.Events.FinishedLoading,
|
||||
|
||||
@@ -689,7 +689,11 @@ suite('JSO Deserialization', function() {
|
||||
Blockly.Blocks['test_block'] = {
|
||||
init: function() { },
|
||||
|
||||
mutationToDom: function() { },
|
||||
mutationToDom: function() {
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('value', 'some value');
|
||||
return container;
|
||||
},
|
||||
|
||||
domToMutation: function(element) {
|
||||
this.someProperty = element.getAttribute('value');
|
||||
|
||||
@@ -481,9 +481,9 @@ function assertNthCallEventArgEquals(spy, n, instanceType, expectedProperties,
|
||||
}
|
||||
exports.assertNthCallEventArgEquals = assertNthCallEventArgEquals;
|
||||
|
||||
function defineStackBlock() {
|
||||
function defineStackBlock(name = 'stack_block') {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "stack_block",
|
||||
"type": name,
|
||||
"message0": "",
|
||||
"previousStatement": null,
|
||||
"nextStatement": null
|
||||
@@ -491,9 +491,9 @@ function defineStackBlock() {
|
||||
}
|
||||
exports.defineStackBlock = defineStackBlock;
|
||||
|
||||
function defineRowBlock() {
|
||||
function defineRowBlock(name = 'row_block') {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "row_block",
|
||||
"type": name,
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
@@ -506,9 +506,9 @@ function defineRowBlock() {
|
||||
}
|
||||
exports.defineRowBlock = defineRowBlock;
|
||||
|
||||
function defineStatementBlock() {
|
||||
function defineStatementBlock(name = 'statement_block') {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "statement_block",
|
||||
"type": name,
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
@@ -525,9 +525,9 @@ function defineStatementBlock() {
|
||||
}
|
||||
exports.defineStatementBlock = defineStatementBlock;
|
||||
|
||||
function defineBasicBlockWithField() {
|
||||
function defineBasicBlockWithField(name = 'test_field_block') {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "test_field_block",
|
||||
"type": name,
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
goog.module('Blockly.test.trashcan');
|
||||
|
||||
const {assertEventFired, assertEventNotFired, sharedTestSetup, sharedTestTeardown, simulateClick} = goog.require('Blockly.test.helpers');
|
||||
const {assertEventFired, assertEventNotFired, defineBasicBlockWithField, defineRowBlock, defineStatementBlock, defineStackBlock, defineMutatorBlocks, sharedTestSetup, sharedTestTeardown, simulateClick} = goog.require('Blockly.test.helpers');
|
||||
|
||||
|
||||
suite("Trashcan", function() {
|
||||
@@ -15,14 +15,13 @@ suite("Trashcan", function() {
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
xmlString + '</xml>');
|
||||
xml = xml.children[0];
|
||||
var event = new Blockly.Events.BlockDelete();
|
||||
event.oldXml = xml;
|
||||
event.workspaceId = workspace.id;
|
||||
var block = Blockly.Xml.domToBlock(xml, workspace);
|
||||
var event = new Blockly.Events.BlockDelete(block);
|
||||
Blockly.Events.fire(event);
|
||||
}
|
||||
function fireNonDeleteEvent(workspace, oldXml) {
|
||||
var event = new Blockly.Events.Abstract();
|
||||
event.type = 'dummy_type';
|
||||
event.type = 'test_field_block';
|
||||
event.workspaceId = workspace.id;
|
||||
if (oldXml) {
|
||||
event.oldXml = oldXml;
|
||||
@@ -32,17 +31,27 @@ suite("Trashcan", function() {
|
||||
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
defineBasicBlockWithField();
|
||||
defineRowBlock();
|
||||
defineRowBlock('row_block2');
|
||||
defineStatementBlock();
|
||||
defineStatementBlock('statement_block2');
|
||||
defineStackBlock();
|
||||
defineStackBlock('stack_block2');
|
||||
defineMutatorBlocks();
|
||||
this.workspace = Blockly.inject('blocklyDiv',
|
||||
{'trashcan': true, 'maxTrashcanContents': Infinity});
|
||||
this.trashcan = this.workspace.trashcan;
|
||||
});
|
||||
teardown(function() {
|
||||
sharedTestTeardown.call(this);
|
||||
Blockly.Extensions.unregister('xml_mutator');
|
||||
Blockly.Extensions.unregister('jso_mutator');
|
||||
});
|
||||
|
||||
suite("Events", function() {
|
||||
test("Delete", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="test_field_block"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
});
|
||||
test("Non-Delete", function() {
|
||||
@@ -52,7 +61,7 @@ suite("Trashcan", function() {
|
||||
test("Non-Delete w/ oldXml", function() {
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
||||
' <block type="dummy_type"/>' +
|
||||
' <block type="test_field_block"/>' +
|
||||
'</xml>'
|
||||
);
|
||||
xml = xml.children[0];
|
||||
@@ -60,7 +69,7 @@ suite("Trashcan", function() {
|
||||
chai.assert.equal(this.trashcan.contents_.length, 0);
|
||||
});
|
||||
test("Shadow Delete", function() {
|
||||
fireDeleteEvent(this.workspace, '<shadow type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<shadow type="test_field_block"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 0);
|
||||
});
|
||||
test("Click without contents - fires workspace click", function() {
|
||||
@@ -73,7 +82,7 @@ suite("Trashcan", function() {
|
||||
this.workspace.id, null);
|
||||
});
|
||||
test("Click with contents - fires trashcanOpen", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="test_field_block"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
// Stub flyout interaction.
|
||||
var showFlyoutStub = sinon.stub(this.trashcan.flyout, "show");
|
||||
@@ -107,56 +116,52 @@ suite("Trashcan", function() {
|
||||
});
|
||||
suite("Unique Contents", function() {
|
||||
test("Simple", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="test_field_block"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="test_field_block"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
});
|
||||
test("Different Coords", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" x="10" y="10"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" x="20" y="20"/>');
|
||||
fireDeleteEvent(
|
||||
this.workspace, '<block type="test_field_block" x="10" y="10"/>');
|
||||
fireDeleteEvent(
|
||||
this.workspace, '<block type="test_field_block" x="20" y="20"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
});
|
||||
test("Different IDs", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" id="id1"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" id="id2"/>');
|
||||
fireDeleteEvent(
|
||||
this.workspace, '<block type="test_field_block" id="id1"/>');
|
||||
fireDeleteEvent(
|
||||
this.workspace, '<block type="test_field_block" id="id2"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
});
|
||||
test("No Disabled - Disabled True", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" disabled="true"/>');
|
||||
fireDeleteEvent(
|
||||
this.workspace, '<block type="test_field_block"/>');
|
||||
fireDeleteEvent(
|
||||
this.workspace, '<block type="test_field_block" disabled="true"/>');
|
||||
// Disabled tags get removed because disabled blocks aren't allowed to
|
||||
// be dragged from flyouts. See #2239 and #3243.
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
});
|
||||
test("No Editable - Editable False", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" editable="false"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("No Movable - Movable False", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type" movable="false"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("Different Field Values", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <field name="dummy_name">dummy_value1</field>' +
|
||||
'<block type="test_field_block">' +
|
||||
' <field name="NAME">dummy_value1</field>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <field name="dummy_name">dummy_value2</field>' +
|
||||
'<block type="test_field_block">' +
|
||||
' <field name="NAME">dummy_value2</field>' +
|
||||
'</block>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("No Values - Values", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="row_block"/>');
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <value name="dummy_input">' +
|
||||
' <block type="dummy_type"/>' +
|
||||
'<block type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <block type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</block>'
|
||||
);
|
||||
@@ -164,27 +169,27 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Different Value Blocks", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <value name="dummy_input">' +
|
||||
' <block type="dummy_type1"/>' +
|
||||
'<block type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <block type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <value name="dummy_input">' +
|
||||
' <block type="dummy_type2"/>' +
|
||||
'<block type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <block type="row_block2"/>' +
|
||||
' </value>' +
|
||||
'</block>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("No Statements - Statements", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="statement_block"/>');
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <statement name="dummy_input">' +
|
||||
' <block type="dummy_type"/>' +
|
||||
'<block type="statement_block">' +
|
||||
' <statement name="NAME">' +
|
||||
' <block type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</block>'
|
||||
);
|
||||
@@ -192,27 +197,27 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Different Statement Blocks", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <statement name="dummy_input">' +
|
||||
' <block type="dummy_type1"/>' +
|
||||
'<block type="statement_block">' +
|
||||
' <statement name="NAME">' +
|
||||
' <block type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <statement name="dummy_input">' +
|
||||
' <block type="dummy_type2"/>' +
|
||||
'<block type="test_field_block">' +
|
||||
' <statement name="NAME">' +
|
||||
' <block type="statement_block2"/>' +
|
||||
' </statement>' +
|
||||
'</block>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("No Next - Next", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="stack_block"/>');
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="stack_block">' +
|
||||
' <next>' +
|
||||
' <block type="dummy_type"/>' +
|
||||
' <block type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</block>'
|
||||
);
|
||||
@@ -220,25 +225,25 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Different Next Blocks", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="stack_block">' +
|
||||
' <next>' +
|
||||
' <block type="dummy_type1"/>' +
|
||||
' <block type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="stack_block">' +
|
||||
' <next>' +
|
||||
' <block type="dummy_type2"/>' +
|
||||
' <block type="stack_block2"/>' +
|
||||
' </next>' +
|
||||
'</block>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("No Comment - Comment", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="test_field_block"/>');
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment>comment_text</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
@@ -246,12 +251,12 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Different Comment Text", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment>comment_text1</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment>comment_text2</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
@@ -259,12 +264,12 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Different Comment Size", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment h="10" w="10">comment_text</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment h="20" w="20">comment_text</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
@@ -273,36 +278,27 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Different Comment Pinned", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment pinned="false">comment_text</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
'<block type="test_field_block">' +
|
||||
' <comment pinned="true">comment_text</comment>' +
|
||||
'</block>'
|
||||
);
|
||||
// pinned tags are removed b/c the blocks appear the same.
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
});
|
||||
test("No Mutator - Mutator", function() {
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type"/>');
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <mutation dummy_attribute="dummy_value"></mutation>' +
|
||||
'</block>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
});
|
||||
test("Different Mutator", function() {
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <mutation dummy_attribute="dummy_value1"></mutation>' +
|
||||
'<block type="xml_block">' +
|
||||
' <mutation hasInput="true"></mutation>' +
|
||||
'</block>'
|
||||
);
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type">' +
|
||||
' <mutation dummy_attribute="dummy_value2"></mutation>' +
|
||||
'<block type="xml_block">' +
|
||||
' <mutation hasInputt="false"></mutation>' +
|
||||
'</block>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 2);
|
||||
@@ -312,22 +308,10 @@ suite("Trashcan", function() {
|
||||
test("Max 0", function() {
|
||||
this.workspace.options.maxTrashcanContents = 0;
|
||||
fireDeleteEvent(this.workspace,
|
||||
'<block type="dummy_type"/>'
|
||||
'<block type="test_field_block"/>'
|
||||
);
|
||||
chai.assert.equal(this.trashcan.contents_.length, 0);
|
||||
this.workspace.options.maxTrashcanContents = Infinity;
|
||||
});
|
||||
test("Last In First Out", function() {
|
||||
this.workspace.options.maxTrashcanContents = 1;
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type1"/>');
|
||||
fireDeleteEvent(this.workspace, '<block type="dummy_type2"/>');
|
||||
chai.assert.equal(this.trashcan.contents_.length, 1);
|
||||
chai.assert.equal(
|
||||
Blockly.Xml.textToDom(this.trashcan.contents_[0])
|
||||
.getAttribute('type'),
|
||||
'dummy_type2'
|
||||
);
|
||||
this.workspace.options.maxTrashcanContents = Infinity;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user