(att1: string, att2: string, resultIsMutation: boolean, pool?: AttributePool|null)
| 475 | * @returns {string} |
| 476 | */ |
| 477 | export const composeAttributes = (att1: string, att2: string, resultIsMutation: boolean, pool?: AttributePool|null): string => { |
| 478 | // att1 and att2 are strings like "*3*f*1c", asMutation is a boolean. |
| 479 | // Sometimes attribute (key,value) pairs are treated as attribute presence |
| 480 | // information, while other times they are treated as operations that |
| 481 | // mutate a set of attributes, and this affects whether an empty value |
| 482 | // is a deletion or a change. |
| 483 | // Examples, of the form (att1Items, att2Items, resultIsMutation) -> result |
| 484 | // ([], [(bold, )], true) -> [(bold, )] |
| 485 | // ([], [(bold, )], false) -> [] |
| 486 | // ([], [(bold, true)], true) -> [(bold, true)] |
| 487 | // ([], [(bold, true)], false) -> [(bold, true)] |
| 488 | // ([(bold, true)], [(bold, )], true) -> [(bold, )] |
| 489 | // ([(bold, true)], [(bold, )], false) -> [] |
| 490 | // pool can be null if att2 has no attributes. |
| 491 | if ((!att1) && resultIsMutation) { |
| 492 | // In the case of a mutation (i.e. composing two exportss), |
| 493 | // an att2 composed with an empy att1 is just att2. If att1 |
| 494 | // is part of an attribution string, then att2 may remove |
| 495 | // attributes that are already gone, so don't do this optimization. |
| 496 | return att2; |
| 497 | } |
| 498 | if (!att2) return att1; |
| 499 | return AttributeMap.fromString(att1, pool).updateFromString(att2, !resultIsMutation).toString(); |
| 500 | }; |
| 501 | |
| 502 | |
| 503 | /** |
no test coverage detected