#include "core/css/StyleSheetContents.h"
#include "core/css/StyleSheetList.h"
#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/NamedFlow.h"
-#include "core/dom/NamedFlowCollection.h"
#include "core/dom/Node.h"
#include "core/dom/NodeList.h"
#include "core/fetch/CSSStyleSheetResource.h"
#include "core/page/Page.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderObject.h"
-#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTextFragment.h"
#include "platform/fonts/Font.h"
return result;
}
-class UpdateRegionLayoutTask {
-public:
- UpdateRegionLayoutTask(InspectorCSSAgent*);
- void scheduleFor(NamedFlow*, int documentNodeId);
- void unschedule(NamedFlow*);
- void reset();
- void onTimer(Timer<UpdateRegionLayoutTask>*);
-
-private:
- InspectorCSSAgent* m_cssAgent;
- Timer<UpdateRegionLayoutTask> m_timer;
- HashMap<NamedFlow*, int> m_namedFlows;
-};
-
-UpdateRegionLayoutTask::UpdateRegionLayoutTask(InspectorCSSAgent* cssAgent)
- : m_cssAgent(cssAgent)
- , m_timer(this, &UpdateRegionLayoutTask::onTimer)
-{
-}
-
-void UpdateRegionLayoutTask::scheduleFor(NamedFlow* namedFlow, int documentNodeId)
-{
- m_namedFlows.add(namedFlow, documentNodeId);
-
- if (!m_timer.isActive())
- m_timer.startOneShot(0);
-}
-
-void UpdateRegionLayoutTask::unschedule(NamedFlow* namedFlow)
-{
- m_namedFlows.remove(namedFlow);
-}
-
-void UpdateRegionLayoutTask::reset()
-{
- m_timer.stop();
- m_namedFlows.clear();
-}
-
-void UpdateRegionLayoutTask::onTimer(Timer<UpdateRegionLayoutTask>*)
-{
- // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed.
- Vector<std::pair<NamedFlow*, int> > namedFlows;
-
- for (HashMap<NamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it)
- namedFlows.append(std::make_pair(it->key, it->value));
-
- for (unsigned i = 0, size = namedFlows.size(); i < size; ++i) {
- NamedFlow* namedFlow = namedFlows.at(i).first;
- int documentNodeId = namedFlows.at(i).second;
-
- if (m_namedFlows.contains(namedFlow)) {
- m_cssAgent->regionLayoutUpdated(namedFlow, documentNodeId);
- m_namedFlows.remove(namedFlow);
- }
- }
-
- if (!m_namedFlows.isEmpty() && !m_timer.isActive())
- m_timer.startOneShot(0);
-}
-
-class ChangeRegionOversetTask {
-public:
- ChangeRegionOversetTask(InspectorCSSAgent*);
- void scheduleFor(NamedFlow*, int documentNodeId);
- void unschedule(NamedFlow*);
- void reset();
- void onTimer(Timer<ChangeRegionOversetTask>*);
-
-private:
- InspectorCSSAgent* m_cssAgent;
- Timer<ChangeRegionOversetTask> m_timer;
- HashMap<NamedFlow*, int> m_namedFlows;
-};
-
-ChangeRegionOversetTask::ChangeRegionOversetTask(InspectorCSSAgent* cssAgent)
- : m_cssAgent(cssAgent)
- , m_timer(this, &ChangeRegionOversetTask::onTimer)
-{
-}
-
-void ChangeRegionOversetTask::scheduleFor(NamedFlow* namedFlow, int documentNodeId)
-{
- m_namedFlows.add(namedFlow, documentNodeId);
-
- if (!m_timer.isActive())
- m_timer.startOneShot(0);
-}
-
-void ChangeRegionOversetTask::unschedule(NamedFlow* namedFlow)
-{
- m_namedFlows.remove(namedFlow);
-}
-
-void ChangeRegionOversetTask::reset()
-{
- m_timer.stop();
- m_namedFlows.clear();
-}
-
-void ChangeRegionOversetTask::onTimer(Timer<ChangeRegionOversetTask>*)
-{
- // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed.
- for (HashMap<NamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it)
- m_cssAgent->regionOversetChanged(it->key, it->value);
-
- m_namedFlows.clear();
-}
-
class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(StyleSheetAction);
public:
String m_oldText;
};
-class InspectorCSSAgent::SetStyleTextAction FINAL : public InspectorCSSAgent::StyleSheetAction {
- WTF_MAKE_NONCOPYABLE(SetStyleTextAction);
-public:
- SetStyleTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& text)
- : InspectorCSSAgent::StyleSheetAction("SetPropertyText", styleSheet)
- , m_cssId(cssId)
- , m_text(text)
- {
- }
-
- virtual String toString() OVERRIDE
- {
- return mergeId() + ": " + m_oldText + " -> " + m_text;
- }
-
- virtual bool perform(ExceptionState& exceptionState) OVERRIDE
- {
- return redo(exceptionState);
- }
-
- virtual bool undo(ExceptionState& exceptionState) OVERRIDE
- {
- String placeholder;
- return m_styleSheet->setStyleText(m_cssId, m_oldText, &placeholder, exceptionState);
- }
-
- virtual bool redo(ExceptionState& exceptionState) OVERRIDE
- {
- return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText, exceptionState);
- }
-
- virtual String mergeId() OVERRIDE
- {
- return String::format("SetStyleText %s:%u", m_cssId.styleSheetId().utf8().data(), m_cssId.ordinal());
- }
-
- virtual void merge(PassOwnPtr<Action> action) OVERRIDE
- {
- ASSERT(action->mergeId() == mergeId());
-
- SetStyleTextAction* other = static_cast<SetStyleTextAction*>(action.get());
- m_text = other->m_text;
- }
-
-private:
- InspectorCSSId m_cssId;
- String m_text;
- String m_oldText;
-};
-
class InspectorCSSAgent::SetPropertyTextAction FINAL : public InspectorCSSAgent::StyleSheetAction {
WTF_MAKE_NONCOPYABLE(SetPropertyTextAction);
public:
String oldText;
bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, &oldText, exceptionState);
m_oldText = oldText.stripWhiteSpace();
- // FIXME: remove this once the model handles this case.
- if (!m_oldText.endsWith(';'))
- m_oldText.append(';');
return result;
}
bool m_overwrite;
};
-class InspectorCSSAgent::TogglePropertyAction FINAL : public InspectorCSSAgent::StyleSheetAction {
- WTF_MAKE_NONCOPYABLE(TogglePropertyAction);
-public:
- TogglePropertyAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, bool disable)
- : InspectorCSSAgent::StyleSheetAction("ToggleProperty", styleSheet)
- , m_cssId(cssId)
- , m_propertyIndex(propertyIndex)
- , m_disable(disable)
- {
- }
-
- virtual bool perform(ExceptionState& exceptionState) OVERRIDE
- {
- return redo(exceptionState);
- }
-
- virtual bool undo(ExceptionState& exceptionState) OVERRIDE
- {
- return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, !m_disable, exceptionState);
- }
-
- virtual bool redo(ExceptionState& exceptionState) OVERRIDE
- {
- return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, m_disable, exceptionState);
- }
-
-private:
- InspectorCSSId m_cssId;
- unsigned m_propertyIndex;
- bool m_disable;
-};
-
class InspectorCSSAgent::SetRuleSelectorAction FINAL : public InspectorCSSAgent::StyleSheetAction {
WTF_MAKE_NONCOPYABLE(SetRuleSelectorAction);
public:
void InspectorCSSAgent::resetNonPersistentData()
{
- m_namedFlowCollectionsRequested.clear();
- if (m_updateRegionLayoutTask)
- m_updateRegionLayoutTask->reset();
- if (m_changeRegionOversetTask)
- m_changeRegionOversetTask->reset();
resetPseudoStates();
}
m_frontend->mediaQueryResultChanged();
}
-void InspectorCSSAgent::didCreateNamedFlow(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- ErrorString errorString;
- m_frontend->namedFlowCreated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
-}
-
-void InspectorCSSAgent::willRemoveNamedFlow(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- if (m_updateRegionLayoutTask)
- m_updateRegionLayoutTask->unschedule(namedFlow);
-
- m_frontend->namedFlowRemoved(documentNodeId, namedFlow->name().string());
-}
-
void InspectorCSSAgent::willMutateRules()
{
++m_styleSheetsPendingMutation;
}
}
-void InspectorCSSAgent::didUpdateRegionLayout(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- if (!m_updateRegionLayoutTask)
- m_updateRegionLayoutTask = adoptPtr(new UpdateRegionLayoutTask(this));
- m_updateRegionLayoutTask->scheduleFor(namedFlow, documentNodeId);
-}
-
-void InspectorCSSAgent::regionLayoutUpdated(NamedFlow* namedFlow, int documentNodeId)
-{
- if (namedFlow->flowState() == NamedFlow::FlowStateNull)
- return;
-
- ErrorString errorString;
- RefPtr<NamedFlow> protector(namedFlow);
-
- m_frontend->regionLayoutUpdated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
-}
-
-void InspectorCSSAgent::didChangeRegionOverset(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- if (!m_changeRegionOversetTask)
- m_changeRegionOversetTask = adoptPtr(new ChangeRegionOversetTask(this));
- m_changeRegionOversetTask->scheduleFor(namedFlow, documentNodeId);
-}
-
-void InspectorCSSAgent::regionOversetChanged(NamedFlow* namedFlow, int documentNodeId)
-{
- if (namedFlow->flowState() == NamedFlow::FlowStateNull)
- return;
-
- ErrorString errorString;
- RefPtr<NamedFlow> protector(namedFlow);
-
- m_frontend->regionOversetChanged(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
-}
-
void InspectorCSSAgent::activeStyleSheetsUpdated(Document* document)
{
if (styleSheetEditInProgress())
}
}
-void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader> >& styleInfos)
-{
- styleInfos = TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader>::create();
- Vector<InspectorStyleSheet*> styleSheets;
- collectAllStyleSheets(styleSheets);
- for (size_t i = 0; i < styleSheets.size(); ++i)
- styleInfos->addItem(styleSheets.at(i)->buildObjectForStyleSheetInfo());
-}
-
void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& styleSheetObject)
{
InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
return;
RefPtr<TypeBuilder::CSS::CSSStyleSheetBody> result = TypeBuilder::CSS::CSSStyleSheetBody::create()
- .setStyleSheetId(styleSheetId)
.setRules(buildArrayForRuleList(inspectorStyleSheet->pageStyleSheet()->rules().get()));
bool success = inspectorStyleSheet->fillObjectForStyleSheet(result);
void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
{
InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
- if (!inspectorStyleSheet)
+ if (!inspectorStyleSheet) {
+ *errorString = "Style sheet with id " + styleSheetId + " not found.";
return;
+ }
TrackExceptionState exceptionState;
m_domAgent->history()->perform(adoptPtr(new SetStyleSheetTextAction(inspectorStyleSheet, text)), exceptionState);
*errorString = InspectorDOMAgent::toErrorString(exceptionState);
}
-void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<JSONObject>& fullStyleId, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
-{
- InspectorCSSId compoundId(fullStyleId);
- ASSERT(!compoundId.isEmpty());
-
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
- if (!inspectorStyleSheet)
- return;
-
- TrackExceptionState exceptionState;
- m_domAgent->history()->perform(adoptPtr(new SetStyleTextAction(inspectorStyleSheet, compoundId, text)), exceptionState);
- if (!exceptionState.hadException())
- result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
- *errorString = InspectorDOMAgent::toErrorString(exceptionState);
-}
-
void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<JSONObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
{
InspectorCSSId compoundId(fullStyleId);
*errorString = InspectorDOMAgent::toErrorString(exceptionState);
}
-void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<JSONObject>& fullStyleId, int propertyIndex, bool disable, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
-{
- InspectorCSSId compoundId(fullStyleId);
- ASSERT(!compoundId.isEmpty());
-
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
- if (!inspectorStyleSheet)
- return;
-
- TrackExceptionState exceptionState;
- bool success = m_domAgent->history()->perform(adoptPtr(new TogglePropertyAction(inspectorStyleSheet, compoundId, propertyIndex, disable)), exceptionState);
- if (success)
- result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
- *errorString = InspectorDOMAgent::toErrorString(exceptionState);
-}
-
void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<JSONObject>& fullRuleId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
{
InspectorCSSId compoundId(fullRuleId);
result = inspectorStyleSheet->buildObjectForRule(rule, buildMediaListChain(rule));
}
-void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo> >& cssProperties)
-{
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo> > properties = TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo>::create();
- for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
- CSSPropertyID id = convertToCSSPropertyID(i);
- RefPtr<TypeBuilder::CSS::CSSPropertyInfo> property = TypeBuilder::CSS::CSSPropertyInfo::create()
- .setName(getPropertyNameString(id));
-
- const StylePropertyShorthand& shorthand = shorthandForProperty(id);
- if (!shorthand.length()) {
- properties->addItem(property.release());
- continue;
- }
- RefPtr<TypeBuilder::Array<String> > longhands = TypeBuilder::Array<String>::create();
- for (unsigned j = 0; j < shorthand.length(); ++j) {
- CSSPropertyID longhandID = shorthand.properties()[j];
- longhands->addItem(getPropertyNameString(longhandID));
- }
- property->setLonghands(longhands);
- properties->addItem(property.release());
- }
- cssProperties = properties.release();
-}
-
void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses)
{
Element* element = m_domAgent->assertElement(errorString, nodeId);
m_nodeIdToForcedPseudoState.set(nodeId, forcedPseudoState);
else
m_nodeIdToForcedPseudoState.remove(nodeId);
- element->ownerDocument()->setNeedsStyleRecalc();
-}
-
-void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int documentNodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::NamedFlow> >& result)
-{
- Document* document = m_domAgent->assertDocument(errorString, documentNodeId);
- if (!document)
- return;
-
- m_namedFlowCollectionsRequested.add(documentNodeId);
-
- Vector<RefPtr<NamedFlow> > namedFlowsVector = document->namedFlows()->namedFlows();
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::NamedFlow> > namedFlows = TypeBuilder::Array<TypeBuilder::CSS::NamedFlow>::create();
-
- for (Vector<RefPtr<NamedFlow> >::iterator it = namedFlowsVector.begin(); it != namedFlowsVector.end(); ++it)
- namedFlows->addItem(buildObjectForNamedFlow(errorString, it->get(), documentNodeId));
-
- result = namedFlows.release();
+ element->ownerDocument()->setNeedsStyleRecalc(SubtreeStyleChange);
}
PassRefPtr<TypeBuilder::CSS::CSSMedia> InspectorCSSAgent::buildMediaObject(const MediaList* media, MediaListSource mediaListSource, const String& sourceURL, CSSStyleSheet* parentStyleSheet)
return toElement(node);
}
-int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document)
-{
- int documentNodeId = m_domAgent->boundNodeId(document);
- if (!documentNodeId || !m_namedFlowCollectionsRequested.contains(documentNodeId))
- return 0;
-
- return documentNodeId;
-}
-
void InspectorCSSAgent::collectAllStyleSheets(Vector<InspectorStyleSheet*>& result)
{
Vector<CSSStyleSheet*> cssStyleSheets;
// user agent stylesheets. To work around this issue, we use CSSOM wrapper created by inspector.
if (!rule->parentStyleSheet()) {
if (!m_inspectorUserAgentStyleSheet)
- m_inspectorUserAgentStyleSheet = CSSStyleSheet::create(CSSDefaultStyleSheets::defaultStyleSheet);
+ m_inspectorUserAgentStyleSheet = CSSStyleSheet::create(CSSDefaultStyleSheets::instance().defaultStyleSheet());
rule->setParentStyleSheet(m_inspectorUserAgentStyleSheet.get());
}
return bindStyleSheet(rule->parentStyleSheet())->buildObjectForRule(rule, buildMediaListChain(rule));
const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
long index = 0;
PseudoId elementPseudoId = element->pseudoId();
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
const CSSSelector* firstTagHistorySelector = selector;
bool matched = false;
if (elementPseudoId)
return inspectorStyle->buildObjectForStyle();
}
-PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > InspectorCSSAgent::buildArrayForRegions(ErrorString* errorString, PassRefPtr<NodeList> regionList, int documentNodeId)
-{
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > regions = TypeBuilder::Array<TypeBuilder::CSS::Region>::create();
-
- for (unsigned i = 0; i < regionList->length(); ++i) {
- TypeBuilder::CSS::Region::RegionOverset::Enum regionOverset;
-
- switch (toElement(regionList->item(i))->renderRegion()->regionOversetState()) {
- case RegionFit:
- regionOverset = TypeBuilder::CSS::Region::RegionOverset::Fit;
- break;
- case RegionEmpty:
- regionOverset = TypeBuilder::CSS::Region::RegionOverset::Empty;
- break;
- case RegionOverset:
- regionOverset = TypeBuilder::CSS::Region::RegionOverset::Overset;
- break;
- case RegionUndefined:
- continue;
- default:
- ASSERT_NOT_REACHED();
- continue;
- }
-
- RefPtr<TypeBuilder::CSS::Region> region = TypeBuilder::CSS::Region::create()
- .setRegionOverset(regionOverset)
- // documentNodeId was previously asserted
- .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i)));
-
- regions->addItem(region);
- }
-
- return regions.release();
-}
-
-PassRefPtr<TypeBuilder::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString* errorString, NamedFlow* webkitNamedFlow, int documentNodeId)
-{
- RefPtr<NodeList> contentList = webkitNamedFlow->getContent();
- RefPtr<TypeBuilder::Array<int> > content = TypeBuilder::Array<int>::create();
-
- for (unsigned i = 0; i < contentList->length(); ++i) {
- // documentNodeId was previously asserted
- content->addItem(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, contentList->item(i)));
- }
-
- RefPtr<TypeBuilder::CSS::NamedFlow> namedFlow = TypeBuilder::CSS::NamedFlow::create()
- .setDocumentNodeId(documentNodeId)
- .setName(webkitNamedFlow->name().string())
- .setOverset(webkitNamedFlow->overset())
- .setContent(content)
- .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId));
-
- return namedFlow.release();
-}
-
void InspectorCSSAgent::didRemoveDocument(Document* document)
{
if (document)
m_nodeIdToForcedPseudoState.clear();
for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = documentsToChange.end(); it != end; ++it)
- (*it)->setNeedsStyleRecalc();
+ (*it)->setNeedsStyleRecalc(SubtreeStyleChange);
}
} // namespace WebCore