Making background the default x,y coordinates

Hello,
I want to make the background as the default x,y coordinates of any element nested within it whenever I create and move them inside of it. Like in the picture, I want the custom:electricityResource x and y become zero when I create or move it at the corner of the background. Also, I want to restrict creating and moving custom elements outside of the background. How can I achieve that?
Thanks…

Screenshot%20from%202019-09-16%2013-07-45

This is my exported diagram. The custom:electricityResource x and y are not 0.

<?xml version="1.0" encoding="UTF-8"?>
<custom:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:custom="http://custom.com" xmlns:customdi="http://customdi.com" xmlns:dc="http://dc.com" id="Definitions_1">
  <custom:modeler id="Modeler_1" isExecutable="false">
    <custom:background id="Background_1">
      <custom:electricityResource id="ElectricityResource_16jn66p" serviceStatus="true" enabled="true" />
    </custom:background>
  </custom:modeler>
  <customdi:CUSTOMDiagram id="CUSTOMDiagram_1">
    <customdi:CUSTOMPlane id="CUSTOMPlane_1" customElement="Modeler_1">
      <customdi:CUSTOMShape id="_CUSTOMShape_Background_2" customElement="Background_1">
        <dc:Bounds x="135" y="13" width="1100" height="750" />
      </customdi:CUSTOMShape>
      <customdi:CUSTOMShape id="ElectricityResource_16jn66p_di" customElement="ElectricityResource_16jn66p">
        <dc:Bounds x="138" y="16" width="36" height="36" />
      </customdi:CUSTOMShape>
    </customdi:CUSTOMPlane>
  </customdi:CUSTOMDiagram>
</custom:definitions>

This is my CustomUpdater.js file.

import {
  assign,
  forEach
} from 'min-dash';

import inherits from 'inherits';

import {
  remove as collectionRemove,
} from 'diagram-js/lib/util/Collections';

import {
  Label
} from 'diagram-js/lib/model';

import {
  is
} from '../../util/ModelUtil';

import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';

/**
 * A handler responsible for updating the underlying CUSTOM XML + DI
 * once changes on the diagram happen
 */
export default function CustomUpdater(
    eventBus, customFactory, translate) {

  CommandInterceptor.call(this, eventBus);

  this._customFactory = customFactory;
  this._translate = translate;

  var self = this;


  // CUSTOM + DI update //////////////////////


  // update parent
  function updateParent(e) {
    var context = e.context;

    self.updateParent(context.shape || context.oldParent);
  }

  function reverseUpdateParent(e) {
    var context = e.context;

    var element = context.shape;

        // oldParent is the (old) new parent, because we are undoing
        oldParent = context.parent || context.newParent;

    self.updateParent(element, oldParent);
  }

  this.executed([
    'shape.move',
    'shape.create',
    'shape.delete',
  ], ifBpmn(updateParent));

  this.reverted([
    'shape.move',
    'shape.create',
    'shape.delete',
  ], ifBpmn(reverseUpdateParent));

  /*
   * ## Updating Parent
   */
  function updateRoot(event) {
    var context = event.context,
        oldRoot = context.oldRoot,
        children = oldRoot.children;

    forEach(children, function(child) {
      if (is(child, 'custom:BaseElement')) {
        self.updateParent(child);
      }
    });
  }

  this.executed([ 'canvas.updateRoot' ], updateRoot);
  this.reverted([ 'canvas.updateRoot' ], updateRoot);


  // update bounds
  function updateBounds(e) {
    var shape = e.context.shape;

    if (!is(shape, 'custom:BaseElement')) {
      return;
    }

    self.updateBounds(shape);
  }

  this.executed([ 'shape.move', 'shape.create', 'shape.resize' ], ifBpmn(function(event) {

    // exclude labels because they're handled separately during shape.changed
    if (event.context.shape.type === 'label') {
      return;
    }

    updateBounds(event);
  }));

  this.reverted([ 'shape.move', 'shape.create', 'shape.resize' ], ifBpmn(function(event) {

    // exclude labels because they're handled separately during shape.changed
    if (event.context.shape.type === 'label') {
      return;
    }

    updateBounds(event);
  }));

  // Handle labels separately. This is necessary, because the label bounds have to be updated
  // every time its shape changes, not only on move, create and resize.
  eventBus.on('shape.changed', function(event) {
    if (event.element.type === 'label') {
      updateBounds({ context: { shape: event.element } });
    }
  });
}

inherits(CustomUpdater, CommandInterceptor);

CustomUpdater.$inject = [
  'eventBus',
  'customFactory',
  'translate'
];


// implementation //////////////////////

CustomUpdater.prototype.updateParent = function(element, oldParent) {

  // do not update label parent
  if (element instanceof Label) {
    return;
  }

  var parentShape = element.parent;

  var businessObject = element.businessObject,
      parentBusinessObject = parentShape && parentShape.businessObject,
      parentDi = parentBusinessObject && parentBusinessObject.di;

  this.updateSemanticParent(businessObject, parentBusinessObject);

  this.updateDiParent(businessObject.di, parentDi);
};

CustomUpdater.prototype.updateBounds = function(shape) {

  var di = shape.businessObject.di;

  var target = (shape instanceof Label) ? this._getLabel(di) : di;

  var bounds = target.bounds;

  if (!bounds) {
    bounds = this._customFactory.createDiBounds();
    target.set('bounds', bounds);
  }

  assign(bounds, {
    x: shape.x,
    y: shape.y,
    width: shape.width,
    height: shape.height
  });
};

CustomUpdater.prototype.updateDiParent = function(di, parentDi) {

  if (parentDi && !is(parentDi, 'customdi:CUSTOMPlane')) {
    parentDi = parentDi.$parent;
  }

  if (di.$parent === parentDi) {
    return;
  }

  var planeElements = (parentDi || di.$parent).get('planeElement');

  if (parentDi) {
    planeElements.push(di);
    di.$parent = parentDi;
  } else {
    collectionRemove(planeElements, di);
    di.$parent = null;
  }
};

CustomUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {

  var containment,
      translate = this._translate;

  if (businessObject.$parent === newParent) {
    return;
  }

  if (is(businessObject, 'custom:Modeler')) {
    if (newParent) {

      if (is(newParent, 'custom:Lane')) {
        do {

          // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer)
          newParent = newParent.$parent.$parent;
        } while (is(newParent, 'custom:Lane'));

      }
    }

    containment = 'modelerShapes';

  } 

  if (!containment) {
    throw new Error(translate(
      'no parent for {element} in {parent}',
      {
        element: businessObject.id,
        parent: newParent.id
      }
    ));
  }

  var children;

  if (businessObject.$parent) {

    // remove from old parent
    children = businessObject.$parent.get(containment);
    collectionRemove(children, businessObject);
  }

  if (!newParent) {
    businessObject.$parent = null;
  } else {

    // add to new parent
    children = newParent.get(containment);
    children.push(businessObject);
    businessObject.$parent = newParent;
  }
};


// helpers //////////////////////

CustomUpdater.prototype._getLabel = function(di) {
  if (!di.label) {
    di.label = this._customFactory.createDiLabel();
  }

  return di.label;
};


/**
 * Make sure the event listener is only called
 * if the touched element is a CUSTOM element.
 *
 * @param  {Function} fn
 * @return {Function} guarded function
 */
function ifBpmn(fn) {

  return function(event) {

    var context = event.context,
        element = context.shape;

    if (is(element, 'custom:BaseElement')) {
      fn(event);
    }
  };
}

To restrict any modeling actions, you can use the rules module. Check out the sample RulesProvider to implement the rules yourself.