Skip to content

Commit 26dc0d9

Browse files
authored
Merge pull request #8 from kristerkari/feature/better-not-operator-support
Support not operator with platform, e.g. @media not ios
2 parents 3601b57 + 8b89cf5 commit 26dc0d9

File tree

3 files changed

+292
-5
lines changed

3 files changed

+292
-5
lines changed

src/__tests__/index.spec.js

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,285 @@ describe("media queries", () => {
629629
).toEqual({ a: 2 });
630630
});
631631

632+
it("should process media query with NOT operator and type", () => {
633+
expect(
634+
process({
635+
__mediaQueries: {
636+
"@media not print": [
637+
{
638+
inverse: true,
639+
type: "print",
640+
expressions: []
641+
}
642+
],
643+
"@media print": [
644+
{
645+
inverse: false,
646+
type: "print",
647+
expressions: []
648+
}
649+
]
650+
},
651+
a: 1,
652+
"@media not print": {
653+
a: 2
654+
},
655+
"@media print": {
656+
a: 3
657+
}
658+
})
659+
).toEqual({ a: 2 });
660+
});
661+
662+
it("should process media query with NOT and OR operators and type", () => {
663+
expect(
664+
process({
665+
__mediaQueries: {
666+
"@media not print, (orientation: landscape)": [
667+
{
668+
inverse: true,
669+
type: "print",
670+
expressions: []
671+
},
672+
{
673+
expressions: [
674+
{
675+
feature: "orientation",
676+
modifier: undefined,
677+
value: "landscape"
678+
}
679+
],
680+
inverse: false,
681+
type: "all"
682+
}
683+
],
684+
"@media print": [
685+
{
686+
inverse: false,
687+
type: "print",
688+
expressions: []
689+
}
690+
]
691+
},
692+
a: 1,
693+
"@media not print, (orientation: landscape)": {
694+
a: 2
695+
},
696+
"@media print": {
697+
a: 3
698+
}
699+
})
700+
).toEqual({ a: 2 });
701+
expect(
702+
process({
703+
__mediaQueries: {
704+
"@media not ios, (orientation: landscape)": [
705+
{
706+
inverse: true,
707+
type: "ios",
708+
expressions: []
709+
},
710+
{
711+
expressions: [
712+
{
713+
feature: "orientation",
714+
modifier: undefined,
715+
value: "landscape"
716+
}
717+
],
718+
inverse: false,
719+
type: "all"
720+
}
721+
],
722+
"@media print": [
723+
{
724+
inverse: false,
725+
type: "print",
726+
expressions: []
727+
}
728+
]
729+
},
730+
a: 1,
731+
"@media not ios, (orientation: landscape)": {
732+
a: 2
733+
},
734+
"@media print": {
735+
a: 3
736+
}
737+
})
738+
).toEqual({ a: 2 });
739+
expect(
740+
process({
741+
__mediaQueries: {
742+
"@media not ios, (orientation: portrait)": [
743+
{
744+
inverse: true,
745+
type: "ios",
746+
expressions: []
747+
},
748+
{
749+
expressions: [
750+
{
751+
feature: "orientation",
752+
modifier: undefined,
753+
value: "portrait"
754+
}
755+
],
756+
inverse: false,
757+
type: "all"
758+
}
759+
],
760+
"@media print": [
761+
{
762+
inverse: false,
763+
type: "print",
764+
expressions: []
765+
}
766+
]
767+
},
768+
a: 1,
769+
"@media not ios, (orientation: portrait)": {
770+
a: 2
771+
},
772+
"@media print": {
773+
a: 3
774+
}
775+
})
776+
).toEqual({ a: 1 });
777+
});
778+
779+
it("should process media query with NOT and AND operators and platform", () => {
780+
expect(
781+
process({
782+
__mediaQueries: {
783+
"@media android": [
784+
{
785+
inverse: false,
786+
type: "android",
787+
expressions: []
788+
}
789+
],
790+
"@media not ios and (orientation: landscape)": [
791+
{
792+
inverse: true,
793+
type: "ios",
794+
expressions: [
795+
{
796+
feature: "orientation",
797+
modifier: undefined,
798+
value: "landscape"
799+
}
800+
]
801+
}
802+
]
803+
},
804+
a: 1,
805+
"@media android": {
806+
a: 2
807+
},
808+
"@media not ios and (orientation: landscape)": {
809+
a: 3
810+
}
811+
})
812+
).toEqual({ a: 1 });
813+
expect(
814+
process({
815+
__mediaQueries: {
816+
"@media android": [
817+
{
818+
inverse: false,
819+
type: "android",
820+
expressions: []
821+
}
822+
],
823+
"@media not ios and (orientation: portrait)": [
824+
{
825+
inverse: true,
826+
type: "ios",
827+
expressions: [
828+
{
829+
feature: "orientation",
830+
modifier: undefined,
831+
value: "portrait"
832+
}
833+
]
834+
}
835+
]
836+
},
837+
a: 1,
838+
"@media android": {
839+
a: 2
840+
},
841+
"@media not ios and (orientation: portrait)": {
842+
a: 4
843+
}
844+
})
845+
).toEqual({ a: 4 });
846+
expect(
847+
process({
848+
__mediaQueries: {
849+
"@media android": [
850+
{
851+
inverse: false,
852+
type: "android",
853+
expressions: []
854+
}
855+
],
856+
"@media not android and (orientation: portrait)": [
857+
{
858+
inverse: true,
859+
type: "android",
860+
expressions: [
861+
{
862+
feature: "orientation",
863+
modifier: undefined,
864+
value: "portrait"
865+
}
866+
]
867+
}
868+
]
869+
},
870+
a: 1,
871+
"@media android": {
872+
a: 2
873+
},
874+
"@media not android and (orientation: portrait)": {
875+
a: 3
876+
}
877+
})
878+
).toEqual({ a: 3 });
879+
});
880+
881+
it("should process media query with not operator and platform", () => {
882+
expect(
883+
process({
884+
__mediaQueries: {
885+
"@media android": [
886+
{
887+
inverse: false,
888+
type: "android",
889+
expressions: []
890+
}
891+
],
892+
"@media not android": [
893+
{
894+
inverse: true,
895+
type: "android",
896+
expressions: []
897+
}
898+
]
899+
},
900+
a: 1,
901+
"@media android": {
902+
a: 2
903+
},
904+
"@media not android": {
905+
a: 3
906+
}
907+
})
908+
).toEqual({ a: 3 });
909+
});
910+
632911
it("should ignore non-matching media queries", () => {
633912
expect(
634913
process({

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export function process(obj) {
4747
const matchObject = getMatchObject();
4848

4949
mqKeys.forEach(key => {
50-
if (/^@media\s+(ios|android)/i.test(key)) {
50+
if (/^@media\s+(not\s+)?(ios|android)/i.test(key)) {
5151
matchObject.type = Platform.OS;
5252
} else {
5353
matchObject.type = "screen";

src/mediaquery.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ function matchQuery(query, values) {
3030
// equal for a match.
3131
var typeMatch = query.type === "all" || values.type === query.type;
3232

33-
// Quit early when `type` doesn't match, but take "not" into account.
34-
if ((typeMatch && inverse) || !(typeMatch || inverse)) {
35-
return false;
33+
if (query.expressions.length === 0) {
34+
// Quit early when `type` doesn't match, but take "not" into account.
35+
if ((typeMatch && inverse) || !(typeMatch || inverse)) {
36+
return false;
37+
}
3638
}
3739

3840
var expressionsMatch = query.expressions.every(function(expression) {
@@ -90,7 +92,13 @@ function matchQuery(query, values) {
9092
}
9193
});
9294

93-
return (expressionsMatch && !inverse) || (!expressionsMatch && inverse);
95+
const isMatch = typeMatch && expressionsMatch;
96+
97+
if (inverse) {
98+
return !isMatch;
99+
}
100+
101+
return isMatch;
94102
}
95103

96104
// -- Utilities ----------------------------------------------------------------

0 commit comments

Comments
 (0)