@@ -18,11 +18,11 @@ import type {BlockSvg} from './block_svg.js';
1818import * as common from './common.js' ;
1919import { ComponentManager } from './component_manager.js' ;
2020import { config } from './config.js' ;
21+ import * as constants from './constants.js' ;
2122import * as eventUtils from './events/utils.js' ;
2223import type { IDeleteArea } from './interfaces/i_delete_area.js' ;
2324import type { IDragTarget } from './interfaces/i_drag_target.js' ;
2425import type { RenderedConnection } from './rendered_connection.js' ;
25- import * as blocks from './serialization/blocks.js' ;
2626import type { Coordinate } from './utils/coordinate.js' ;
2727import type { WorkspaceSvg } from './workspace_svg.js' ;
2828import * as renderManagement from './render_management.js' ;
@@ -43,6 +43,16 @@ interface CandidateConnection {
4343 radius : number ;
4444}
4545
46+ /**
47+ * An error message to throw if the block created by createMarkerBlock_ is
48+ * missing any components.
49+ */
50+ const DUPLICATE_BLOCK_ERROR =
51+ 'The insertion marker ' +
52+ 'manager tried to create a marker but the result is missing %1. If ' +
53+ 'you are using a mutator, make sure your domToMutation method is ' +
54+ 'properly defined.' ;
55+
4656/**
4757 * Class that controls updates to connections during drags. It is primarily
4858 * responsible for finding the closest eligible connection and highlighting or
@@ -222,16 +232,48 @@ export class InsertionMarkerManager {
222232 * @returns The insertion marker that represents the given block.
223233 */
224234 private createMarkerBlock ( sourceBlock : BlockSvg ) : BlockSvg {
235+ const imType = sourceBlock . type ;
236+
225237 eventUtils . disable ( ) ;
226238 let result : BlockSvg ;
227239 try {
228- const blockJson = blocks . save ( sourceBlock ) ;
229- if ( ! blockJson ) {
230- throw new Error ( 'Failed to serialize source block.' ) ;
240+ result = this . workspace . newBlock ( imType ) ;
241+ result . setInsertionMarker ( true ) ;
242+ if ( sourceBlock . saveExtraState ) {
243+ const state = sourceBlock . saveExtraState ( ) ;
244+ if ( state && result . loadExtraState ) {
245+ result . loadExtraState ( state ) ;
246+ }
247+ } else if ( sourceBlock . mutationToDom ) {
248+ const oldMutationDom = sourceBlock . mutationToDom ( ) ;
249+ if ( oldMutationDom && result . domToMutation ) {
250+ result . domToMutation ( oldMutationDom ) ;
251+ }
252+ }
253+ // Copy field values from the other block. These values may impact the
254+ // rendered size of the insertion marker. Note that we do not care about
255+ // child blocks here.
256+ for ( let i = 0 ; i < sourceBlock . inputList . length ; i ++ ) {
257+ const sourceInput = sourceBlock . inputList [ i ] ;
258+ if ( sourceInput . name === constants . COLLAPSED_INPUT_NAME ) {
259+ continue ; // Ignore the collapsed input.
260+ }
261+ const resultInput = result . inputList [ i ] ;
262+ if ( ! resultInput ) {
263+ throw new Error ( DUPLICATE_BLOCK_ERROR . replace ( '%1' , 'an input' ) ) ;
264+ }
265+ for ( let j = 0 ; j < sourceInput . fieldRow . length ; j ++ ) {
266+ const sourceField = sourceInput . fieldRow [ j ] ;
267+ const resultField = resultInput . fieldRow [ j ] ;
268+ if ( ! resultField ) {
269+ throw new Error ( DUPLICATE_BLOCK_ERROR . replace ( '%1' , 'a field' ) ) ;
270+ }
271+ resultField . setValue ( sourceField . getValue ( ) ) ;
272+ }
231273 }
232- result = blocks . append ( blockJson , this . workspace ) as BlockSvg ;
233274
234- result . setInsertionMarker ( true ) ;
275+ result . setCollapsed ( sourceBlock . isCollapsed ( ) ) ;
276+ result . setInputsInline ( sourceBlock . getInputsInline ( ) ) ;
235277
236278 result . initSvg ( ) ;
237279 result . getSvgRoot ( ) . setAttribute ( 'visibility' , 'hidden' ) ;
0 commit comments