Skip to content
This repository was archived by the owner on May 5, 2022. It is now read-only.

Improved support for media queries #11

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
*.iml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import com.vaadin.sass.internal.parser.MediaListImpl;
import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.InputSource;
import org.w3c.css.sac.LexicalUnit;
Expand Down Expand Up @@ -168,7 +169,7 @@ public void importStyle(String uri, SACMediaList media,

@Override
public void startMedia(SACMediaList media) throws CSSException {
MediaNode node = new MediaNode(media);
MediaNode node = new MediaNode((MediaListImpl)media);
nodeStack.peek().appendChild(node);
nodeStack.push(node);
}
Expand Down
32 changes: 31 additions & 1 deletion src/main/java/com/vaadin/sass/internal/parser/Interpolation.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,16 @@ public LexicalUnitImpl getContainedValue() {
* @return The value of the evaluated expression, a SassListItem.
*/
public SassListItem replaceInterpolation() {
if (expression instanceof LexicalUnitImpl) {
if (expression instanceof SassList) {
StringBuilder buffer = new StringBuilder();
if (appendLexicalItems((SassList)expression, buffer)) {
return new LexicalUnitImpl(getLineNumber(), getLineNumber(),
LexicalUnitImpl.SAC_IDENT, buffer.toString());

} else {
return expression;
}
} else if (expression instanceof LexicalUnitImpl) {
String unquotedString = expression.unquotedString();
return new LexicalUnitImpl(getLineNumber(), getLineNumber(),
LexicalUnitImpl.SAC_IDENT, unquotedString);
Expand All @@ -139,6 +148,27 @@ public SassListItem replaceInterpolation() {
}
}

private boolean appendLexicalItems(SassList list, StringBuilder buffer) {
boolean first = true;
for (SassListItem sassListItem : list) {
if (first) {
first = false;
} else {
buffer.append(list.getSeparator());
}
if ((sassListItem instanceof LexicalUnitImpl)) {
buffer.append(((LexicalUnitImpl)sassListItem).unquotedString());
} else if (sassListItem instanceof SassList) {
if (!appendLexicalItems((SassList)sassListItem, buffer)) {
return false;
}
} else {
return false;
}
}
return true;
}

@Override
public boolean containsVariable() {
return expression.containsVariable();
Expand Down
71 changes: 41 additions & 30 deletions src/main/java/com/vaadin/sass/internal/parser/MediaListImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
package com.vaadin.sass.internal.parser;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.w3c.css.sac.SACMediaList;

Expand All @@ -37,64 +39,73 @@ public class MediaListImpl implements SACMediaList, Serializable {
*
*/
private static final long serialVersionUID = 1L;
String[] array = new String[10];
int current;
private List<SassListItem> items = new ArrayList<SassListItem>();

public List<SassListItem> getSassListItems() {
return items;
}

public SassListItem getSassListItem(int index) {
if ((index < 0) || (index >= getLength())) {
return null;
}
return items.get(index);
}

@Override
public int getLength() {
return current;
return items.size();
}

@Override
public String item(int index) {
if ((index < 0) || (index >= current)) {
if ((index < 0) || (index >= getLength())) {
return null;
}
return array[index];
return items.get(index).toString();
}

void addItem(String medium) {
public void addItem(String medium) {
if (medium.equals("all")) {
array[0] = "all";
current = 1;
return;
items.clear();
}
for (int i = 0; i < current; i++) {
if (medium.equals(array[i])) {
return;
}
addItem(new StringItem(medium));
}

public void addAllItems(Iterable<SassListItem> items) {
for (SassListItem item : items) {
addItem(item);
}
if (current == array.length) {
String[] old = array;
array = new String[current + current];
System.arraycopy(old, 0, array, 0, current);
}

public void addItem(SassListItem item) {
if (!items.contains(item)) {
items.add(item);
}
array[current++] = medium;
}

/**
* Returns a string representation of this object.
*/
@Override
public String toString() {
switch (current) {
switch (items.size()) {
case 0:
return "";
case 1:
return array[0];
return items.get(0).toString();
default:
boolean not_done = true;
int i = 0;
StringBuffer buf = new StringBuffer(50);
do {
buf.append(array[i++]);
if (i == current) {
not_done = false;
boolean first = true;
StringBuilder buffer = new StringBuilder(50);
for (SassListItem item : items) {
if (first) {
first = false;
} else {
buf.append(", ");
buffer.append(", ");
}
} while (not_done);
return buf.toString();
buffer.append(item.toString());
}
return buffer.toString();
}
}
}
37 changes: 28 additions & 9 deletions src/main/java/com/vaadin/sass/internal/tree/MediaNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@

package com.vaadin.sass.internal.tree;

import java.util.Collection;
import java.util.Collections;

import com.vaadin.sass.internal.ScssContext;
import com.vaadin.sass.internal.parser.*;
import org.w3c.css.sac.SACMediaList;

import com.vaadin.sass.internal.ScssContext;
import java.util.*;

public class MediaNode extends Node {
public class MediaNode extends Node implements IVariableNode {
private static final long serialVersionUID = 2502097081457509523L;

SACMediaList media;
MediaListImpl media;

public MediaNode(SACMediaList media) {
public MediaNode(MediaListImpl media) {
super();
this.media = media;
}
Expand All @@ -42,7 +41,7 @@ public SACMediaList getMedia() {
return media;
}

public void setMedia(SACMediaList media) {
public void setMedia(MediaListImpl media) {
this.media = media;
}

Expand All @@ -58,6 +57,7 @@ public String toString() {

@Override
public Collection<Node> traverse(ScssContext context) {
replaceVariables(context);
traverseChildren(context);
return Collections.singleton((Node) this);
}
Expand All @@ -69,7 +69,7 @@ private String buildString(BuildStringStrategy strategy, boolean indent) {
if (i > 0) {
builder.append(", ");
}
builder.append(media.item(i));
builder.append(media.getSassListItem(i).buildString(strategy));
}
}
builder.append(" {\n");
Expand All @@ -91,6 +91,25 @@ private String buildString(BuildStringStrategy strategy, boolean indent) {
return builder.toString();
}

public void wrapInBlockNode(BlockNode blockNode) {
for (Node child : new ArrayList<Node>(getChildren())) {
blockNode.appendChild(child);
}
appendChild(blockNode);
}

@Override
public void replaceVariables(ScssContext context) {

MediaListImpl newMedia = new MediaListImpl();
for (SassListItem sassListItem : media.getSassListItems()) {
StringInterpolationSequence interpolationSequence = new StringInterpolationSequence(Collections.singletonList(sassListItem));
StringInterpolationSequence replacedSequence = interpolationSequence.replaceVariables(context);
newMedia.addAllItems(replacedSequence.getItems());
}
media = newMedia;
}

@Override
public MediaNode copy() {
return new MediaNode(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.vaadin.sass.internal.ScssStylesheet;
import com.vaadin.sass.internal.selector.Selector;
import com.vaadin.sass.internal.tree.BlockNode;
import com.vaadin.sass.internal.tree.MediaNode;
import com.vaadin.sass.internal.tree.Node;

/**
Expand Down Expand Up @@ -65,6 +66,10 @@ public static Collection<Node> traverse(ScssContext context, BlockNode node) {
((BlockNode) child).setParentSelectors(node
.getSelectorList());
result.addAll(child.traverse(context));
} else if (child instanceof MediaNode) {
BlockNode mediaParentNode = new BlockNode(node.getSelectorList());
((MediaNode)child).wrapInBlockNode(mediaParentNode);
result.addAll(child.traverse(context));
} else {
Collection<Node> childTraversed = child
.traverse(context);
Expand Down
35 changes: 32 additions & 3 deletions src/main/javacc/com/vaadin/sass/internal/Parser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -962,10 +962,36 @@ void media() :
void mediaDirective() :
{}
{
debuggingDirective() | LOOKAHEAD(2) styleRule() | skipUnknownRule() | contentDirective()
styleRuleOrDeclarationOrNestedProperties() | includeDirective() | contentDirective()
}

void mediaStatement(MediaListImpl ml) :
{
List<SassListItem> seq;
List<SassListItem> list = new ArrayList<SassListItem>();
}
{
(seq = mediaSeq() { list.addAll(seq); } (< COMMA > ( <S> )* seq = mediaSeq() { list.addAll(seq); })* ( <S> )*)
{
ml.addAllItems(list);
} | plainMediaStatement(ml)
}

List<SassListItem> mediaSeq() :
{
List<SassListItem> items = new ArrayList<SassListItem>();
Interpolation s;
}
{

(s = interpolation() {items.add(s);})
{
return items;
}

}

void plainMediaStatement(MediaListImpl ml) :
{
Token t;
}
Expand All @@ -975,7 +1001,10 @@ void mediaStatement(MediaListImpl ml) :
// loop over comma separated parts, add each to ml
while ((t.kind != LBRACE) && (t.kind != EOF) && (t.kind != SEMICOLON)) {
StringBuffer s = new StringBuffer();
s.append(getToken(0).image);
String image = getToken(0).image;
if (!image.equals("@media")) {
s.append(image);
}
while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF) && (t.kind != SEMICOLON)) {
s.append(t.image);
getNextToken();
Expand Down Expand Up @@ -1879,7 +1908,7 @@ Interpolation interpolation() :
SassListItem expression;
}
{
n = < START_INTERPOLATION> { line = n.beginLine; column = n.beginColumn; } expression = expr() <RBRACE>
n = < START_INTERPOLATION> { line = n.beginLine; column = n.beginColumn; } expression = expressionList() <RBRACE>
{
return new Interpolation(expression, line, column);
}
Expand Down