@@ -369,22 +369,25 @@ export default class DevTools {
369369 /**
370370 * A much nicer way of laying out the blocks into columns
371371 */
372- doCleanUp ( e ) {
372+ doCleanUp ( e , dataId ) {
373373 let workspace = this . utils . getWorkspace ( ) ;
374374 if ( e ) {
375375 e . cancelBubble = true ;
376376 e . preventDefault ( ) ;
377377 this . hidePopups ( workspace ) ;
378- setTimeout ( ( ) => this . doCleanUp ( ) , 0 ) ;
378+ setTimeout ( ( ) => this . doCleanUp ( undefined , dataId ) , 0 ) ;
379379 return ;
380380 }
381381
382+ let makeSpaceForBlock = dataId && workspace . getBlockById ( dataId ) ;
383+ makeSpaceForBlock = makeSpaceForBlock && makeSpaceForBlock . getRootBlock ( ) ;
384+
382385 UndoGroup . startUndoGroup ( workspace ) ;
383386
384387 let result = this . getOrderedTopBlockColumns ( true ) ;
385388 let columns = result . cols ;
386389 let orphanCount = result . orphans . blocks . length ;
387- if ( orphanCount > 0 ) {
390+ if ( orphanCount > 0 && ! dataId ) {
388391 let message = this . msg ( "orphaned" , {
389392 count : orphanCount ,
390393 } ) ;
@@ -406,15 +409,17 @@ export default class DevTools {
406409 let maxWidth = 0 ;
407410
408411 for ( const block of column . blocks ) {
412+ let extraWidth = block === makeSpaceForBlock ? 380 : 0 ;
413+ let extraHeight = block === makeSpaceForBlock ? 480 : 72 ;
409414 let xy = block . getRelativeToSurfaceXY ( ) ;
410415 if ( cursorX - xy . x !== 0 || cursorY - xy . y !== 0 ) {
411416 block . moveBy ( cursorX - xy . x , cursorY - xy . y ) ;
412417 }
413418 let heightWidth = block . getHeightWidth ( ) ;
414- cursorY += heightWidth . height + 72 ;
419+ cursorY += heightWidth . height + extraHeight ;
415420
416421 let maxWidthWithComments = maxWidths [ block . id ] || 0 ;
417- maxWidth = Math . max ( maxWidth , Math . max ( heightWidth . width , maxWidthWithComments ) ) ;
422+ maxWidth = Math . max ( maxWidth , Math . max ( heightWidth . width + extraWidth , maxWidthWithComments ) ) ;
418423 }
419424
420425 cursorX += maxWidth + 96 ;
@@ -446,7 +451,7 @@ export default class DevTools {
446451 }
447452 }
448453
449- if ( unusedLocals . length > 0 ) {
454+ if ( unusedLocals . length > 0 && ! dataId ) {
450455 const unusedCount = unusedLocals . length ;
451456 let message = this . msg ( "unused-var" , {
452457 count : unusedCount ,
@@ -1229,12 +1234,15 @@ export default class DevTools {
12291234 }
12301235
12311236 /**
1232- * Initiates a drag event for all block stacks expect those in the set of ids.
1237+ * Initiates a drag event for all block stacks except those in the set of ids.
12331238 * But why? - Because we know all the ids of the existing stacks before we paste / duplicate - so we can find the
12341239 * new stack by excluding all the known ones.
12351240 * @param ids Set of previously known ids
12361241 */
12371242 beginDragOfNewBlocksNotInIDs ( ids ) {
1243+ if ( ! this . addon . settings . get ( "enablePasteBlocksAtMouse" ) ) {
1244+ return ;
1245+ }
12381246 let wksp = this . utils . getWorkspace ( ) ;
12391247 let topBlocks = wksp . getTopBlocks ( ) ;
12401248 for ( const block of topBlocks ) {
@@ -1297,6 +1305,9 @@ export default class DevTools {
12971305 if ( document . activeElement . tagName === "INPUT" ) {
12981306 return ;
12991307 }
1308+ // todo: if (!this.addon.settings.get("enableCtrlLeftRightNav")) {
1309+ // return;
1310+ // }
13001311 if ( this . isScriptEditor ( ) ) {
13011312 this . utils . navigationHistory . goBack ( ) ;
13021313 } else if ( this . isCostumeEditor ( ) ) {
@@ -1312,6 +1323,9 @@ export default class DevTools {
13121323 if ( document . activeElement . tagName === "INPUT" ) {
13131324 return ;
13141325 }
1326+ // todo: if (!this.addon.settings.get("enableCtrlLeftRightNav")) {
1327+ // return;
1328+ // }
13151329 if ( this . isScriptEditor ( ) ) {
13161330 this . utils . navigationHistory . goForward ( ) ;
13171331 } else if ( this . isCostumeEditor ( ) ) {
@@ -1363,12 +1377,14 @@ export default class DevTools {
13631377 contextMenu . insertAdjacentHTML (
13641378 "beforeend" ,
13651379 `
1366- <div class="${ this . addon . tab . scratchClass ( "context-menu_menu-item" , {
1367- others : [ "react-contextmenu-item" , "s3devSTT" ] ,
1368- } ) } " role="menuitem"
1369- tabindex="-1" aria-disabled="false" style="border-top: 1px solid hsla(0, 0%, 0%, 0.15);"><span>${ this . m (
1370- "top"
1371- ) } </span></div>
1380+ <div class="${ this . addon . tab . scratchClass (
1381+ "context-menu_menu-item" ,
1382+ "context-menu_menu-item-bordered" ,
1383+ {
1384+ others : [ "react-contextmenu-item" , "s3devSTT" ] ,
1385+ }
1386+ ) } " role="menuitem"
1387+ tabindex="-1" aria-disabled="false"><span>${ this . m ( "top" ) } </span></div>
13721388 <div class="${ this . addon . tab . scratchClass ( "context-menu_menu-item" , {
13731389 others : [ "react-contextmenu-item" , "s3devSTT" ] ,
13741390 } ) } " role="menuitem"
@@ -1394,27 +1410,32 @@ export default class DevTools {
13941410 return ;
13951411 }
13961412 if ( isBackground ) {
1413+ let cleanupPlus = this . addon . settings . get ( "enableCleanUpPlus" ) ;
1414+
13971415 let nodes = blocklyContextMenu . children ;
13981416 const realBlockly = await this . addon . tab . traps . getBlockly ( ) ;
1399- for ( const node of nodes ) {
1400- if ( node . textContent === realBlockly . Msg . CLEAN_UP ) {
1401- node . remove ( ) ;
1402- break ;
1417+ if ( cleanupPlus ) {
1418+ for ( const node of nodes ) {
1419+ if ( node . textContent === realBlockly . Msg . CLEAN_UP ) {
1420+ node . remove ( ) ;
1421+ break ;
1422+ }
14031423 }
14041424 }
1405- blocklyContextMenu . insertAdjacentHTML (
1406- "beforeend" ,
1407- `
1408- <div id="s3devCleanUp" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1409- <div class="goog-menuitem-content" style="user-select: none;">${ this . m (
1410- "clean-plus"
1411- ) } </div>
1412- </div>
1413- <div id="s3devPaste" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none;">
1414- <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "paste" ) } </div>
1415- </div>
1416- `
1417- ) ;
1425+ let html = cleanupPlus
1426+ ? `
1427+ <div id="s3devCleanUp" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1428+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "clean-plus" ) } </div>
1429+ </div>
1430+ `
1431+ : "" ;
1432+
1433+ html += `
1434+ <div id="s3devPaste" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none;">
1435+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "paste" ) } </div>
1436+ </div>
1437+ ` ;
1438+ blocklyContextMenu . insertAdjacentHTML ( "beforeend" , html ) ;
14181439 } else {
14191440 let wksp = this . utils . getWorkspace ( ) ;
14201441 let block = wksp . getBlockById ( dataId ) ;
@@ -1453,22 +1474,19 @@ export default class DevTools {
14531474 blocklyContextMenu . insertAdjacentHTML (
14541475 "beforeend" ,
14551476 `
1456- <div id="s3devCopy" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1457- <div class="goog-menuitem-content" style="user-select: none;">${ this . m (
1458- "copy-all"
1459- ) } </div>
1460- </div>
1461- <div id="s3devCopyBlock" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none;">
1462- <div class="goog-menuitem-content" style="user-select: none;">${ this . m (
1463- "copy-block"
1464- ) } </div>
1465- </div>
1466- <div id="s3devCutBlock" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none;">
1467- <div class="goog-menuitem-content" style="user-select: none;">${ this . m (
1468- "cut-block"
1469- ) } </div>
1470- </div>
1471- `
1477+ <div id="s3devMakeSpace" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1478+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "make-space" ) } </div>
1479+ </div>
1480+ <div id="s3devCopy" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1481+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "copy-all" ) } </div>
1482+ </div>
1483+ <div id="s3devCopyBlock" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none;">
1484+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "copy-block" ) } </div>
1485+ </div>
1486+ <div id="s3devCutBlock" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none;">
1487+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "cut-block" ) } </div>
1488+ </div>
1489+ `
14721490 ) ;
14731491 }
14741492
@@ -1477,12 +1495,12 @@ export default class DevTools {
14771495 blocklyContextMenu . insertAdjacentHTML (
14781496 "beforeend" ,
14791497 `
1480- <div id="s3devReplaceAllVars" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1481- <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "swap" , {
1482- var : block . getCategory ( ) === "data" ? this . m ( "variables" ) : this . m ( "lists" ) ,
1483- } ) } </div>
1484- </div>
1485- `
1498+ <div id="s3devReplaceAllVars" class="goog-menuitem s3dev-mi" role="menuitem" style="user-select: none; border-top: 1px solid hsla(0, 0%, 0%, 0.15);">
1499+ <div class="goog-menuitem-content" style="user-select: none;">${ this . m ( "swap" , {
1500+ var : block . getCategory ( ) === "data" ? this . m ( "variables" ) : this . m ( "lists" ) ,
1501+ } ) } </div>
1502+ </div>
1503+ `
14861504 ) ;
14871505 this . selVarID = block . getVars ( ) [ 0 ] ;
14881506 }
@@ -1498,6 +1516,10 @@ export default class DevTools {
14981516 if ( copyDiv ) {
14991517 copyDiv . addEventListener ( "click" , ( ...e ) => this . doCleanUp ( ...e ) ) ;
15001518 }
1519+ copyDiv = blocklyContextMenu . querySelector ( "div#s3devMakeSpace" ) ;
1520+ if ( copyDiv ) {
1521+ copyDiv . addEventListener ( "click" , ( e ) => this . doCleanUp ( e , dataId ) ) ;
1522+ }
15011523 copyDiv = blocklyContextMenu . querySelector ( "div#s3devCopy" ) ;
15021524 if ( copyDiv ) {
15031525 copyDiv . addEventListener ( "click" , ( ...e ) => eventCopyClick ( ...e ) ) ;
@@ -1622,6 +1644,10 @@ export default class DevTools {
16221644 return ;
16231645 }
16241646
1647+ // todo: if (!this.addon.settings.get("enableBlockInjector")) {
1648+ // return;
1649+ // }
1650+
16251651 e . cancelBubble = true ;
16261652 e . preventDefault ( ) ;
16271653
@@ -1681,6 +1707,10 @@ export default class DevTools {
16811707 return ;
16821708 }
16831709
1710+ if ( ! this . addon . settings . get ( "enableMiddleClickFinder" ) ) {
1711+ return ;
1712+ }
1713+
16841714 let w = this . utils . getWorkspace ( ) ;
16851715 let dataId = blockSvg . getAttribute ( "data-id" ) ;
16861716 let block = w . getBlockById ( dataId ) ;
0 commit comments