зеркало из https://github.com/mozilla/pjs.git
Handle effects of medium feature changes on XBL style sheets. (Bug 156716) r+sr=bzbarsky
This commit is contained in:
Родитель
b2c415253b
Коммит
65ceaca225
|
@ -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>
|
||||
|
Загрузка…
Ссылка в новой задаче