| 3648 | } |
| 3649 | |
| 3650 | cloneWith(other) { |
| 3651 | var additions = []; |
| 3652 | for (var id in other.filters) { |
| 3653 | var status = this.addable(other.filters[id]); |
| 3654 | // status is true, false or null. if it's null we don't fail this |
| 3655 | // clone nor do we add the filter. |
| 3656 | if (status === false) { |
| 3657 | return false; |
| 3658 | } |
| 3659 | if (status === true) { |
| 3660 | // Adding the filter will override another value. |
| 3661 | additions.push(other.filters[id]); |
| 3662 | } |
| 3663 | } |
| 3664 | |
| 3665 | // Adding the other filters doesn't make this filterset invalid, but it |
| 3666 | // doesn't add anything to it either. |
| 3667 | if (!additions.length) { |
| 3668 | return null; |
| 3669 | } |
| 3670 | |
| 3671 | // We can successfully add all filters. Now clone the filterset and add the |
| 3672 | // new rules. |
| 3673 | var clone = new CartoCSS.Tree.Filterset(); |
| 3674 | |
| 3675 | // We can add the rules that are already present without going through the |
| 3676 | // add function as a Filterset is always in it's simplest canonical form. |
| 3677 | for (id in this.filters) { |
| 3678 | clone.filters[id] = this.filters[id]; |
| 3679 | } |
| 3680 | |
| 3681 | // Only add new filters that actually change the filter. |
| 3682 | while (id = additions.shift()) { |
| 3683 | clone.add(id); |
| 3684 | } |
| 3685 | |
| 3686 | return clone; |
| 3687 | } |
| 3688 | |
| 3689 | addable(filter) { |
| 3690 | var key = filter.key.toString(), |