Avoid applying CSS multiple times (#4784)

* Move the applyStyleFromScope to onLoaded, when the views are created and id or className properties are set the CSS selectors are queried and applied multiple times

* Condense the changes when applying properties
This commit is contained in:
Panayot Cankov
2017-09-25 18:32:00 +03:00
committed by SvetoslavTsenov
parent b0577728be
commit 6d7c1ff295
25 changed files with 536 additions and 524 deletions

View File

@@ -1,7 +1,7 @@
import * as helper from "../helper";
import * as btnCounter from "./pages/button-counter";
import * as TKUnit from "../../TKUnit";
import { isIOS } from "tns-core-modules/platform";
import { isIOS, isAndroid } from "tns-core-modules/platform";
// Integration tests that asser sertain runtime behavior, lifecycle events atc.
@@ -118,4 +118,51 @@ export function test_navigating_away_does_not_excessively_reset() {
// NOTE: Recycling may mess this up so feel free to change the test,
// but ensure a reasonable amount of native setters were called when the views navigate away
assert(1);
}
}
export function test_css_sets_properties() {
const page = helper.navigateToModule("ui/lifecycle/pages/page-two");
const buttons = ["btn1", "btn2", "btn3", "btn4"].map(id => page.getViewById<btnCounter.Button>(id));
buttons.forEach(btn => {
TKUnit.assertEqual(btn.colorSetNativeCount, 1, `Expected ${btn.id}'s native color to propagated exactly once when inflating from xml.`);
TKUnit.assertEqual(btn.colorPropertyChangeCount, 1, `Expected ${btn.id}'s colorChange to be fired exactly once when inflating from xml.`);
});
buttons.forEach(btn => {
btn.className = "";
});
const expectedChangesAfterClearingClasses = [1, 2, 2, 2];
for (var i = 0; i < buttons.length; i++) {
TKUnit.assertEqual(buttons[i].colorSetNativeCount, expectedChangesAfterClearingClasses[i], `Expected ${buttons[i].id} native set after clear.`);
TKUnit.assertEqual(buttons[i].colorPropertyChangeCount, expectedChangesAfterClearingClasses[i], `Expected ${buttons[i].id} change notifications after clear.`);
}
buttons[0].className = "nocolor";
buttons[1].className = "red";
buttons[2].className = "blue";
buttons[3].className = "red blue";
const expectedChangesAfterResettingClasses = [1, 3, 3, 3];
for (let i = 0; i < buttons.length; i++) {
TKUnit.assertEqual(buttons[i].colorSetNativeCount, expectedChangesAfterResettingClasses[i], `Expected ${buttons[i].id} native set after classes are reapplied.`);
TKUnit.assertEqual(buttons[i].colorPropertyChangeCount, expectedChangesAfterResettingClasses[i], `Expected ${buttons[i].id} change notifications classes are reapplied.`);
}
const stack: any = page.getViewById("stack");
page.content = null;
for (let i = 0; i < buttons.length; i++) {
TKUnit.assertEqual(buttons[i].colorSetNativeCount, expectedChangesAfterResettingClasses[i], `Expected ${buttons[i].id} native set to not be called when removed from page.`);
TKUnit.assertEqual(buttons[i].colorPropertyChangeCount, expectedChangesAfterResettingClasses[i], `Expected ${buttons[i].id} change notifications for css properties to not occur when removed from page.`);
}
page.content = stack;
// TODO: The check counts here should be the same as the counts before removing from the page.
const expectedNativeSettersAfterReaddedToPage = isAndroid ? [2, 4, 4, 4] : expectedChangesAfterResettingClasses;
for (let i = 0; i < buttons.length; i++) {
TKUnit.assertEqual(buttons[i].colorSetNativeCount, expectedNativeSettersAfterReaddedToPage[i], `Expected ${buttons[i].id} native set to not be called when added to page.`);
TKUnit.assertEqual(buttons[i].colorPropertyChangeCount, expectedChangesAfterResettingClasses[i], `Expected ${buttons[i].id} change notifications for css properties to not occur when added to page.`);
}
}

View File

@@ -5,6 +5,13 @@ export class Button extends button.Button {
nativeBackgroundRedraws = 0;
backgroundInternalSetNativeCount = 0;
fontInternalSetNativeCount = 0;
colorSetNativeCount = 0;
colorPropertyChangeCount = 0;
constructor() {
super();
this.style.on("colorChange", () => this.colorPropertyChangeCount++);
}
[view.backgroundInternalProperty.setNative](value) {
this.backgroundInternalSetNativeCount++;
@@ -18,5 +25,9 @@ export class Button extends button.Button {
this.nativeBackgroundRedraws++;
super._redrawNativeBackground(value);
}
[view.colorProperty.setNative](value) {
this.colorSetNativeCount++;
return super[view.colorProperty.setNative](value);
}
}
Button.prototype.recycleNativeView = "never";

View File

@@ -0,0 +1,15 @@
Button {
color: orange;
}
.red {
color: red;
}
.blue {
color: blue;
}
.nocolor {
background: red;
}

View File

@@ -0,0 +1,8 @@
<Page xmlns:btnCount="ui/lifecycle/pages/button-counter">
<StackLayout id="stack">
<btnCount:Button id="btn1" text="one" class="nocolor" />
<btnCount:Button id="btn2" text="two" class="red" />
<btnCount:Button id="btn3" text="three" class="blue" />
<btnCount:Button id="btn4" text="four" class="red blue" />
</StackLayout>
</Page>