Bug 839103 - Part 11: Add StyleRule{Added,Removed,Changed} events. r=bz

This commit is contained in:
Cameron McCormack 2013-05-16 17:13:36 +10:00
parent f72487c6d0
commit f5a84d4c82
9 changed files with 126 additions and 15 deletions

View File

@ -68,12 +68,13 @@ function dynamicStylesheetAdded(evt) {
}
function dynamicStylesheetApplicableStateChanged(evt) {
gBrowser.removeEventListener("StyleSheetApplicableStateChanged", dynamicStylesheetApplicableStateChanged, true);
ok(true, "received dynamic style sheet applicable state change event");
is(evt.type, "StyleSheetApplicableStateChanged", "evt.type has expected value");
is(evt.target, gBrowser.contentDocument, "event targets correct document");
is(evt.stylesheet, gLinkElement.sheet, "evt.stylesheet has the right value");
is(evt.applicable, true, "evt.applicable has the right value");
gBrowser.removeEventListener("StyleSheetApplicableStateChanged", dynamicStylesheetApplicableStateChanged, true);
gBrowser.addEventListener("StyleSheetApplicableStateChanged", dynamicStylesheetApplicableStateChangedToFalse, true);
gLinkElement.disabled = true;
}
@ -85,6 +86,7 @@ function dynamicStylesheetApplicableStateChangedToFalse(evt) {
is(evt.target, gBrowser.contentDocument, "event targets correct document");
is(evt.stylesheet, gLinkElement.sheet, "evt.stylesheet has the right value");
is(evt.applicable, false, "evt.applicable has the right value");
gBrowser.addEventListener("StyleSheetRemoved", dynamicStylesheetRemoved, true);
gBrowser.contentDocument.body.removeChild(gLinkElement);
}
@ -97,7 +99,48 @@ function dynamicStylesheetRemoved(evt) {
ok(evt.stylesheet, "evt.stylesheet is defined");
ok(evt.stylesheet.toString().contains("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
ok(evt.stylesheet.href.contains(gStyleSheet), "evt.stylesheet is the removed stylesheet");
is(evt.rule, null, "evt.rule is null");
gBrowser.addEventListener("StyleRuleAdded", styleRuleAdded, true);
gBrowser.contentDocument.querySelector("style").sheet.insertRule("*{color:black}", 0);
}
function styleRuleAdded(evt) {
gBrowser.removeEventListener("StyleRuleAdded", styleRuleAdded, true);
ok(true, "received style rule added event");
is(evt.type, "StyleRuleAdded", "evt.type has expected value");
is(evt.target, gBrowser.contentDocument, "event targets correct document");
ok(evt.stylesheet, "evt.stylesheet is defined");
ok(evt.stylesheet.toString().contains("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
ok(evt.rule, "evt.rule is defined");
is(evt.rule.cssText, "* { color: black; }", "evt.rule.cssText has expected value");
gBrowser.addEventListener("StyleRuleChanged", styleRuleChanged, true);
evt.rule.style.cssText = "color:green";
}
function styleRuleChanged(evt) {
gBrowser.removeEventListener("StyleRuleChanged", styleRuleChanged, true);
ok(true, "received style rule changed event");
is(evt.type, "StyleRuleChanged", "evt.type has expected value");
is(evt.target, gBrowser.contentDocument, "event targets correct document");
ok(evt.stylesheet, "evt.stylesheet is defined");
ok(evt.stylesheet.toString().contains("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
ok(evt.rule, "evt.rule is defined");
is(evt.rule.cssText, "* { color: green; }", "evt.rule.cssText has expected value");
gBrowser.addEventListener("StyleRuleRemoved", styleRuleRemoved, true);
evt.stylesheet.deleteRule(0);
}
function styleRuleRemoved(evt) {
gBrowser.removeEventListener("StyleRuleRemoved", styleRuleRemoved, true);
ok(true, "received style rule removed event");
is(evt.type, "StyleRuleRemoved", "evt.type has expected value");
is(evt.target, gBrowser.contentDocument, "event targets correct document");
ok(evt.stylesheet, "evt.stylesheet is defined");
ok(evt.stylesheet.toString().contains("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
ok(evt.rule, "evt.rule is defined");
executeSoon(concludeTest);
}

View File

@ -3,6 +3,7 @@
<head>
<title>Document for Bug 839103</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style></style>
</head>
<body>
</body>

View File

@ -137,6 +137,7 @@
#include "nsIPrompt.h"
#include "nsIPropertyBag2.h"
#include "nsIDOMPageTransitionEvent.h"
#include "nsIDOMStyleRuleChangeEvent.h"
#include "nsIDOMStyleSheetChangeEvent.h"
#include "nsIDOMStyleSheetApplicableStateChangeEvent.h"
#include "nsJSUtils.h"
@ -202,6 +203,8 @@
#include "nsITextControlElement.h"
#include "nsIDOMNSEditableElement.h"
#include "nsIEditor.h"
#include "nsIDOMCSSStyleRule.h"
#include "mozilla/css/Rule.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -3904,8 +3907,6 @@ nsDocument::SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
}
}
#undef DO_STYLESHEET_NOTIFICATION
// These three functions are a lot like the implementation of the
// corresponding API for regular stylesheets.
@ -4633,31 +4634,60 @@ nsDocument::DocumentStatesChanged(nsEventStates aStateMask)
}
void
nsDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet,
nsDocument::StyleRuleChanged(nsIStyleSheet* aSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged,
(this, aStyleSheet,
(this, aSheet,
aOldStyleRule, aNewStyleRule));
if (StyleSheetChangeEventsEnabled()) {
nsCOMPtr<css::Rule> rule = do_QueryInterface(aNewStyleRule);
DO_STYLESHEET_NOTIFICATION(NS_NewDOMStyleRuleChangeEvent,
nsIDOMStyleRuleChangeEvent,
InitStyleRuleChangeEvent,
"StyleRuleChanged",
rule ? rule->GetDOMRule() : nullptr);
}
}
void
nsDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet,
nsDocument::StyleRuleAdded(nsIStyleSheet* aSheet,
nsIStyleRule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded,
(this, aStyleSheet, aStyleRule));
(this, aSheet, aStyleRule));
if (StyleSheetChangeEventsEnabled()) {
nsCOMPtr<css::Rule> rule = do_QueryInterface(aStyleRule);
DO_STYLESHEET_NOTIFICATION(NS_NewDOMStyleRuleChangeEvent,
nsIDOMStyleRuleChangeEvent,
InitStyleRuleChangeEvent,
"StyleRuleAdded",
rule ? rule->GetDOMRule() : nullptr);
}
}
void
nsDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
nsDocument::StyleRuleRemoved(nsIStyleSheet* aSheet,
nsIStyleRule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved,
(this, aStyleSheet, aStyleRule));
(this, aSheet, aStyleRule));
if (StyleSheetChangeEventsEnabled()) {
nsCOMPtr<css::Rule> rule = do_QueryInterface(aStyleRule);
DO_STYLESHEET_NOTIFICATION(NS_NewDOMStyleRuleChangeEvent,
nsIDOMStyleRuleChangeEvent,
InitStyleRuleChangeEvent,
"StyleRuleRemoved",
rule ? rule->GetDOMRule() : nullptr);
}
}
#undef DO_STYLESHEET_NOTIFICATION
//
// nsIDOMDocument interface

View File

@ -46,6 +46,7 @@ XPIDL_SOURCES += [
'nsIDOMScrollAreaEvent.idl',
'nsIDOMSimpleGestureEvent.idl',
'nsIDOMSmartCardEvent.idl',
'nsIDOMStyleRuleChangeEvent.idl',
'nsIDOMStyleSheetChangeEvent.idl',
'nsIDOMStyleSheetApplicableStateChangeEvent.idl',
'nsIDOMTouchEvent.idl',

View File

@ -0,0 +1,28 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIDOMEvent.idl"
interface nsIDOMCSSRule;
interface nsIDOMCSSStyleSheet;
[scriptable, builtinclass, uuid(36098d39-b471-47e9-976e-33fee3d81467)]
interface nsIDOMStyleRuleChangeEvent : nsIDOMEvent
{
readonly attribute nsIDOMCSSStyleSheet stylesheet;
readonly attribute nsIDOMCSSRule rule;
[noscript] void initStyleRuleChangeEvent(in DOMString aTypeArg,
in boolean aCanBubbleArg,
in boolean aCancelableArg,
in nsIDOMCSSStyleSheet aStyleSheet,
in nsIDOMCSSRule aRule);
};
dictionary StyleRuleChangeEventInit : EventInit
{
nsIDOMCSSStyleSheet stylesheet;
nsIDOMCSSRule rule;
};

View File

@ -546,6 +546,7 @@ var interfaceNamesInGlobalScope =
"SpeechRecognitionError",
"SpeechSynthesisEvent",
"PushManager",
"StyleRuleChangeEvent",
"StyleSheetChangeEvent",
"StyleSheetApplicableStateChangeEvent",
"MozMobileMessageThread",

View File

@ -24,6 +24,7 @@ simple_events = [
'DeviceLightEvent',
'MozApplicationEvent',
'SmartCardEvent',
'StyleRuleChangeEvent',
'StyleSheetChangeEvent',
'StyleSheetApplicableStateChangeEvent',
#ifdef MOZ_B2G_BT

View File

@ -1386,12 +1386,13 @@ StyleRule::Clone() const
/* virtual */ nsIDOMCSSRule*
StyleRule::GetDOMRule()
{
if (!GetStyleSheet()) {
// inline style rules aren't supposed to have a DOM rule object, only
// a declaration.
return nullptr;
}
if (!mDOMRule) {
if (!GetStyleSheet()) {
// Inline style rules aren't supposed to have a DOM rule object, only
// a declaration. But if we do have one already, from a style sheet
// rule that used to be in a document, we still want to return it.
return nullptr;
}
mDOMRule = new DOMCSSStyleRule(this);
NS_ADDREF(mDOMRule);
}

View File

@ -2035,6 +2035,11 @@ nsCSSStyleSheet::DeleteRule(uint32_t aIndex)
nsRefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(aIndex);
if (rule) {
mInner->mOrderedRules.RemoveObjectAt(aIndex);
if (mDocument && mDocument->StyleSheetChangeEventsEnabled()) {
// Force creation of the DOM rule, so that it can be put on the
// StyleRuleRemoved event object.
rule->GetDOMRule();
}
rule->SetStyleSheet(nullptr);
DidDirty();