flexysnap 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/annotateWireframe.js +3 -3
- package/src/wireframeComparison.js +125 -12
package/package.json
CHANGED
package/src/annotateWireframe.js
CHANGED
|
@@ -61,9 +61,9 @@ async function annotateWireframeFile(wireframeFile, screenshotFile) {
|
|
|
61
61
|
image: { fill: 'rgba(70, 180, 120, 0.4)', stroke: '#2EBC6F' },
|
|
62
62
|
text: { fill: 'rgba(50, 130, 190, 0.4)', stroke: '#0066CC' },
|
|
63
63
|
error: { fill: 'rgba(211, 47, 47, 0.4)', stroke: '#D32F2F' },
|
|
64
|
-
missing: { fill: 'rgba(233, 30, 140, 0.4)', stroke: '#
|
|
65
|
-
extra: { fill: 'rgba(156, 39, 176, 0.4)', stroke: '#
|
|
66
|
-
shift: { fill: 'rgba(121, 85, 72, 0.4)', stroke: '#
|
|
64
|
+
missing: { fill: 'rgba(233, 30, 140, 0.4)', stroke: '#D32F2F' },
|
|
65
|
+
extra: { fill: 'rgba(156, 39, 176, 0.4)', stroke: '#D32F2F' },
|
|
66
|
+
shift: { fill: 'rgba(121, 85, 72, 0.4)', stroke: '#D32F2F' }
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
function determineColorKey(obj, defaultKey) {
|
|
@@ -11,16 +11,16 @@ function calculateBoundingBoxDistance(rect1, rect2) {
|
|
|
11
11
|
Math.abs(rect1.bottom - rect2.bottom));
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function
|
|
14
|
+
function pairByBoundingBox(currentIndices, baselineIndices, currentElements, baselineElements) {
|
|
15
15
|
const pairings = [];
|
|
16
|
-
|
|
17
|
-
for (
|
|
18
|
-
for (
|
|
16
|
+
|
|
17
|
+
for (const currentIndex of currentIndices) {
|
|
18
|
+
for (const baselineIndex of baselineIndices) {
|
|
19
19
|
const distance = calculateBoundingBoxDistance(
|
|
20
20
|
currentElements[currentIndex].boundingRect,
|
|
21
21
|
baselineElements[baselineIndex].boundingRect
|
|
22
22
|
);
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
pairings.push({
|
|
25
25
|
currentIndex,
|
|
26
26
|
baselineIndex,
|
|
@@ -34,7 +34,7 @@ function createPairings(currentElements, baselineElements) {
|
|
|
34
34
|
const usedCurrentIndices = new Set();
|
|
35
35
|
const usedBaselineIndices = new Set();
|
|
36
36
|
const matchedPairs = [];
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
for (const pairing of pairings) {
|
|
39
39
|
if (!usedCurrentIndices.has(pairing.currentIndex) && !usedBaselineIndices.has(pairing.baselineIndex)) {
|
|
40
40
|
usedCurrentIndices.add(pairing.currentIndex);
|
|
@@ -42,21 +42,134 @@ function createPairings(currentElements, baselineElements) {
|
|
|
42
42
|
matchedPairs.push(pairing);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
const unmatchedCurrent = [];
|
|
47
|
+
for (const currentIndex of currentIndices) {
|
|
48
|
+
if (!usedCurrentIndices.has(currentIndex)) {
|
|
49
|
+
unmatchedCurrent.push(currentIndex);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const unmatchedBaseline = [];
|
|
54
|
+
for (const baselineIndex of baselineIndices) {
|
|
55
|
+
if (!usedBaselineIndices.has(baselineIndex)) {
|
|
56
|
+
unmatchedBaseline.push(baselineIndex);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
matchedPairs,
|
|
62
|
+
unmatchedCurrent,
|
|
63
|
+
unmatchedBaseline
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createPairings(currentElements, baselineElements) {
|
|
68
|
+
const currentIndices = currentElements.map((_, index) => index);
|
|
69
|
+
const baselineIndices = baselineElements.map((_, index) => index);
|
|
70
|
+
|
|
71
|
+
return pairByBoundingBox(currentIndices, baselineIndices, currentElements, baselineElements);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function buildTextIndexMap(texts) {
|
|
75
|
+
const map = new Map();
|
|
76
|
+
texts.forEach((textElement, index) => {
|
|
77
|
+
const key = textElement.text;
|
|
78
|
+
if (!map.has(key)) {
|
|
79
|
+
map.set(key, []);
|
|
80
|
+
}
|
|
81
|
+
map.get(key).push(index);
|
|
82
|
+
});
|
|
83
|
+
return map;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function createTextPairings(currentTexts, baselineTexts) {
|
|
87
|
+
const currentTextMap = buildTextIndexMap(currentTexts);
|
|
88
|
+
const baselineTextMap = buildTextIndexMap(baselineTexts);
|
|
89
|
+
|
|
90
|
+
const usedCurrentIndices = new Set();
|
|
91
|
+
const usedBaselineIndices = new Set();
|
|
92
|
+
const matchedPairs = [];
|
|
93
|
+
|
|
94
|
+
for (const [text, currentIndices] of currentTextMap) {
|
|
95
|
+
const baselineIndices = baselineTextMap.get(text);
|
|
96
|
+
if (currentIndices.length === 1 && baselineIndices && baselineIndices.length === 1) {
|
|
97
|
+
const currentIndex = currentIndices[0];
|
|
98
|
+
const baselineIndex = baselineIndices[0];
|
|
99
|
+
matchedPairs.push({
|
|
100
|
+
currentIndex,
|
|
101
|
+
baselineIndex,
|
|
102
|
+
distance: 0
|
|
103
|
+
});
|
|
104
|
+
usedCurrentIndices.add(currentIndex);
|
|
105
|
+
usedBaselineIndices.add(baselineIndex);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
for (const [text, currentIndices] of currentTextMap) {
|
|
110
|
+
const baselineIndices = baselineTextMap.get(text) || [];
|
|
111
|
+
const remainingCurrentIndices = currentIndices.filter(index => !usedCurrentIndices.has(index));
|
|
112
|
+
const remainingBaselineIndices = baselineIndices.filter(index => !usedBaselineIndices.has(index));
|
|
113
|
+
|
|
114
|
+
if (remainingCurrentIndices.length > 0 && remainingBaselineIndices.length > 0) {
|
|
115
|
+
const result = pairByBoundingBox(
|
|
116
|
+
remainingCurrentIndices,
|
|
117
|
+
remainingBaselineIndices,
|
|
118
|
+
currentTexts,
|
|
119
|
+
baselineTexts
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
for (const pairing of result.matchedPairs) {
|
|
123
|
+
matchedPairs.push(pairing);
|
|
124
|
+
usedCurrentIndices.add(pairing.currentIndex);
|
|
125
|
+
usedBaselineIndices.add(pairing.baselineIndex);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const remainingCurrentIndices = [];
|
|
131
|
+
for (let i = 0; i < currentTexts.length; i++) {
|
|
132
|
+
if (!usedCurrentIndices.has(i)) {
|
|
133
|
+
remainingCurrentIndices.push(i);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const remainingBaselineIndices = [];
|
|
138
|
+
for (let i = 0; i < baselineTexts.length; i++) {
|
|
139
|
+
if (!usedBaselineIndices.has(i)) {
|
|
140
|
+
remainingBaselineIndices.push(i);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (remainingCurrentIndices.length > 0 && remainingBaselineIndices.length > 0) {
|
|
145
|
+
const result = pairByBoundingBox(
|
|
146
|
+
remainingCurrentIndices,
|
|
147
|
+
remainingBaselineIndices,
|
|
148
|
+
currentTexts,
|
|
149
|
+
baselineTexts
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
for (const pairing of result.matchedPairs) {
|
|
153
|
+
matchedPairs.push(pairing);
|
|
154
|
+
usedCurrentIndices.add(pairing.currentIndex);
|
|
155
|
+
usedBaselineIndices.add(pairing.baselineIndex);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
46
159
|
const unmatchedCurrent = [];
|
|
47
|
-
for (let i = 0; i <
|
|
160
|
+
for (let i = 0; i < currentTexts.length; i++) {
|
|
48
161
|
if (!usedCurrentIndices.has(i)) {
|
|
49
162
|
unmatchedCurrent.push(i);
|
|
50
163
|
}
|
|
51
164
|
}
|
|
52
|
-
|
|
165
|
+
|
|
53
166
|
const unmatchedBaseline = [];
|
|
54
|
-
for (let i = 0; i <
|
|
167
|
+
for (let i = 0; i < baselineTexts.length; i++) {
|
|
55
168
|
if (!usedBaselineIndices.has(i)) {
|
|
56
169
|
unmatchedBaseline.push(i);
|
|
57
170
|
}
|
|
58
171
|
}
|
|
59
|
-
|
|
172
|
+
|
|
60
173
|
return {
|
|
61
174
|
matchedPairs,
|
|
62
175
|
unmatchedCurrent,
|
|
@@ -112,7 +225,7 @@ function replaceDigitsWithPlaceholder(text) {
|
|
|
112
225
|
}
|
|
113
226
|
|
|
114
227
|
function compareTexts(baselineTexts, currentTexts, options) {
|
|
115
|
-
const {matchedPairs, unmatchedCurrent, unmatchedBaseline} =
|
|
228
|
+
const {matchedPairs, unmatchedCurrent, unmatchedBaseline} = createTextPairings(currentTexts, baselineTexts);
|
|
116
229
|
|
|
117
230
|
for (const pairing of matchedPairs) {
|
|
118
231
|
const baselineText = baselineTexts[pairing.baselineIndex];
|