Fixed sorting issue with Css Selectors with same specificity.

This commit is contained in:
Nedyalko Nikolov
2016-06-14 15:11:11 +03:00
parent 58be9796b6
commit 9ac40a5acb
4 changed files with 58 additions and 5 deletions

View File

@ -12,6 +12,7 @@ import types = require("utils/types");
import viewModule = require("ui/core/view");
import styleModule = require("ui/styling/style");
import dependencyObservableModule = require("ui/core/dependency-observable");
import {StyleScope} from 'ui/styling/style-scope';
export function test_css_dataURI_is_applied_to_backgroundImageSource() {
var stack = new stackModule.StackLayout();
@ -1443,6 +1444,17 @@ export function test_CascadingClassNamesAppliesAfterPageLoad() {
helper.assertViewBackgroundColor(stack, "#FF0000");
});
}
export function test_SortingOfCssSelectorsWithSameSpecificity() {
let scope = new StyleScope();
scope.css = ".button { border-color: #b2b2b2; background-color: hotpink; color: #444; margin: 5; padding: 7 2; border-width: 1; border-style: solid; border-radius: 2; text-align: center; font-size: 18; line-height: 42; } .button-small { background-color: salmon; } .button-large { font-size: 26; } .button-light { border-color: #ddd; background-color: #fff; color: #444; } .button-stable { border-color: #b2b2b2; background-color: #f8f8f8; color: #444; } .button-positive { border-color: #0c60ee; background-color: #387ef5; color: #fff; } .button-calm { border-color: #0a9dc7;background-color: #11c1f3; color: #fff; } .button-balanced { border-color: #28a54c; background-color: #33cd5f; color: #fff; } .button-energized { border-color: #e6b500; background-color: #ffc900; color: #fff; } .button-assertive { border-color: #e42112; background-color: #ef473a; color: #fff; } .button-royal { border-color: #6b46e5; background-color: #886aea; color: #fff; } .button-dark { border-color: #111; background-color: #444; color: #fff; }";
scope.ensureSelectors();
let expressions = [];
(<any>scope)._mergedCssSelectors.forEach((v) => {
expressions.push(v.expression);
});
TKUnit.assertTrue(expressions.indexOf('button') < expressions.indexOf('button-calm'), "button class selector should be before button-calm selector.");
}
// <snippet module="ui/styling" title="styling">
// For information and example how to use style properties please refer to special [**Styling**](../../../styling.md) topic.
// </snippet>

View File

@ -191,7 +191,8 @@ export class StyleScope {
mergedResult.push.apply(mergedResult, arrays[i]);
}
}
mergedResult.sort((a, b) => a.specificity - b.specificity);
ensureUtils();
mergedResult = utils.mergeSort(mergedResult, (a, b) => { return a.specificity - b.specificity; });
return mergedResult;
}
@ -200,9 +201,9 @@ export class StyleScope {
this.ensureSelectors();
view.style._beginUpdate();
let i,
selector: cssSelector.CssSelector,
matchedStateSelectors = new Array<cssSelector.CssVisualStateSelector>()
let i;
let selector: cssSelector.CssSelector;
let matchedStateSelectors = new Array<cssSelector.CssVisualStateSelector>();
// Go trough all selectors - and directly apply all non-state selectors
for (i = 0; i < this._mergedCssSelectors.length; i++) {

View File

@ -134,3 +134,36 @@ export function isDataURI(uri: string): boolean {
return firstSegment && firstSegment.indexOf("data:") === 0 && firstSegment.indexOf('base64') >= 0;
}
export function mergeSort(arr, compareFunc) {
if (arr.length < 2) {
return arr;
}
let middle = arr.length / 2;
let left = arr.slice(0, middle);
let right = arr.slice(middle, arr.length);
return merge(mergeSort(left, compareFunc), mergeSort(right, compareFunc), compareFunc);
}
export function merge(left, right, compareFunc) {
let result = [];
while(left.length && right.length) {
if (compareFunc(left[0], right[0]) <= 0) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length) {
result.push(left.shift());
}
while (right.length) {
result.push(right.shift());
}
return result;
}

View File

@ -249,5 +249,12 @@
* Converts string value to number or boolean.
* @param value The original value.
*/
export function convertString(value: any): any
export function convertString(value: any): any
/**
* Sorts an array by using merge sort algoritm (which ensures stable sort since the built-in Array.sort() does not promise a stable sort).
* @param arr - array to be sorted
* @param compareFunc - function that will be used to compare two elements of the array
*/
export function mergeSort(arr: Array<any>, compareFunc: (a: any, b: any) => number): Array<any>
}