void AXRController::recursiveMatchRulesToDisplayObjects(HSSRule::p & rule, const std::vector<HSSDisplayObject::p> & scope)
{
    this->currentChain = rule->selectorChain;
    this->currentChainSize = this->currentChain->size();
    this->currentChainCount = 0;
    this->currentSelectorNode = this->currentChain->get(0);
    
    const std::vector<HSSDisplayObject::p> selection = this->selectHierarchical(scope);
    unsigned i, size, j, size2;
    for (i=0, size=selection.size(); i<size; i++) {
        const HSSDisplayObject::p & displayObject = selection[i];
        std_log1("match "+displayObject->getElementName());
        displayObject->rulesAdd(rule);
        displayObject->setNeedsRereadRules(true);
        displayObject->setNeedsSurface(true);
        displayObject->setDirty(true);
        
        //if it is a container it may have children
        if(displayObject->isA(HSSObjectTypeContainer)){
            HSSContainer::p container = boost::static_pointer_cast<HSSContainer>(displayObject);
            for (j=0, size2=rule->childrenSize(); j<size2; j++) {
                HSSRule::p childRule = rule->childrenGet(j);
                this->recursiveMatchRulesToDisplayObjects(childRule, container->children);
            }
        }
    }
    
    
//    //look at the selector chain
//    HSSSelectorChain * selectorChain(rule->selectorChain.get());
//    std::vector<HSSDisplayObject::p>tempSelection;
//    unsigned i, j, size;
//    
//    unsigned selectorCount = 0;
//    unsigned selectorSize = selectorChain->size();
//    while (selectorCount < selectorSize) {
//        const HSSParserNode::p & selector = selectorChain->get(selectorCount++);
//        if(selectorChain->size() == 1){
//            if(selector->isA(HSSParserNodeTypeSelector)){
//                HSSSelector::p simpleSelector = boost::static_pointer_cast<HSSSelector>(selector);
//                //select items
//                for (i=0, size=scope.size(); i<size; i++) {
//                    const HSSDisplayObject::p & displayObject = scope[i];
//                
//                    //does it match
//                    if(simpleSelector->getElementName() == displayObject->getElementName()){
//                        std_log1("match "+displayObject->getElementName());
//                        displayObject->rulesAdd(rule);
//                        displayObject->setNeedsRereadRules(true);
//                        displayObject->setNeedsSurface(true);
//                        displayObject->setDirty(true);
//                        
//                        //if it is a container it may have children
//                        if(displayObject->isA(HSSObjectTypeContainer)){
//                            HSSContainer::p container = boost::static_pointer_cast<HSSContainer>(displayObject);
//                            for (i=0; i<container->children.size(); i++) { //FIXME: container will have an accessor for chlidrenSize in the future
//                                for (j=0; j<rule->childrenSize(); j++) {
//                                    HSSRule::p childRule = rule->childrenGet(j);
//                                    this->recursiveMatchRulesToDisplayObjects(childRule, container->children);
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        } else {
//            const HSSParserNode::p & selector2 = selectorChain->get(selectorCount++);
//            HSSParserNodeType selectorType = selector2->getType();
//            switch (selectorType) {
//                case HSSParserNodeTypeCombinator:
//                {
//                    HSSCombinator::p combinator = boost::static_pointer_cast<HSSCombinator>(selector2);
//                    const HSSCombinatorType & combinatorType = combinator->getCombinatorType();
//                    switch (combinatorType) {
//                        case HSSCombinatorTypeNextSiblings:
//                            <#statements#>
//                            break;
//                            
//                        default:
//                            break;
//                    }
//                    break;
//                }
//                    
//                default:
//                    break;
//            }
//        }
//    }
//    
//    
//    
//    //select items
//    for (i=0, size=scope.size(); i<size; i++) {
//        const HSSDisplayObject::p & displayObject = scope[i];
//        
//        
//        
//        //in case we're dealing with a displayObject which cannot have children
//        //we shortcut here
//        if(selectorChain->size() > 1 && !displayObject->isA(HSSObjectTypeContainer)){
//            //we're done
//            continue;
//        }
//        
//        for (j=0, size=selectorChain->size(); j<size; j++) {
//            const HSSParserNode::p & currentNode = selectorChain->get(j);
//            if(currentNode->isA(HSSParserNodeTypeSelector)){
//                HSSSelector::p simpleSelector = boost::static_pointer_cast<HSSSelector>(currentNode);
//                
//                //match the selector
//                if (simpleSelector->getElementName() == displayObject->getElementName()) {
//                    tempSelection.push_back(displayObject);
//                }
//            }
//        }
//    }
}
예제 #2
0
void AXRController::recursiveMatchRulesToDisplayObjects(const HSSRule::p & rule, const std::vector<HSSDisplayObject::p> & scope, HSSContainer::p container, bool applyingInstructions)
{
    HSSInstruction::p instruction = rule->getInstruction();
    if (instruction && applyingInstructions) {
        switch (instruction->getInstructionType()) {
            case HSSNewInstruction:
            {
                std::string elementName = rule->getSelectorChain()->subject()->getElementName();
                unsigned i;
                unsigned argssize = 1;
                HSSParserNode::p argument = instruction->getArgument();
                if(argument){
                    if (argument->isA(HSSParserNodeTypeNumberConstant)) {
                        HSSNumberConstant::p argnum = boost::static_pointer_cast<HSSNumberConstant>(argument);
                        argssize = (int)argnum->getValue();
                    }
                }
                
                for (i=0; i<argssize; i++) {
                    HSSContainer::p newContainer = HSSContainer::p(new HSSContainer());
                    newContainer->setName(elementName);
                    newContainer->setElementName(elementName);;
                    this->add(newContainer);
                    rule->setThisObj(newContainer);
                    newContainer->rulesAdd(rule, (rule->getActiveByDefault() ? HSSRuleStateOn : HSSRuleStateOff ));
                    std_log1("created "+newContainer->getElementName());
                    newContainer->setNeedsRereadRules(true);
                    newContainer->setNeedsSurface(true);
                    newContainer->setDirty(true);
                    unsigned i, size;
                    this->currentContext.push(newContainer);
                    for (i=0, size=rule->childrenSize(); i<size; i++) {
                        const HSSRule::p childRule = rule->childrenGet(i);
                        this->recursiveMatchRulesToDisplayObjects(childRule, newContainer->getChildren(), newContainer, applyingInstructions);
                    }
                    newContainer->setNeedsRereadRules(true);
                    //newContainer->fireEvent(HSSEventTypeLoad);
                    this->currentContext.pop();
                }
                
                break;
            }
                
            case HSSMoveInstruction:
            {
                HSSContainer::p parent = container->getParent();
                if (parent) {
                    std::vector<HSSDisplayObject::p> moveScope = parent->getChildren();
                    this->setSelectorChain(rule->getSelectorChain());
                    std::vector< std::vector<HSSDisplayObject::p> > selection = this->selectHierarchical(moveScope, container);
                    unsigned i, j, k, size, size2, size3;
                    
                    this->currentContext.push(container);
                    //move the children over
                    for (i=0, size=selection.size(); i<size; i++) {
                        std::vector<HSSDisplayObject::p> inner = selection[i];
                        for (j=0, size2=inner.size(); j<size2; j++) {
                            HSSDisplayObject::p theDO = inner[j];
                            if(theDO != container){
                                theDO->removeFromParent();
                                this->add(theDO);
                                rule->setThisObj(theDO);
                                std_log1("moved "+theDO->getElementName());
                                theDO->rulesAdd(rule, (rule->getActiveByDefault() ? HSSRuleStateOn : HSSRuleStateOff ));
                                theDO->setNeedsRereadRules(true);
                                theDO->setNeedsSurface(true);
                                theDO->setDirty(true);
                                
                                if(theDO->isA(HSSObjectTypeContainer)){
                                    HSSContainer::p theContainer = boost::static_pointer_cast<HSSContainer>(theDO);
                                    this->currentContext.push(theContainer);
                                    //assign more rules
                                    for (k=0, size3=rule->childrenSize(); k<size3; k++) {
                                        const HSSRule::p childRule = rule->childrenGet(k);
                                        this->recursiveMatchRulesToDisplayObjects(childRule, theContainer->getChildren(), theContainer, applyingInstructions);
                                    }
                                    this->currentContext.pop();
                                }
                                
                                theDO->setNeedsRereadRules(true);
                                //theDO->fireEvent(HSSEventTypeLoad);
                            }
                            
                        }
                    }
                    this->currentContext.pop();
                }
                
                break;
            }
                
            case HSSDeleteInstruction:
            {
                //select the items to be deleted
                this->setSelectorChain(rule->getSelectorChain());
                std::vector< std::vector<HSSDisplayObject::p> > selection = this->selectHierarchical(scope, container);
                unsigned i, j, size, size2;
                for (i=0, size=selection.size(); i<size; i++) {
                    std::vector<HSSDisplayObject::p> inner = selection[i];
                    for (j=0, size2=inner.size(); j<size2; j++) {
                        inner[j]->removeFromParent();
                    }
                }
                break;
            }
                                
            default:
                break;
        }
        
    } else {
        HSSSelectorChain::p selectorChain = rule->getSelectorChain();
        if(selectorChain){
            this->setSelectorChain(selectorChain);
            
            //if it starts with a combinator, adjust the scope and selector chain
            bool useAdjustedScope = false;
            std::vector<HSSDisplayObject::p> adjustedScope;
            if(this->currentSelectorNode->isA(HSSParserNodeTypeCombinator)){
                useAdjustedScope = true;
                adjustedScope.push_back(container);
                this->currentChain->prepend(HSSSelector::p(new HSSSelector(container->getElementName())));
                this->currentChainSize ++;
                this->currentSelectorNode = this->currentChain->get(0);
            }
            
            //we observe the parent for dom changes
            container->observe(HSSObservablePropertyTreeChange, HSSObservablePropertyValue, rule.get(), new HSSValueChangedCallback<HSSRule>(rule.get(), &HSSRule::treeChanged));
            rule->setObservedTreeChanger(container.get());
            rule->setThisObj(container);
            
            rule->setOriginalScope(scope);
            std::vector< std::vector<HSSDisplayObject::p> > selection = this->selectHierarchical((useAdjustedScope ? adjustedScope : scope), container);
            unsigned i, j, k, size, size2, size3;
            for (i=0, size=selection.size(); i<size; i++) {
                std::vector<HSSDisplayObject::p> inner = selection[i];
                for (j=0, size2=inner.size(); j<size2; j++) {
                    const HSSDisplayObject::p & displayObject = inner[j];
                    std_log1("match "+displayObject->getElementName());
                    displayObject->rulesAdd(rule, (rule->getActiveByDefault() ? HSSRuleStateOn : HSSRuleStateOff ));
                    
                    displayObject->setNeedsRereadRules(true);
                    displayObject->setNeedsSurface(true);
                    displayObject->setDirty(true);
                    
                    //if it is a container it may have children
                    if(displayObject->isA(HSSObjectTypeContainer)){
                        HSSContainer::p selectedContainer = boost::static_pointer_cast<HSSContainer>(displayObject);
                        this->currentContext.push(selectedContainer);
                        for (k=0, size3=rule->childrenSize(); k<size3; k++) {
                            const HSSRule::p childRule = rule->childrenGet(k);
                            this->recursiveMatchRulesToDisplayObjects(childRule, selectedContainer->getChildren(), selectedContainer, applyingInstructions);
                        }
                        this->currentContext.pop();
                    }
                    
                    displayObject->setNeedsRereadRules(true);
                }
            }
        }
    }
}