зеркало из https://github.com/mozilla/gecko-dev.git
Bug 833808 part 2. Add some utilities for working with selectors to inspector utils. r=dbaron
This commit is contained in:
Родитель
3aa2cf5f0e
Коммит
1c99b91077
|
@ -16,13 +16,31 @@ interface nsIDOMFontFaceList;
|
||||||
interface nsIDOMRange;
|
interface nsIDOMRange;
|
||||||
interface nsIDOMCSSStyleSheet;
|
interface nsIDOMCSSStyleSheet;
|
||||||
|
|
||||||
[scriptable, uuid(f7a37305-a963-4a2a-b951-2c97a6b27fb4)]
|
[scriptable, uuid(dd8a9dfd-336f-4cce-8ec1-0365ede9a3a8)]
|
||||||
interface inIDOMUtils : nsISupports
|
interface inIDOMUtils : nsISupports
|
||||||
{
|
{
|
||||||
// CSS utilities
|
// CSS utilities
|
||||||
nsISupportsArray getCSSStyleRules(in nsIDOMElement aElement, [optional] in DOMString aPseudo);
|
nsISupportsArray getCSSStyleRules(in nsIDOMElement aElement, [optional] in DOMString aPseudo);
|
||||||
unsigned long getRuleLine(in nsIDOMCSSStyleRule aRule);
|
unsigned long getRuleLine(in nsIDOMCSSStyleRule aRule);
|
||||||
|
|
||||||
|
// Utilities for working with selectors. We don't have a JS OM representation
|
||||||
|
// of a single selector or a selector list yet, but given a rule we can index
|
||||||
|
// into the selector list.
|
||||||
|
//
|
||||||
|
// This is a somewhat backwards API; once we move StyleRule to WebIDL we
|
||||||
|
// should consider using [ChromeOnly] APIs on that.
|
||||||
|
unsigned long getSelectorCount(in nsIDOMCSSStyleRule aRule);
|
||||||
|
// For all three functions below, aSelectorIndex is 0-based
|
||||||
|
AString getSelectorText(in nsIDOMCSSStyleRule aRule,
|
||||||
|
in unsigned long aSelectorIndex);
|
||||||
|
unsigned long long getSpecificity(in nsIDOMCSSStyleRule aRule,
|
||||||
|
in unsigned long aSelectorIndex);
|
||||||
|
// Note: This does not handle scoped selectors correctly, because it has no
|
||||||
|
// idea what the right scope is.
|
||||||
|
bool selectorMatchesElement(in nsIDOMElement aElement,
|
||||||
|
in nsIDOMCSSStyleRule aRule,
|
||||||
|
in unsigned long aSelectorIndex);
|
||||||
|
|
||||||
// Returns true if the string names a property that is inherited by default.
|
// Returns true if the string names a property that is inherited by default.
|
||||||
bool isInheritedProperty(in AString aPropertyName);
|
bool isInheritedProperty(in AString aPropertyName);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,13 @@
|
||||||
#include "nsRange.h"
|
#include "nsRange.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "nsCSSStyleSheet.h"
|
#include "nsCSSStyleSheet.h"
|
||||||
|
#include "nsRuleWalker.h"
|
||||||
|
#include "nsRuleProcessorData.h"
|
||||||
|
#include "nsCSSRuleProcessor.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
using namespace mozilla::css;
|
||||||
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -188,19 +194,136 @@ inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<StyleRule>
|
||||||
|
GetRuleFromDOMRule(nsIDOMCSSStyleRule *aRule, ErrorResult& rv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsICSSStyleRuleDOMWrapper> rule = do_QueryInterface(aRule);
|
||||||
|
if (!rule) {
|
||||||
|
rv.Throw(NS_ERROR_INVALID_ARG);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<StyleRule> cssrule;
|
||||||
|
rv = rule->GetCSSStyleRule(getter_AddRefs(cssrule));
|
||||||
|
if (rv.Failed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cssrule) {
|
||||||
|
rv.Throw(NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
return cssrule.forget();
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
inDOMUtils::GetRuleLine(nsIDOMCSSStyleRule *aRule, uint32_t *_retval)
|
inDOMUtils::GetRuleLine(nsIDOMCSSStyleRule *aRule, uint32_t *_retval)
|
||||||
{
|
{
|
||||||
*_retval = 0;
|
ErrorResult rv;
|
||||||
|
nsRefPtr<StyleRule> rule = GetRuleFromDOMRule(aRule, rv);
|
||||||
|
if (rv.Failed()) {
|
||||||
|
return rv.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
NS_ENSURE_ARG_POINTER(aRule);
|
*_retval = rule->GetLineNumber();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsICSSStyleRuleDOMWrapper> rule = do_QueryInterface(aRule);
|
NS_IMETHODIMP
|
||||||
nsRefPtr<mozilla::css::StyleRule> cssrule;
|
inDOMUtils::GetSelectorCount(nsIDOMCSSStyleRule* aRule, uint32_t *aCount)
|
||||||
nsresult rv = rule->GetCSSStyleRule(getter_AddRefs(cssrule));
|
{
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
ErrorResult rv;
|
||||||
NS_ENSURE_TRUE(cssrule != nullptr, NS_ERROR_FAILURE);
|
nsRefPtr<StyleRule> rule = GetRuleFromDOMRule(aRule, rv);
|
||||||
*_retval = cssrule->GetLineNumber();
|
if (rv.Failed()) {
|
||||||
|
return rv.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t count = 0;
|
||||||
|
for (nsCSSSelectorList* sel = rule->Selector(); sel; sel = sel->mNext) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
*aCount = count;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsCSSSelectorList*
|
||||||
|
GetSelectorAtIndex(nsIDOMCSSStyleRule* aRule, uint32_t aIndex, ErrorResult& rv)
|
||||||
|
{
|
||||||
|
nsRefPtr<StyleRule> rule = GetRuleFromDOMRule(aRule, rv);
|
||||||
|
if (rv.Failed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (nsCSSSelectorList* sel = rule->Selector(); sel;
|
||||||
|
sel = sel->mNext, --aIndex) {
|
||||||
|
if (aIndex == 0) {
|
||||||
|
return sel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ran out of selectors
|
||||||
|
rv.Throw(NS_ERROR_INVALID_ARG);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
inDOMUtils::GetSelectorText(nsIDOMCSSStyleRule* aRule,
|
||||||
|
uint32_t aSelectorIndex,
|
||||||
|
nsAString& aText)
|
||||||
|
{
|
||||||
|
ErrorResult rv;
|
||||||
|
nsCSSSelectorList* sel = GetSelectorAtIndex(aRule, aSelectorIndex, rv);
|
||||||
|
if (rv.Failed()) {
|
||||||
|
return rv.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<StyleRule> rule = GetRuleFromDOMRule(aRule, rv);
|
||||||
|
MOZ_ASSERT(!rv.Failed(), "How could we get a selector but not a rule?");
|
||||||
|
|
||||||
|
sel->mSelectors->ToString(aText, rule->GetStyleSheet(), false);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
inDOMUtils::GetSpecificity(nsIDOMCSSStyleRule* aRule,
|
||||||
|
uint32_t aSelectorIndex,
|
||||||
|
uint64_t* aSpecificity)
|
||||||
|
{
|
||||||
|
ErrorResult rv;
|
||||||
|
nsCSSSelectorList* sel = GetSelectorAtIndex(aRule, aSelectorIndex, rv);
|
||||||
|
if (rv.Failed()) {
|
||||||
|
return rv.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
*aSpecificity = sel->mWeight;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
inDOMUtils::SelectorMatchesElement(nsIDOMElement* aElement,
|
||||||
|
nsIDOMCSSStyleRule* aRule,
|
||||||
|
uint32_t aSelectorIndex,
|
||||||
|
bool* aMatches)
|
||||||
|
{
|
||||||
|
nsCOMPtr<Element> element = do_QueryInterface(aElement);
|
||||||
|
NS_ENSURE_ARG_POINTER(element);
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
nsCSSSelectorList* tail = GetSelectorAtIndex(aRule, aSelectorIndex, rv);
|
||||||
|
if (rv.Failed()) {
|
||||||
|
return rv.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want just the one list item, not the whole list tail
|
||||||
|
nsAutoPtr<nsCSSSelectorList> sel(tail->Clone(false));
|
||||||
|
|
||||||
|
element->OwnerDoc()->FlushPendingLinkUpdates();
|
||||||
|
// XXXbz what exactly should we do with visited state here?
|
||||||
|
TreeMatchContext matchingContext(false,
|
||||||
|
nsRuleWalker::eRelevantLinkUnvisited,
|
||||||
|
element->OwnerDoc(),
|
||||||
|
TreeMatchContext::eNeverMatchVisited);
|
||||||
|
*aMatches = nsCSSRuleProcessor::SelectorListMatches(element, matchingContext,
|
||||||
|
sel);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,8 @@ private:
|
||||||
* items (where each |nsCSSSelectorList| object's |mSelectors| has
|
* items (where each |nsCSSSelectorList| object's |mSelectors| has
|
||||||
* an |mNext| for the P or H1). We represent them as linked lists.
|
* an |mNext| for the P or H1). We represent them as linked lists.
|
||||||
*/
|
*/
|
||||||
|
class inDOMUtils;
|
||||||
|
|
||||||
struct nsCSSSelectorList {
|
struct nsCSSSelectorList {
|
||||||
nsCSSSelectorList(void);
|
nsCSSSelectorList(void);
|
||||||
~nsCSSSelectorList(void);
|
~nsCSSSelectorList(void);
|
||||||
|
@ -250,9 +252,11 @@ struct nsCSSSelectorList {
|
||||||
nsCSSSelector* mSelectors;
|
nsCSSSelector* mSelectors;
|
||||||
int32_t mWeight;
|
int32_t mWeight;
|
||||||
nsCSSSelectorList* mNext;
|
nsCSSSelectorList* mNext;
|
||||||
private:
|
protected:
|
||||||
|
friend class inDOMUtils;
|
||||||
nsCSSSelectorList* Clone(bool aDeep) const;
|
nsCSSSelectorList* Clone(bool aDeep) const;
|
||||||
|
|
||||||
|
private:
|
||||||
nsCSSSelectorList(const nsCSSSelectorList& aCopy) MOZ_DELETE;
|
nsCSSSelectorList(const nsCSSSelectorList& aCopy) MOZ_DELETE;
|
||||||
nsCSSSelectorList& operator=(const nsCSSSelectorList& aCopy) MOZ_DELETE;
|
nsCSSSelectorList& operator=(const nsCSSSelectorList& aCopy) MOZ_DELETE;
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче