Merge pull request #1 from google/develop

Develop
This commit is contained in:
Tianwei Du
2017-12-09 02:01:36 +08:00
committed by GitHub
7 changed files with 158 additions and 52 deletions

View File

@@ -168,7 +168,9 @@ Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY) {
this.draggingBlock_.moveToDragSurface_();
if (this.workspace_.toolbox_) {
this.workspace_.toolbox_.addDeleteStyle();
var style = this.draggingBlock_.isDeletable() ? 'blocklyToolboxDelete' :
'blocklyToolboxGrab';
this.workspace_.toolbox_.addStyle(style);
}
};
@@ -224,7 +226,9 @@ Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
this.workspace_.setResizesEnabled(true);
if (this.workspace_.toolbox_) {
this.workspace_.toolbox_.removeDeleteStyle();
var style = this.draggingBlock_.isDeletable() ? 'blocklyToolboxDelete' :
'blocklyToolboxGrab';
this.workspace_.toolbox_.removeStyle(style);
}
Blockly.Events.setGroup(false);
};

View File

@@ -253,6 +253,12 @@ Blockly.Css.CONTENT = [
'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',
'}',
'.blocklyToolboxGrab {',
'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
'cursor: grabbing;',
'cursor: -webkit-grabbing;',
'}',
'.blocklyDragging>.blocklyPath,',
'.blocklyDragging>.blocklyPathLight {',
'fill-opacity: .8;',
@@ -499,6 +505,9 @@ Blockly.Css.CONTENT = [
'.blocklyDropdownMenu {',
'padding: 0 !important;',
/* max-height value is same as the constant
* Blockly.FieldDropdown.MAX_MENU_HEIGHT defined in field_dropdown.js. */
'max-height: 300px !important;',
'}',
/* Override the default Closure URL. */

View File

@@ -68,6 +68,12 @@ goog.inherits(Blockly.FieldDropdown, Blockly.Field);
*/
Blockly.FieldDropdown.CHECKMARK_OVERHANG = 25;
/**
* Maximum height of the dropdown menu,it's also referenced in css.js as
* part of .blocklyDropdownMenu.
*/
Blockly.FieldDropdown.MAX_MENU_HEIGHT = 300;
/**
* Android can't (in 2014) display "▾", so use "▼" instead.
*/
@@ -239,6 +245,10 @@ Blockly.FieldDropdown.prototype.positionMenu_ = function(menu) {
this.createWidget_(menu);
var menuSize = Blockly.utils.uiMenu.getSize(menu);
if (menuSize.height > Blockly.FieldDropdown.MAX_MENU_HEIGHT) {
menuSize.height = Blockly.FieldDropdown.MAX_MENU_HEIGHT;
}
if (this.sourceBlock_.RTL) {
Blockly.utils.uiMenu.adjustBBoxesForRTL(viewportBBox, anchorBBox, menuSize);
}

View File

@@ -175,6 +175,13 @@ Blockly.FieldImage.prototype.render_ = function() {
// NOP
};
/**
* Images are fixed width, no need to render even if forced.
*/
Blockly.FieldImage.prototype.forceRerender = function() {
// NOP
};
/**
* Images are fixed width, no need to update.
* @private

View File

@@ -596,6 +596,33 @@ Blockly.Flyout.prototype.onMouseDown_ = function(e) {
}
};
/**
* Helper function to get the list of variables that have been added to the
* workspace after adding a new block, using the given list of variables that
* were in the workspace before the new block was added.
* @param {!Array.<!Blockly.VariableModel>} originalVariables The array of
* variables that existed in the workspace before adding the new block.
* @return {!Array.<!Blockly.VariableModel>} The new array of variables that were
* freshly added to the workspace after creating the new block, or [] if no
* new variables were added to the workspace.
* @private
*/
Blockly.Flyout.prototype.getAddedVariables_ = function(originalVariables) {
var allCurrentVariables = this.targetWorkspace_.getAllVariables();
var addedVariables = [];
if (originalVariables.length != allCurrentVariables.length) {
for (var i = 0; i < allCurrentVariables.length; i++) {
var variable = allCurrentVariables[i];
// For any variable that is present in allCurrentVariables but not
// present in originalVariables, add the variable to addedVariables.
if (!originalVariables.includes(variable)) {
addedVariables.push(variable);
}
}
}
return addedVariables;
};
/**
* Create a copy of this block on the workspace.
* @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout.
@@ -606,6 +633,7 @@ Blockly.Flyout.prototype.onMouseDown_ = function(e) {
Blockly.Flyout.prototype.createBlock = function(originalBlock) {
var newBlock = null;
Blockly.Events.disable();
var variablesBeforeCreation = this.targetWorkspace_.getAllVariables();
this.targetWorkspace_.setResizesEnabled(false);
try {
newBlock = this.placeNewBlock_(originalBlock);
@@ -615,9 +643,16 @@ Blockly.Flyout.prototype.createBlock = function(originalBlock) {
Blockly.Events.enable();
}
var newVariables = this.getAddedVariables_(variablesBeforeCreation);
if (Blockly.Events.isEnabled()) {
Blockly.Events.setGroup(true);
Blockly.Events.fire(new Blockly.Events.Create(newBlock));
// Fire a VarCreate event for each (if any) new variable created.
for(var i = 0; i < newVariables.length; i++) {
var thisVariable = newVariables[i];
Blockly.Events.fire(new Blockly.Events.VarCreate(thisVariable));
}
}
if (this.autoClose) {
this.hide();

View File

@@ -422,21 +422,23 @@ Blockly.Toolbox.prototype.clearSelection = function() {
};
/**
* Adds styles on the toolbox indicating blocks will be deleted.
* Adds a style on the toolbox. Usually used to change the cursor.
* @param {string} style The name of the class to add.
* @package
*/
Blockly.Toolbox.prototype.addDeleteStyle = function() {
Blockly.Toolbox.prototype.addStyle = function(style) {
Blockly.utils.addClass(/** @type {!Element} */ (this.HtmlDiv),
'blocklyToolboxDelete');
style);
};
/**
* Remove styles from the toolbox that indicate blocks will be deleted.
* Removes a style from the toolbox. Usually used to change the cursor.
* @param {string} style The name of the class to remove.
* @package
*/
Blockly.Toolbox.prototype.removeDeleteStyle = function() {
Blockly.Toolbox.prototype.removeStyle = function(style) {
Blockly.utils.removeClass(/** @type {!Element} */ (this.HtmlDiv),
'blocklyToolboxDelete');
style);
};
/**

View File

@@ -86,6 +86,50 @@ Blockly.Xml.blockToDomWithXY = function(block, opt_noId) {
return element;
};
/**
* Encode a field as XML.
* @param {!Blockly.Field} field The field to encode.
* @param {!Blockly.Workspace} workspace The workspace that the field is in.
* @return {?Element} XML element, or null if the field did not need to be
* serialized.
* @private
*/
Blockly.Xml.fieldToDom_ = function(field, workspace) {
if (field.name && field.EDITABLE) {
var container = goog.dom.createDom('field', null, field.getValue());
container.setAttribute('name', field.name);
if (field instanceof Blockly.FieldVariable) {
var variable = workspace.getVariable(field.getValue());
if (variable) {
container.setAttribute('id', variable.getId());
container.setAttribute('variabletype', variable.type);
}
}
return container;
}
return null;
};
/**
* Encode all of a block's fields as XML and attach them to the given tree of
* XML elements.
* @param {!Blockly.Block} block A block with fields to be encoded.
* @param {!Element} element The XML element to which the field DOM should be
* attached.
* @private
*/
Blockly.Xml.allFieldsToDom_ = function(block, element) {
var workspace = block.workspace;
for (var i = 0, input; input = block.inputList[i]; i++) {
for (var j = 0, field; field = input.fieldRow[j]; j++) {
var fieldDom = Blockly.Xml.fieldToDom_(field, workspace);
if (fieldDom) {
element.appendChild(fieldDom);
}
}
}
};
/**
* Encode a block subtree as XML.
* @param {!Blockly.Block} block The root block to encode.
@@ -105,25 +149,8 @@ Blockly.Xml.blockToDom = function(block, opt_noId) {
element.appendChild(mutation);
}
}
function fieldToDom(field) {
if (field.name && field.EDITABLE) {
var container = goog.dom.createDom('field', null, field.getValue());
container.setAttribute('name', field.name);
if (field instanceof Blockly.FieldVariable) {
var variable = block.workspace.getVariable(field.getValue());
if (variable) {
container.setAttribute('id', variable.getId());
container.setAttribute('variabletype', variable.type);
}
}
element.appendChild(container);
}
}
for (var i = 0, input; input = block.inputList[i]; i++) {
for (var j = 0, field; field = input.fieldRow[j]; j++) {
fieldToDom(field);
}
}
Blockly.Xml.allFieldsToDom_(block, element);
var commentText = block.getCommentText();
if (commentText) {
@@ -583,31 +610,7 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
// Titles were renamed to field in December 2013.
// Fall through.
case 'field':
var field = block.getField(name);
var text = xmlChild.textContent;
if (field instanceof Blockly.FieldVariable) {
// TODO (marisaleung): When we change setValue and getValue to
// interact with IDs instead of names, update this so that we get
// the variable based on ID instead of textContent.
var type = xmlChild.getAttribute('variabletype') || '';
var variable = workspace.getVariable(text);
if (!variable) {
variable = workspace.createVariable(text, type,
xmlChild.getAttribute(id));
}
if (type != null && type !== variable.type) {
throw Error('Serialized variable type with id \'' +
variable.getId() + '\' had type ' + variable.type + ', and ' +
'does not match variable field that references it: ' +
Blockly.Xml.domToText(xmlChild) + '.');
}
}
if (!field) {
console.warn('Ignoring non-existent field ' + name + ' in block ' +
prototypeName);
break;
}
field.setValue(text);
Blockly.Xml.domToField_(block, name, xmlChild);
break;
case 'value':
case 'statement':
@@ -695,6 +698,42 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
return block;
};
/**
* Decode an XML field tag and set the value of that field on the given block.
* @param {!Blockly.Block} block The block that is currently being deserialized.
* @param {string} fieldName The name of the field on the block.
* @param {!Element} xml The field tag to decode.
* @private
*/
Blockly.Xml.domToField_ = function(block, fieldName, xml) {
var field = block.getField(fieldName);
if (!field) {
console.warn('Ignoring non-existent field ' + fieldName + ' in block ' +
block.type);
return;
}
var text = xml.textContent;
if (field instanceof Blockly.FieldVariable) {
// TODO (#1199): When we change setValue and getValue to
// interact with IDs instead of names, update this so that we get
// the variable based on ID instead of textContent.
var type = xml.getAttribute('variabletype') || '';
var variable = block.workspace.getVariable(text);
if (!variable) {
variable = block.workspace.createVariable(text, type,
xml.getAttribute('id'));
}
if (type != null && type !== variable.type) {
throw Error('Serialized variable type with id \'' +
variable.getId() + '\' had type ' + variable.type + ', and ' +
'does not match variable field that references it: ' +
Blockly.Xml.domToText(xml) + '.');
}
}
field.setValue(text);
};
/**
* Remove any 'next' block (statements in a stack).
* @param {!Element} xmlBlock XML block element.