blob: d29d0594910ea883e10ecbe7d06d249e26d576f9 [file] [log] [blame]
/*
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "StyleRelations.h"
#include "Element.h"
#include "NodeRenderStyle.h"
#include "RenderStyle.h"
#include "StyleUpdate.h"
namespace WebCore {
namespace Style {
std::unique_ptr<Relations> commitRelationsToRenderStyle(RenderStyle& style, const Element& element, const Relations& relations)
{
if (!relations.isEmpty())
style.setUnique();
std::unique_ptr<Relations> remainingRelations;
auto appendStyleRelation = [&remainingRelations] (const Relation& relation) {
if (!remainingRelations)
remainingRelations = makeUnique<Relations>();
remainingRelations->append(relation);
};
for (auto& relation : relations) {
if (relation.element != &element) {
appendStyleRelation(relation);
continue;
}
switch (relation.type) {
case Relation::AffectedByEmpty:
style.setEmptyState(relation.value);
appendStyleRelation(relation);
break;
case Relation::FirstChild:
style.setFirstChildState();
break;
case Relation::LastChild:
style.setLastChildState();
break;
case Relation::Unique:
break;
case Relation::AffectedByPreviousSibling:
case Relation::DescendantsAffectedByPreviousSibling:
case Relation::AffectsNextSibling:
case Relation::ChildrenAffectedByForwardPositionalRules:
case Relation::DescendantsAffectedByForwardPositionalRules:
case Relation::ChildrenAffectedByBackwardPositionalRules:
case Relation::DescendantsAffectedByBackwardPositionalRules:
case Relation::ChildrenAffectedByFirstChildRules:
case Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
case Relation::ChildrenAffectedByLastChildRules:
case Relation::NthChildIndex:
appendStyleRelation(relation);
break;
}
}
return remainingRelations;
}
void commitRelations(std::unique_ptr<Relations> relations, Update& update)
{
if (!relations)
return;
for (auto& relation : *relations) {
auto& element = const_cast<Element&>(*relation.element);
switch (relation.type) {
case Relation::AffectedByEmpty:
element.setStyleAffectedByEmpty();
break;
case Relation::AffectedByPreviousSibling:
element.setStyleIsAffectedByPreviousSibling();
break;
case Relation::DescendantsAffectedByPreviousSibling:
element.setDescendantsAffectedByPreviousSibling();
break;
case Relation::AffectsNextSibling: {
auto* sibling = &element;
for (unsigned i = 0; i < relation.value && sibling; ++i, sibling = sibling->nextElementSibling())
sibling->setAffectsNextSiblingElementStyle();
break;
}
case Relation::ChildrenAffectedByForwardPositionalRules:
element.setChildrenAffectedByForwardPositionalRules();
break;
case Relation::DescendantsAffectedByForwardPositionalRules:
element.setDescendantsAffectedByForwardPositionalRules();
break;
case Relation::ChildrenAffectedByBackwardPositionalRules:
element.setChildrenAffectedByBackwardPositionalRules();
break;
case Relation::DescendantsAffectedByBackwardPositionalRules:
element.setDescendantsAffectedByBackwardPositionalRules();
break;
case Relation::ChildrenAffectedByFirstChildRules:
element.setChildrenAffectedByFirstChildRules();
break;
case Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
element.setChildrenAffectedByBackwardPositionalRules();
element.setChildrenAffectedByPropertyBasedBackwardPositionalRules();
break;
case Relation::ChildrenAffectedByLastChildRules:
element.setChildrenAffectedByLastChildRules();
break;
case Relation::FirstChild:
if (auto* style = update.elementStyle(element))
style->setFirstChildState();
break;
case Relation::LastChild:
if (auto* style = update.elementStyle(element))
style->setLastChildState();
break;
case Relation::NthChildIndex:
if (auto* style = update.elementStyle(element))
style->setUnique();
element.setChildIndex(relation.value);
break;
case Relation::Unique:
if (auto* style = update.elementStyle(element))
style->setUnique();
break;
}
}
}
}
}