Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { getRoot, types } from "mobx-state-tree";
import { FF_DEV_3391, isFF } from "../../utils/feature-flags";
import { BaseTag } from "../TagBase";
import { SNAP_TO_PIXEL_MODE } from "../../components/ImageView/Image";
 
const ControlBase = types
  .model({
    ...(isFF(FF_DEV_3391)
      ? {
          id: types.identifier,
          name: types.string,
        }
      : {
          name: types.identifier,
        }),
    smart: true,
    smartonly: false,
    isControlTag: true,
  })
  .volatile(() => ({
    snapMode: SNAP_TO_PIXEL_MODE.EDGE,
  }))
  .views((self) => ({
    // historically two "types" were used and we should keep that backward compatibility:
    // 1. name of control tag for describing labeled region;
    // 2. label type to attach corresponding value to this region.
    // usually they are the same, but with some problems:
    // a. for hypertextlabels label type should be "htmllabels";
    // original type are overwritten by Tree#buildData with real tag name,
    // so _type was introduced to contain desired result type;
    // b. but for textarea they differ from each other: "textarea" and "text".
    // so now there is simple way to distinguish and overwrite them via two methods:
    get resultType() {
      return self.type;
    },
 
    // and
    get valueType() {
      return self.type;
    },
 
    get toNameTag() {
      return self.annotation.names.get(self.toname);
    },
 
    selectedValues() {
      throw new Error("Control tag needs to implement selectedValues method in views");
    },
 
    get result() {
      return self.annotation.results.find((r) => r.from_name === self);
    },
 
    getSnappedPoint(point) {
      if (self.snap === "pixel") {
        return self.toNameTag.snapPointToPixel(point, self.snapMode);
      }
      return point;
    },
 
    get smartEnabled() {
      const smart = self.smart ?? false;
      const autoAnnotation = getRoot(self)?.autoAnnotation ?? false;
 
      // @todo: Not sure why smartonly ignores autoAnnotation; It was like this from the beginning
      return (autoAnnotation && smart) || self.smartonly || false;
    },
  }));
 
export default types.compose(ControlBase, BaseTag);