Exemple #1
0
 def test_groups(self):
     fl = {'ws': ' ', 'nl': '\n'}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['.a', ',', '.b'], 0).parse(sc)
     for i in [
         (['&', '.scope', ' ', 'a'], '.a.scope a,\n.b.scope a'),
         (['.scope', '&', ' ', 'a'], '.scope.a a,\n.scope.b a'),
         (['.scope', ' ', 'a', '&'], '.scope a.a,\n.scope a.b'),
         (['>', '&', '.scope', ' ', 'a'], ' > .a.scope a,\n > .b.scope a'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
     sc.current = Identifier(['.next'], 0).parse(sc)
     sc.push()
     sc.current = Identifier(['.c', ',', '.d'], 0).parse(sc)
     id = Identifier(['.deep'], 0)
     self.assertEqual(
         id.parse(sc).fmt(fl), '.a .next .c .deep,\n'
         '.b .next .c .deep,\n'
         '.a .next .d .deep,\n'
         '.b .next .d .deep')
     self.assertEqual(
         id.raw(), '.a% %.next% %.c% %.deep%'
         '.b% %.next% %.c% %.deep%'
         '.a% %.next% %.d% %.deep%'
         '.b% %.next% %.d% %.deep')
Exemple #2
0
 def test_groups(self):
     fl = {'ws': ' '}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['.a', ',', '.b'], 0).parse(sc)
     for i in [
         (['&', '.scope', ' ', 'a'], '.a.scope a, .b.scope a'),
         (['.scope', '&', ' ', 'a'], '.scope.a a, .scope.b a'),
         (['.scope', ' ', 'a', '&'], '.scope a.a, .scope a.b'),
         (['>', '&', '.scope', ' ', 'a'], ' > .a.scope a, > .b.scope a'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
     sc.current = Identifier(['.next'], 0).parse(sc)
     sc.push()
     sc.current = Identifier(['.c', ',', '.d'], 0).parse(sc)
     id = Identifier(['.deep'], 0)
     self.assertEqual(id.parse(sc).fmt(fl), '.a .next .c .deep, '
                      '.a .next .d .deep, '
                      '.b .next .c .deep, '
                      '.b .next .d .deep')
     self.assertEqual(id.raw(), '.a% %.next% %.c% %.deep%.a%'
                                ' %.next% %.d% %.deep%.b% %.next%'
                                ' %.c% %.deep%.b% %.next% %.d% %.deep')
Exemple #3
0
 def test_media(self):
     fl = {'ws': ' '}
     sc = Scope()
     sc.push()
     sc.current = Identifier(
         ['@media', ' ', 'screen', ',', 'projection'], 0).parse(sc)
     self.assertEqual(sc.current.fmt(fl), '@media screen,projection')
     for i in [
         (['html'], 'html'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
Exemple #4
0
 def test_media(self):
     fl = {'ws': ' ', 'nl': '\n'}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['@media', ' ', 'screen', ',', 'projection'],
                             0).parse(sc)
     self.assertEqual(sc.current.fmt(fl), '@media screen,projection')
     for i in [
         (['html'], 'html'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
Exemple #5
0
 def test_basic(self):
     fl = {'ws': ' '}
     for i in [
         ([], ''),
         (['.scope', ' ', 'a'], '.scope a'),
         (['a', ' ', '.scope'], 'a .scope'),
         (['a', '.scope'], 'a.scope'),
         (['a', '>', 'p', '>', 'h2'], 'a > p > h2'),
         (['a', '~', 'p', '+', 'h2'], 'a ~ p + h2'),
         (['*', 'html'], '* html'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(None).fmt(fl), r, i)
Exemple #6
0
 def test_basic(self):
     fl = {'ws': ' ', 'nl': '\n'}
     for i in [
         ([], ''),
         (['.scope', ' ', 'a'], '.scope a'),
         (['a', ' ', '.scope'], 'a .scope'),
         (['a', '.scope'], 'a.scope'),
         (['a', '>', 'p', '>', 'h2'], 'a > p > h2'),
         (['a', '~', 'p', '+', 'h2'], 'a ~ p + h2'),
         (['*', 'html'], '* html'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(None).fmt(fl), r, i)
Exemple #7
0
 def test_scope(self):
     fl = {'ws': ' '}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['.current'], 0).parse(sc)
     for i in [
         (['.scope', ' ', 'a'], '.current .scope a'),
         (['a', ' ', '.scope'], '.current a .scope'),
         (['a', '.scope'], '.current a.scope'),
         (['a', '>', 'p', '>', 'h2'], '.current a > p > h2'),
         (['a', '~', 'p', '+', 'h2'], '.current a ~ p + h2'),
         (['>', 'p', '+', 'h2'], '.current > p + h2'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
Exemple #8
0
 def test_scope(self):
     fl = {'ws': ' ', 'nl': '\n'}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['.current'], 0).parse(sc)
     for i in [
         (['.scope', ' ', 'a'], '.current .scope a'),
         (['a', ' ', '.scope'], '.current a .scope'),
         (['a', '.scope'], '.current a.scope'),
         (['a', '>', 'p', '>', 'h2'], '.current a > p > h2'),
         (['a', '~', 'p', '+', 'h2'], '.current a ~ p + h2'),
         (['>', 'p', '+', 'h2'], '.current > p + h2'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
Exemple #9
0
 def test_combinators(self):
     fl = {'ws': ' '}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['.current'], 0).parse(sc)
     for i in [
         (['&', '.scope', ' ', 'a'], '.current.scope a'),
         (['.scope', '&', ' ', 'a'], '.scope.current a'),
         (['.scope', ' ', 'a', '&'], '.scope a.current'),
         (['&', '>', '.scope', ' ', 'a'], '.current > .scope a'),
         (['.span', '&', '.scope', ' ', 'a', '&'],
          '.span.current.scope a.current'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
     sc.push()
     sc.current = Identifier(['&', '.next'], 0).parse(sc)
     id = Identifier(['&', '.top'], 0)
     self.assertEqual(id.parse(sc).fmt(fl), '.current.next.top')
Exemple #10
0
 def test_combinators(self):
     fl = {'ws': ' ', 'nl': '\n'}
     sc = Scope()
     sc.push()
     sc.current = Identifier(['.current'], 0).parse(sc)
     for i in [
         (['&', '.scope', ' ', 'a'], '.current.scope a'),
         (['.scope', '&', ' ', 'a'], '.scope.current a'),
         (['.scope', ' ', 'a', '&'], '.scope a.current'),
         (['&', '>', '.scope', ' ', 'a'], '.current > .scope a'),
         (['.span', '&', '.scope', ' ', 'a',
           '&'], '.span.current.scope a.current'),
     ]:
         t, r = i
         id = Identifier(t, 0)
         self.assertEqual(id.parse(sc).fmt(fl), r, i)
     sc.push()
     sc.current = Identifier(['&', '.next'], 0).parse(sc)
     id = Identifier(['&', '.top'], 0)
     self.assertEqual(id.parse(sc).fmt(fl), '.current.next.top')
Exemple #11
0
 def parse(self, scope):
     """Parse block node.
     args:
         scope (Scope): Current scope
     raises:
         SyntaxError
     returns:
         self
     """
     if not self.parsed:
         scope.push()
         self.name, inner = self.tokens
         scope.current = self.name
         scope.real.append(self.name)
         if not self.name.parsed:
             self.name.parse(scope)
         if not inner:
             inner = []
         inner = list(utility.flatten([p.parse(scope) for p in inner if p]))
         self.parsed = []
         self.inner = []
         if not hasattr(self, "inner_media_queries"):
             self.inner_media_queries = []
         for p in inner:
             if p is not None:
                 if isinstance(p, Block):
                     if len(scope) == 2 and p.tokens[1] is not None:
                         p_is_mediaquery = p.name.tokens[0] == '@media'
                         # Inner block @media ... { ... } is a nested media
                         # query. But double-nested media queries have to be
                         # removed and marked as well. While parsing ".foo",
                         # both nested "@media print" and double-nested
                         # "@media all" will be handled as we have to
                         # re-arrange the scope and block layout quite a bit:
                         #
                         #   .foo {
                         #       @media print {
                         #           color: blue;
                         #           @media screen { font-size: 12em; }
                         #       }
                         #   }
                         #
                         # Expected result:
                         #
                         #   @media print {
                         #       .foo { color: blue; }
                         #   }
                         #   @media print and screen {
                         #       .foo { font-size: 12 em; }
                         #   }
                         append_list = []
                         reparse_p = False
                         for child in p.tokens[1]:
                             if isinstance(child, Block) and child.name.raw(
                             ).startswith("@media"):
                                 # Remove child from the nested media query, it will be re-added to
                                 # the parent with 'merged' media query (see above example).
                                 p.tokens[1].remove(child)
                                 if p_is_mediaquery:  # Media query inside a & block
                                     # Double-nested media query found. We remove it from 'p' and add
                                     # it to this block with a new 'name'.
                                     reparse_p = True
                                     part_a = p.name.tokens[2:][0][0][0]
                                     part_b = child.name.tokens[2:][0][0]
                                     new_ident_tokens = [
                                         '@media', ' ',
                                         [
                                             part_a, (' ', 'and', ' '),
                                             part_b
                                         ]
                                     ]
                                     # Parse child again with new @media $BLA {} part
                                     child.tokens[0] = Identifier(
                                         new_ident_tokens)
                                     child.parsed = None
                                     child = child.parse(scope)
                                 else:
                                     child.block_name = p.name
                                 append_list.append(child)
                             if reparse_p:
                                 p.parsed = None
                                 p = p.parse(scope)
                         if not p_is_mediaquery and not append_list:
                             self.inner.append(p)
                         else:
                             append_list.insert(
                                 0, p
                             )  # This media query should occur before it's children
                             for media_query in append_list:
                                 self.inner_media_queries.append(
                                     media_query)
                         # NOTE(saschpe): The code is not recursive but we hope that people
                         # wont use triple-nested media queries.
                     else:
                         self.inner.append(p)
                 else:
                     self.parsed.append(p)
         if self.inner_media_queries:
             # Nested media queries, we have to remove self from scope and
             # push all nested @media ... {} blocks.
             scope.remove_block(self, index=-2)
             for mb in self.inner_media_queries:
                 # New inner block with current name and media block contents
                 if hasattr(mb, 'block_name'):
                     cb_name = mb.block_name
                 else:
                     cb_name = self.tokens[0]
                 cb = Block([cb_name, mb.tokens[1]]).parse(scope)
                 # Replace inner block contents with new block
                 new_mb = Block([mb.tokens[0], [cb]]).parse(scope)
                 self.inner.append(new_mb)
                 scope.add_block(new_mb)
         scope.real.pop()
         scope.pop()
     return self