Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pxtblocks/builtins/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { domToWorkspaceNoEvents } from "../importer";
import { shouldDuplicateOnDrag } from "../plugins/duplicateOnDrag";
import { PathObject } from "../plugins/renderer/pathObject";
import { FieldImageNoText } from "../fields/field_imagenotext";
import { getGlobalProgram } from "../external";

export function initFunctions() {
const msg = Blockly.Msg;
Expand Down
4 changes: 3 additions & 1 deletion pxtblocks/builtins/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function initVariables() {
mostRecentVariable = variableModelList[0];
}
let currentFile: string;
const globeIcon = "\uf0ac";

// variables getters first
for (let i = 0; i < variableModelList.length; i++) {
Expand All @@ -34,7 +35,8 @@ export function initVariables() {
if (symbol) {
if (currentFile !== symbol.file) {
currentFile = symbol.file;
const label = createFlyoutGroupLabel(currentFile);
const label = createFlyoutGroupLabel(currentFile, globeIcon);
label.setAttribute("web-icon-color", "#fff");
xmlList.push(label);
}
}
Expand Down
13 changes: 9 additions & 4 deletions pxtblocks/plugins/functions/blocks/functionCallBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,15 @@ const FUNCTION_CALL_MIXIN: FunctionCallMixin = {
},

addFunctionLabel_: function (this: FunctionCallBlock, text) {
this.appendDummyInput("function_name").appendField(
new Blockly.FieldLabel(text, "functionNameText"),
"function_name"
);
const input = this.appendDummyInput("function_name");

if (this.imported_) {
const globe = new Blockly.FieldLabel("\uf0ac", "blocklyText semanticIcon");
globe.setClass("blocklyText semanticIcon");
input.appendField(globe);
}

input.appendField(new Blockly.FieldLabel(text, "functionNameText"), "function_name");
},

updateFunctionLabel_: function (this: FunctionCallBlock, text: string) {
Expand Down
7 changes: 7 additions & 0 deletions pxtblocks/plugins/functions/commonFunctionMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,21 @@ export interface FunctionDefinitionExtraState {
name: string;
functionid: string;
arguments: FunctionArgument[];
imported?: boolean;
}

export const COMMON_FUNCTION_MIXIN = {
name_: "",
functionId_: "",
arguments_: [] as FunctionArgument[],
imported_: false,

mutationToDom: function (this: CommonFunctionBlock): Element | null {
this.ensureIds_();
const container = Blockly.utils.xml.createElement("mutation");
container.setAttribute("name", this.name_);
container.setAttribute("functionid", this.functionId_);
if (this.imported_) container.setAttribute("imported", "true");
this.arguments_.forEach(function (arg) {
const argNode = Blockly.utils.xml.createElement("arg");
argNode.setAttribute("name", arg.name);
Expand Down Expand Up @@ -80,6 +83,8 @@ export const COMMON_FUNCTION_MIXIN = {
this.arguments_ = args;
this.name_ = xmlElement.getAttribute("name")!;

this.imported_ = xmlElement.getAttribute("imported") === "true";

this.restoreSavedFunctionId(xmlElement.getAttribute("functionid")!);
},

Expand All @@ -88,12 +93,14 @@ export const COMMON_FUNCTION_MIXIN = {
name: this.name_,
functionid: this.functionId_,
arguments: this.arguments_.slice(),
imported: this.imported_,
};
},

loadExtraState: function (this: CommonFunctionBlock, state: FunctionDefinitionExtraState) {
this.arguments_ = state.arguments.slice();
this.name_ = state.name;
this.imported_ = !!(state as any).imported;

this.restoreSavedFunctionId(state.functionid);
},
Expand Down
15 changes: 12 additions & 3 deletions pxtblocks/plugins/functions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,10 @@ export function flyoutCategory(workspace: Blockly.WorkspaceSvg) {
// label.setAttribute("text", Blockly.Msg[MsgKey.FUNCTION_FLYOUT_LABEL]);
// xmlList.push(label);

const addFunctionCallBlock = (name: string, args: { name: string; type: string; id: string }[]) => {
const addFunctionCallBlock = (
name: string,
args: { name: string; type: string; id: string }[]
): Element => {
const block = Blockly.utils.xml.createElement("block");
block.setAttribute("type", "function_call");
block.setAttribute("gap", "16");
Expand All @@ -461,6 +464,7 @@ export function flyoutCategory(workspace: Blockly.WorkspaceSvg) {
mutation.appendChild(argElement);
}
xmlList.push(block);
return block;
};

// Populate function call blocks from the current workspace
Expand All @@ -473,6 +477,7 @@ export function flyoutCategory(workspace: Blockly.WorkspaceSvg) {
if (program) {
program.refreshSymbols?.();

const globeIcon = "\uf0ac";
const currentFile = program.getAllWorkspaces().find(w => w.workspace === workspace)?.fileName || pxt.MAIN_BLOCKS;
const localNames = new Set(getAllFunctionDefinitionBlocks(workspace).map(f => f.getName().toLowerCase()));

Expand All @@ -492,10 +497,14 @@ export function flyoutCategory(workspace: Blockly.WorkspaceSvg) {
}

if (importedFunctions.length) {
xmlList.push(createFlyoutGroupLabel(`${file} functions`));
const label = createFlyoutGroupLabel(`${file} functions`, globeIcon);
label.setAttribute("web-icon-color", "#fff");
xmlList.push(label);

for (const func of importedFunctions) {
addFunctionCallBlock(func.name, func.arguments);
const block = addFunctionCallBlock(func.name, func.arguments);
const mutation = block.querySelector("mutation");
if (mutation) mutation.setAttribute("imported", "true");
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions tests/blocklycompiler-test/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,15 @@ async function blockTestAsync(name: string) {

chai.expect(res).to.not.be.undefined;

const compiledTs = res.source.trim().replace(/\s+/g, " ");
const compiledSource = res.outfiles[pxt.MAIN_TS];
const compiledTs = compiledSource.trim().replace(/\s+/g, " ");
const baselineTs = tsFile.trim().replace(/\s+/g, " ");

if (compiledTs !== baselineTs) {
console.log(compiledTs);
}

chai.expect(compiledTs).to.equal(baselineTs, "Compiled result did not match baseline: " + name + " " + res.source);
chai.expect(compiledTs).to.equal(baselineTs, "Compiled result did not match baseline: " + name + " " + compiledSource);
}

describe("blockly compiler", function () {
Expand Down
6 changes: 6 additions & 0 deletions theme/blockly-core.less
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ body.blocklyMinimalBody {
font-family: "Icons";
font-size: 19px;
}
// Fallback to ensure icon font applies even when labels are not wrapped in editable/noneditable text groups
text.semanticIcon {
font-family: "Icons";
font-style: normal;
font-weight: normal;
}
.blocklyEditableText>text.semanticIcon.inverted, .blocklyEditableField>text.semanticIcon.inverted {
fill: #000;
}
Expand Down
15 changes: 11 additions & 4 deletions webapp/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1470,12 +1470,19 @@ export class ProjectView
}

updateFileAsync(name: string, content: string, open?: boolean): Promise<void> {
const p = pkg.mainEditorPkg();
return p.setContentAsync(name, content)
const mainPkg = pkg.mainEditorPkg();
return mainPkg.setContentAsync(name, content)
.then(() => this.reloadHeaderAsync())
.then(() => {
if (open) this.setFile(p.lookupFile("this/" + name));
if (open) {
const reloadedPkg = pkg.mainEditorPkg();
const file = reloadedPkg.lookupFile("this/" + name);
if (file) {
if (pxteditor.isBlocks(file)) this.setSideFile(file);
else this.setFile(file);
}
}
})
.then(() => this.reloadHeaderAsync())
}

isSideDocExpanded(): boolean {
Expand Down