Handle effects of medium feature changes on XBL style sheets. (Bug 156716) r+sr=bzbarsky

This commit is contained in:
L. David Baron 2008-07-26 09:14:49 -07:00
Родитель b2c415253b
Коммит 65ceaca225
8 изменённых файлов: 144 добавлений и 8 удалений

Просмотреть файл

@ -77,6 +77,7 @@
#include "nsDOMCID.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsIScriptGlobalObject.h"
#include "nsTHashtable.h"
#include "nsIScriptContext.h"
#include "nsBindingManager.h"
@ -1234,8 +1235,7 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
}
nsresult
nsBindingManager::WalkRules(nsStyleSet* aStyleSet,
nsIStyleRuleProcessor::EnumFunc aFunc,
nsBindingManager::WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc,
RuleProcessorData* aData,
PRBool* aCutOffInheritance)
{
@ -1280,6 +1280,63 @@ nsBindingManager::WalkRules(nsStyleSet* aStyleSet,
return NS_OK;
}
typedef nsTHashtable<nsVoidPtrHashKey> RuleProcessorSet;
PR_STATIC_CALLBACK(PLDHashOperator)
EnumRuleProcessors(nsISupports *aKey, nsXBLBinding *aBinding, void* aClosure)
{
RuleProcessorSet *set = static_cast<RuleProcessorSet*>(aClosure);
for (nsXBLBinding *binding = aBinding; binding;
binding = binding->GetBaseBinding()) {
nsIStyleRuleProcessor *ruleProc =
binding->PrototypeBinding()->GetRuleProcessor();
if (ruleProc) {
if (!set->IsInitialized() && !set->Init(16))
return PL_DHASH_STOP;
set->PutEntry(ruleProc);
}
}
return PL_DHASH_NEXT;
}
struct MediumFeaturesChangedData {
nsPresContext *mPresContext;
PRBool *mRulesChanged;
};
PR_STATIC_CALLBACK(PLDHashOperator)
EnumMediumFeaturesChanged(nsVoidPtrHashKey *aKey, void* aClosure)
{
nsIStyleRuleProcessor *ruleProcessor =
static_cast<nsIStyleRuleProcessor*>(const_cast<void*>(aKey->GetKey()));
MediumFeaturesChangedData *data =
static_cast<MediumFeaturesChangedData*>(aClosure);
PRBool thisChanged = PR_FALSE;
ruleProcessor->MediumFeaturesChanged(data->mPresContext, &thisChanged);
*data->mRulesChanged = *data->mRulesChanged || thisChanged;
return PL_DHASH_NEXT;
}
nsresult
nsBindingManager::MediumFeaturesChanged(nsPresContext* aPresContext,
PRBool* aRulesChanged)
{
*aRulesChanged = PR_FALSE;
if (!mBindingTable.IsInitialized())
return NS_OK;
RuleProcessorSet set;
mBindingTable.EnumerateRead(EnumRuleProcessors, &set);
if (!set.IsInitialized())
return NS_OK;
MediumFeaturesChangedData data = { aPresContext, aRulesChanged };
set.EnumerateEntries(EnumMediumFeaturesChanged, &data);
return NS_OK;
}
PRBool
nsBindingManager::ShouldBuildChildFrames(nsIContent* aContent)
{

Просмотреть файл

@ -184,10 +184,16 @@ public:
PRBool ShouldBuildChildFrames(nsIContent* aContent);
// Style rule methods
nsresult WalkRules(nsStyleSet* aStyleSet,
nsIStyleRuleProcessor::EnumFunc aFunc,
nsresult WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc,
RuleProcessorData* aData,
PRBool* aCutOffInheritance);
/**
* Do any processing that needs to happen as a result of a change in
* the characteristics of the medium, and return whether this rule
* processor's rules have changed (e.g., because of media queries).
*/
nsresult MediumFeaturesChanged(nsPresContext* aPresContext,
PRBool* aRulesChanged);
NS_HIDDEN_(void) Traverse(nsIContent *aContent,
nsCycleCollectionTraversalCallback &cb);

Просмотреть файл

@ -533,8 +533,7 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
PRBool cutOffInheritance = PR_FALSE;
if (mBindingManager) {
// We can supply additional document-level sheets that should be walked.
mBindingManager->WalkRules(this, aCollectorFunc, aData,
&cutOffInheritance);
mBindingManager->WalkRules(aCollectorFunc, aData, &cutOffInheritance);
}
if (!skipUserStyles && !cutOffInheritance &&
mRuleProcessors[eDocSheet]) // NOTE: different
@ -594,7 +593,7 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
PRBool cutOffInheritance = PR_FALSE;
if (mBindingManager) {
// We can supply additional document-level sheets that should be walked.
mBindingManager->WalkRules(this, aFunc, aData, &cutOffInheritance);
mBindingManager->WalkRules(aFunc, aData, &cutOffInheritance);
}
if (!skipUserStyles && !cutOffInheritance &&
mRuleProcessors[eDocSheet]) // NOTE: different
@ -968,7 +967,6 @@ PRBool
nsStyleSet::MediumFeaturesChanged(nsPresContext* aPresContext)
{
// We can't use WalkRuleProcessors without a content node.
// XXX We don't notify mBindingManager. Should we?
PRBool stylesChanged = PR_FALSE;
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mRuleProcessors); ++i) {
nsIStyleRuleProcessor *processor = mRuleProcessors[i];
@ -980,5 +978,11 @@ nsStyleSet::MediumFeaturesChanged(nsPresContext* aPresContext)
stylesChanged = stylesChanged || thisChanged;
}
if (mBindingManager) {
PRBool thisChanged = PR_FALSE;
mBindingManager->MediumFeaturesChanged(aPresContext, &thisChanged);
stylesChanged = stylesChanged || thisChanged;
}
return stylesChanged;
}

Просмотреть файл

@ -104,6 +104,7 @@ _TEST_FILES = test_acid3_test46.html \
test_initial_computation.html \
test_initial_storage.html \
test_media_queries.html \
test_media_queries_dynamic_xbl.html \
test_of_type_selectors.xhtml \
test_parse_rule.html \
test_property_database.html \
@ -131,6 +132,9 @@ _TEST_FILES = test_acid3_test46.html \
xbl_bindings.xml \
empty.html \
media_queries_iframe.html \
media_queries_dynamic_xbl_binding.xml \
media_queries_dynamic_xbl_iframe.html \
media_queries_dynamic_xbl_style.css \
$(NULL)

Просмотреть файл

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="binding">
<resources>
<stylesheet src="media_queries_dynamic_xbl_style.css" />
</resources>
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml">
<children/>
</html:div>
</content>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,5 @@
<!DOCTYPE HTML>
<style type="text/css">
body { -moz-binding: url(media_queries_dynamic_xbl_binding.xml#binding); }
</style>
<p id="para">Hello</p>

Просмотреть файл

@ -0,0 +1,6 @@
@media (orientation: portrait) {
div { color: purple; }
}
@media (orientation: landscape) {
div { color: blue; }
}

Просмотреть файл

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=156716
-->
<head>
<title>Test for Bug 156716</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="run()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=156716">Mozilla Bug 156716</a>
<iframe id="display" src="media_queries_dynamic_xbl_iframe.html"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 156716 **/
function run() {
var iframe = document.getElementById("display");
var subdoc = iframe.contentDocument;
var subwin = iframe.contentWindow;
var p = subdoc.getElementById("para");
iframe.setAttribute("style", "height: 300px; width: 100px");
is(subwin.getComputedStyle(p, "").color, "rgb(128, 0, 128)",
"should be purple when portait");
iframe.setAttribute("style", "height: 100px; width: 300px");
is(subwin.getComputedStyle(p, "").color, "rgb(0, 0, 255)",
"should be blue when landscape");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>