Which event can trigger before custom menu provider?

I have written one custom StartEvent Menu provider and its kernel code is below:

  getPopupMenuEntries(element) {
    const self = this;
    const {translate} = this
    return function (entries) {
      if (isAny(element, ["bpmn:StartEvent"])) {
        entries = {
          ...entries,
          "add-registry-start-event": {
            label: translate("Registry Start Event"),
            className: "bpmn-icon-start-event-message",
            action: async function () {
              const modeler = document.$modeler
              const moddle = modeler.get("moddle");
              const flowableEventType = moddle.create('flowable:EventType', {
                'xmlns:flowable': "http://flowable.org/bpmn"
              })
              flowableEventType.body = '4444444'
              let extensionElements = moddle.create('bpmn:ExtensionElements', {
                values: [flowableEventType]
              })
              const shape = self.replaceElement(element, { type: 'bpmn:StartEvent' });
              shape.businessObject.$attrs['isRSE'] = 'true'
              shape.businessObject.extensionElements = extensionElements
              extensionElements.$parent = shape
              console.log('click shape: ', shape)
              // debugger
              return shape;
            }
          }
        };
      }
      return entries;
    };
  }

When I change event type from timer Start Event, I need to render my own custom element shape and its kernel code is below.

  drawShape(parentGfx, element) {
    const shape = this.bpmnRenderer.drawShape(parentGfx, element);
    console.log('drawShape: ', element)
    if (isRegistryStartEvent(element)) {
      console.log('draw RSE')
      var defaultFillColor = this.config && this.config.defaultFillColor,
        defaultStrokeColor = this.config && this.config.defaultStrokeColor,
        defaultLabelColor = this.config && this.config.defaultLabelColor;
      var attrs = {
        fill: getFillColor(element, defaultFillColor),
        stroke: getStrokeColor(element, defaultStrokeColor)
      };
      var semantic = getSemantic(element);
      if (!semantic.isInterrupting) {
        attrs = {
          strokeDasharray: '6',
          strokeLinecap: 'round',
          fill: getFillColor(element, defaultFillColor),
          stroke: getStrokeColor(element, defaultStrokeColor)
        };
      }
      var circle = this.createMessageEventPath(parentGfx, element, attrs);
      this.renderMessageEventContent(element, parentGfx);
      return circle;
    }
    return shape;
  }

  function isRegistryStartEvent(element) {
    const judge = element.businessObject.$attrs && !!element.businessObject.$attrs['isRSE']
    return judge
  }

And my render process needs to identify the ‘RSE’ tag and draw the right path. But there is one problem my render process runs earlier than the menu Provider and it leads to the wrong path will be rendered. So how will I resolve this?
Thank you.

Hi @tcguoxing ,

I see you are setting the extension elements directly on the the shape. Other components will not be notified of this change. Does it render correctly if you change the element afterwards, e.g. by moving it?

You can try updating the extensionElements via the updateModdleProperties handler.

    commandStack.execute('element.updateModdleProperties', {
      element,
      moddleElement: businuessObject,
      properties: { extensionElements }
    });

This will trigger an element changed event and should then also trigger a re-render with your renderer.

Hope this helps!

Thanks for your reply.
I have found it renders incorrectly when I move the element. Where should I add these codes? Is there any detailed example?
Best regards

Depending on your problem, you’ll need to append the following code to “add-registry-start-event”

const Modeling = this.bpmnModeler.get("modeling");
Modeling.updateModdleProperties(element, moddleElement, properties)

He can update element extension attributes, at the same time the trigger element. UpdateModdleProperties.
This is how I use it in my code

const modeling = modeler.get("modeling");
modeling.updateModdleProperties(element, element.businessObject, element.businessObject.extensionElements)

Hope this helps you

Yes, it works. Thank you a lot.