@@ -63,6 +63,10 @@ import { serverSyncStore } from "./sync";
6363import { setDifference , setUnion } from "./shim" ;
6464import { breakCyclesMutable , findCycles } from "@webstudio-is/project-build" ;
6565import { $awareness , $selectedPage , selectInstance } from "./awareness" ;
66+ import {
67+ findClosestContainer ,
68+ findClosestInstanceMatchingFragment ,
69+ } from "./matcher" ;
6670
6771export const updateWebstudioData = ( mutate : ( data : WebstudioData ) => void ) => {
6872 serverSyncStore . createTransaction (
@@ -419,63 +423,6 @@ export const findClosestDroppableComponentIndex = ({
419423 return - 1 ;
420424} ;
421425
422- const findClosestDroppableTarget = (
423- metas : Map < string , WsComponentMeta > ,
424- instances : Instances ,
425- instanceSelector : InstanceSelector ,
426- insertConstraints : InsertConstraints
427- ) : undefined | DroppableTarget => {
428- const droppableIndex = findClosestDroppableComponentIndex ( {
429- metas,
430- constraints : insertConstraints ,
431- instances,
432- instanceSelector,
433- // We want to always allow dropping into the root.
434- // For example when body has text content
435- // and the only viable option is to insert at the end.
436- allowInsertIntoTextContainer : instanceSelector . length === 1 ,
437- } ) ;
438- if ( droppableIndex === - 1 ) {
439- return ;
440- }
441-
442- const dropTargetParentInstance = instances . get (
443- instanceSelector [ droppableIndex + 1 ]
444- ) ;
445- let dropTargetInstance = instances . get ( instanceSelector [ droppableIndex ] ) ;
446- // skip collection item when inserting something and go straight into collection instance
447- if (
448- dropTargetInstance === undefined &&
449- dropTargetParentInstance ?. component === collectionComponent
450- ) {
451- instanceSelector = instanceSelector . slice ( 1 ) ;
452- dropTargetInstance = dropTargetParentInstance ;
453- }
454- if ( dropTargetInstance === undefined ) {
455- return ;
456- }
457-
458- if ( droppableIndex === 0 ) {
459- return {
460- parentSelector : instanceSelector ,
461- position : "end" ,
462- } ;
463- }
464-
465- const dropTargetSelector = instanceSelector . slice ( droppableIndex ) ;
466- if ( dropTargetInstance === undefined ) {
467- return ;
468- }
469- const lastChildInstanceId = instanceSelector [ droppableIndex - 1 ] ;
470- const lastChildPosition = dropTargetInstance . children . findIndex (
471- ( child ) => child . type === "id" && child . value === lastChildInstanceId
472- ) ;
473- return {
474- parentSelector : dropTargetSelector ,
475- position : lastChildPosition + 1 ,
476- } ;
477- } ;
478-
479426export const insertInstanceChildrenMutable = (
480427 data : WebstudioData ,
481428 children : Instance [ "children" ] ,
@@ -1613,16 +1560,50 @@ export const findClosestInsertable = (
16131560 }
16141561 const metas = $registeredComponentMetas . get ( ) ;
16151562 const instances = $instances . get ( ) ;
1616- const rootInstanceIds = fragment . children
1617- . filter ( ( child ) => child . type === "id" )
1618- . map ( ( child ) => child . value ) ;
1619- const newInstances = new Map (
1620- fragment . instances . map ( ( instance ) => [ instance . id , instance ] )
1621- ) ;
1622- return findClosestDroppableTarget (
1563+ const closestContainerIndex = findClosestContainer ( {
16231564 metas,
16241565 instances,
16251566 instanceSelector,
1626- computeInstancesConstraints ( metas , newInstances , rootInstanceIds )
1567+ } ) ;
1568+ if ( closestContainerIndex === - 1 ) {
1569+ return ;
1570+ }
1571+ let insertableIndex = findClosestInstanceMatchingFragment ( {
1572+ metas,
1573+ instances,
1574+ instanceSelector : instanceSelector . slice ( closestContainerIndex ) ,
1575+ fragment,
1576+ } ) ;
1577+ if ( insertableIndex === - 1 ) {
1578+ return ;
1579+ }
1580+
1581+ // adjust with container lookup
1582+ insertableIndex = insertableIndex + closestContainerIndex ;
1583+ const parentSelector = instanceSelector . slice ( insertableIndex ) ;
1584+ if ( insertableIndex === 0 ) {
1585+ return {
1586+ parentSelector,
1587+ position : "end" ,
1588+ } ;
1589+ }
1590+ const instance = instances . get ( instanceSelector [ insertableIndex ] ) ;
1591+ if ( instance === undefined ) {
1592+ return ;
1593+ }
1594+ // skip collection item when inserting something and go straight into collection instance
1595+ if ( instance ?. component === collectionComponent && insertableIndex === 1 ) {
1596+ return {
1597+ parentSelector,
1598+ position : "end" ,
1599+ } ;
1600+ }
1601+ const lastChildInstanceId = instanceSelector [ insertableIndex - 1 ] ;
1602+ const lastChildPosition = instance . children . findIndex (
1603+ ( child ) => child . type === "id" && child . value === lastChildInstanceId
16271604 ) ;
1605+ return {
1606+ parentSelector,
1607+ position : lastChildPosition + 1 ,
1608+ } ;
16281609} ;
0 commit comments