Text-Sass-XS

 view release on metacpan or  search on metacpan

libsass/src/expand.cpp  view on Meta::CPAN

#include "expand.hpp"
#include "bind.hpp"
#include "eval.hpp"
#include "contextualize.hpp"
#include "to_string.hpp"
#include "backtrace.hpp"

#include <iostream>
#include <typeinfo>

#ifndef SASS_CONTEXT
#include "context.hpp"
#endif

namespace Sass {

  Expand::Expand(Context& ctx, Eval* eval, Contextualize* contextualize, Env* env, Backtrace* bt)
  : ctx(ctx),
    eval(eval),
    contextualize(contextualize),
    env(env),
    block_stack(vector<Block*>()),
    property_stack(vector<String*>()),
    selector_stack(vector<Selector*>()),
    backtrace(bt),
    extensions(multimap<Simple_Selector_Sequence, Selector_Combination*>())
  { selector_stack.push_back(0); }

  Statement* Expand::operator()(Block* b)
  {
    Env new_env;
    new_env.link(*env);
    env = &new_env;
    Block* bb = new (ctx.mem) Block(b->path(), b->line(), b->length(), b->is_root());
    block_stack.push_back(bb);
    append_block(b);
    block_stack.pop_back();
    env = env->parent();
    return bb;
  }

  Statement* Expand::operator()(Ruleset* r)
  {
    To_String to_string;
    // if (selector_stack.back()) cerr << "expanding " << selector_stack.back()->perform(&to_string) << " and " << r->selector()->perform(&to_string) << endl;
    Selector* sel_ctx = r->selector()->perform(contextualize->with(selector_stack.back(), env, backtrace));
    selector_stack.push_back(sel_ctx);
    Ruleset* rr = new (ctx.mem) Ruleset(r->path(),
                                        r->line(),
                                        sel_ctx,
                                        r->block()->perform(this)->block());
    selector_stack.pop_back();
    return rr;
  }

  Statement* Expand::operator()(Propset* p)
  {
    property_stack.push_back(p->property_fragment());
    Block* expanded_block = p->block()->perform(this)->block();

    Block* current_block = block_stack.back();
    for (size_t i = 0, L = expanded_block->length(); i < L; ++i) {
      Statement* stm = (*expanded_block)[i];
      if (typeid(*stm) == typeid(Declaration)) {
        Declaration* dec = static_cast<Declaration*>(stm);
        String_Schema* combined_prop = new (ctx.mem) String_Schema(p->path(), p->line());
        if (!property_stack.empty()) {
          *combined_prop << property_stack.back()
                         << new (ctx.mem) String_Constant(p->path(), p->line(), "-")
                         << dec->property(); // TODO: eval the prop into a string constant
        }
        else {
          *combined_prop << dec->property();
        }
        dec->property(combined_prop);
        *current_block << dec;
      }
      else {
        error("contents of namespaced properties must result in style declarations only", stm->path(), stm->line(), backtrace);
      }
    }

    property_stack.pop_back();

    return 0;
  }

  Statement* Expand::operator()(Media_Block* m)
  {
    Expression* media_queries = m->media_queries()->perform(eval->with(env, backtrace));
    Media_Block* mm = new (ctx.mem) Media_Block(m->path(),
                                                m->line(),
                                                static_cast<List*>(media_queries),
                                                m->block()->perform(this)->block());
    mm->enclosing_selector(selector_stack.back());
    return mm;
  }

  Statement* Expand::operator()(At_Rule* a)
  {
    Block* ab = a->block();
    selector_stack.push_back(0);
    Selector* as = a->selector();
    if (as) as = as->perform(contextualize->with(0, env, backtrace));
    Block* bb = ab ? ab->perform(this)->block() : 0;
    At_Rule* aa = new (ctx.mem) At_Rule(a->path(),
                                        a->line(),
                                        a->keyword(),
                                        as,
                                        bb);
    selector_stack.pop_back();
    return aa;
  }

  Statement* Expand::operator()(Declaration* d)
  {



( run in 0.643 second using v1.01-cache-2.11-cpan-71847e10f99 )