Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Stable11.2] Cherry pick various fixes over to minecraft stable #10347

Open
wants to merge 4 commits into
base: stable11.2
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions pxtblocks/builtins/loops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import * as Blockly from "blockly";
import { installBuiltinHelpInfo, setBuiltinHelpInfo, setHelpResources } from "../help";
import { setDuplicateOnDrag } from "../plugins/duplicateOnDrag";

export function initLoops() {
const msg = Blockly.Msg;
Expand Down Expand Up @@ -104,6 +105,7 @@ export function initLoops() {
}
}
};
setDuplicateOnDrag(pxtControlsForId, "VAR");

// controls_simple_for
const controlsSimpleForId = "controls_simple_for";
Expand Down Expand Up @@ -313,6 +315,7 @@ export function initLoops() {
);
}
};
setDuplicateOnDrag(pxtControlsForOfId, "VAR");

// controls_for_of
const controlsForOfId = "controls_for_of";
Expand Down
26 changes: 23 additions & 3 deletions pxtblocks/composableMutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,29 @@ export function initExpandableBlock(info: pxtc.BlocksInfo, b: Blockly.Block, def
Blockly.Events.disable();

try {
const nb = Blockly.Xml.domToBlock(shadow, b.workspace);
if (nb) {
input.connection.connect(nb.outputConnection);
let newBlock: Blockly.Block;
if (!b.initialized) {
// use domToBlockInternal so that we don't trigger a render while
// the block is still being initialized
newBlock = Blockly.Xml.domToBlockInternal(shadow, b.workspace);

// we don't know at this time whether the parent block is an insertion marker
// or not. doing this check lets us clean up the block in the case that it is,
// though we get an annoying flicker
setTimeout(() => {
if (newBlock.isInsertionMarker()) {
Blockly.Events.disable();
newBlock.dispose();
Blockly.Events.enable();
}
})
}
else {
newBlock = Blockly.Xml.domToBlock(shadow, b.workspace);
}

if (newBlock) {
input.connection.connect(newBlock.outputConnection);
}
} catch (e) { }

Expand Down
7 changes: 6 additions & 1 deletion pxtblocks/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { initOnStart } from "./builtins/misc";
import { initContextMenu } from "./contextMenu";
import { renderCodeCard } from "./codecardRenderer";
import { FieldDropdown } from "./fields/field_dropdown";
import { setDraggableShadowBlocks, setDuplicateOnDragStrategy } from "./plugins/duplicateOnDrag";
import { setDraggableShadowBlocks, setDuplicateOnDrag, setDuplicateOnDragStrategy } from "./plugins/duplicateOnDrag";
import { applyPolyfills } from "./polyfills";


Expand Down Expand Up @@ -259,6 +259,11 @@ function initBlock(block: Blockly.Block, info: pxtc.BlocksInfo, fn: pxtc.SymbolI
} else {
i.setCheck("Variable");
}

});

comp.handlerArgs.forEach(arg => {
setDuplicateOnDrag(block.type, "HANDLER_DRAG_PARAM_" + arg.name);
});
}
else {
Expand Down
4 changes: 2 additions & 2 deletions pxtblocks/plugins/duplicateOnDrag/connectionChecker.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as Blockly from "blockly";
import { isDuplicateOnDragBlock } from "./duplicateOnDrag";
import { shouldDuplicateOnDrag } from "./duplicateOnDrag";


const OPPOSITE_TYPE: number[] = [];
Expand All @@ -16,7 +16,7 @@ export class DuplicateOnDragConnectionChecker extends Blockly.ConnectionChecker

const replacedBlock = b.targetBlock();

if (replacedBlock && isDuplicateOnDragBlock(replacedBlock)) return false;
if (replacedBlock && shouldDuplicateOnDrag(replacedBlock)) return false;

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions pxtblocks/plugins/duplicateOnDrag/dragStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import * as Blockly from "blockly";

import { DUPLICATE_ON_DRAG_MUTATION_KEY, isAllowlistedShadow } from "./duplicateOnDrag";
import { DUPLICATE_ON_DRAG_MUTATION_KEY, isAllowlistedShadow, shouldDuplicateOnDrag } from "./duplicateOnDrag";
import eventUtils = Blockly.Events;
import Coordinate = Blockly.utils.Coordinate;
import dom = Blockly.utils.dom;
Expand Down Expand Up @@ -160,7 +160,7 @@ export class DuplicateOnDragStrategy implements Blockly.IDragStrategy {

const mutation = this.block.mutationToDom?.();

if (mutation?.getAttribute(DUPLICATE_ON_DRAG_MUTATION_KEY)?.toLowerCase() === "true" || (isAllowlistedShadow(this.block) && isShadow)) {
if (shouldDuplicateOnDrag(this.block)) {
const output = this.block.outputConnection;

if (!output?.targetConnection) return;
Expand Down
70 changes: 68 additions & 2 deletions pxtblocks/plugins/duplicateOnDrag/duplicateOnDrag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,87 @@ import * as Blockly from "blockly";
export const DUPLICATE_ON_DRAG_MUTATION_KEY = "duplicateondrag";

let draggableShadowAllowlist: string[];
let duplicateRefs: DuplicateOnDragRef[];

export function isDuplicateOnDragBlock(block: Blockly.Block) {
return block.mutationToDom?.()?.getAttribute(DUPLICATE_ON_DRAG_MUTATION_KEY)?.toLowerCase() === "true";
interface DuplicateOnDragRef {
parentBlockType: string;
inputName?: string;
childBlockType?: string;
}

export function setDraggableShadowBlocks(ids: string[]) {
draggableShadowAllowlist = ids;
}

/**
* Configures duplicate on drag for a block's child inputs
*
* @param parentBlockType The type of the parent block
* @param inputName The value input to duplicate blocks on when dragged. If not
* specified, all child value inputs will be duplicated
* @param childBlockType The type of the child block to be duplicated. If not specified,
* any block attached to the input will be duplicated on drag
* regardless of type
*/
export function setDuplicateOnDrag(parentBlockType: string, inputName?: string, childBlockType?: string) {
if (!duplicateRefs) {
duplicateRefs = [];
}

const existing = duplicateRefs.some(ref => ref.parentBlockType === parentBlockType && ref.inputName === inputName && ref.childBlockType === childBlockType);
if (existing) {
return;
}

duplicateRefs.push({
parentBlockType,
inputName,
childBlockType
});
}

export function isAllowlistedShadow(block: Blockly.Block) {
if (draggableShadowAllowlist) {
if (draggableShadowAllowlist.indexOf(block.type) !== -1) {
return true;
}
}
return false;
}

export function shouldDuplicateOnDrag(block: Blockly.Block) {
if (block.isShadow() && isAllowlistedShadow(block)) {
return true;
}

if (duplicateRefs) {
const parent = block.outputConnection?.targetBlock();

if (parent) {
const refs = duplicateRefs.filter(r => r.parentBlockType === parent.type);

for (const ref of refs) {
if (ref && (!ref.childBlockType || ref.childBlockType === block.type)) {
if (ref.inputName) {
const targetConnection = block.outputConnection.targetConnection;
if (targetConnection.getParentInput().name === ref.inputName) {
return true;
}
}
else {
return true;
}
}
}
}
}

if (block.mutationToDom) {
const mutation = block.mutationToDom();
if (mutation?.getAttribute(DUPLICATE_ON_DRAG_MUTATION_KEY)?.toLowerCase() === "true") {
return true;
}
}

return false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { MsgKey } from "../msg";
import { FunctionManager } from "../functionManager";
import { COLLAPSE_IMAGE_DATAURI } from "../svgs";
import { ArgumentReporterBlock } from "./argumentReporterBlocks";
import { DUPLICATE_ON_DRAG_MUTATION_KEY } from "../../duplicateOnDrag";
import { DUPLICATE_ON_DRAG_MUTATION_KEY, setDuplicateOnDrag } from "../../duplicateOnDrag";

interface FunctionDefinitionMixin extends CommonFunctionMixin {
createArgumentReporter_(arg: FunctionArgument): ArgumentReporterBlock;
Expand Down Expand Up @@ -205,6 +205,8 @@ Blockly.Blocks[FUNCTION_DEFINITION_BLOCK_TYPE] = {
},
};

setDuplicateOnDrag(FUNCTION_DEFINITION_BLOCK_TYPE);


function editFunctionCallback(block: CommonFunctionBlock) {
// Edit can come from either the function definition or a function call.
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5963,11 +5963,12 @@ document.addEventListener("DOMContentLoaded", async () => {
pxt.blocks.showBlockIdInTooltip = true;
}

initGitHubDb();

pxt.perf.measureStart("setAppTarget");
pkg.setupAppTarget((window as any).pxtTargetBundle);

initGitHubDb();

// DO NOT put any async code before this line! The serviceworker must be initialized before
// the window load event fires
appcache.init(() => theEditor.reloadEditor());
Expand Down
Loading