Diff
Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog 2019-02-18 16:17:10 UTC (rev 241714)
@@ -1,3 +1,24 @@
+2019-02-17 Matt Baker <mattba...@apple.com>
+
+ Web Inspector: Frontend performance is very slow reloading theverge.com - 50% of time in TreeOutline _indexOfTreeElement
+ https://bugs.webkit.org/show_bug.cgi?id=193605
+ <rdar://problem/47403986>
+
+ Reviewed by Devin Rousso.
+
+ * inspector/table/resources/table-utilities.js:
+ (TestPage.registerInitializer.InspectorTest.TableDataSource.prototype.tableIndexForRepresentedObject):
+ (TestPage.registerInitializer.InspectorTest.TableDataSource.prototype.tableRepresentedObjectForIndex):
+ (TestPage.registerInitializer.InspectorTest.TableDataSource):
+ New Table data source methods.
+
+ * inspector/unit-tests/index-set-expected.txt: Removed.
+ * inspector/unit-tests/index-set.html: Removed.
+ * inspector/unit-tests/set-utilities-expected.txt:
+ * inspector/unit-tests/set-utilities.html:
+ Remove IndexSet tests and update tests for Set utilities to include new
+ helper methods `equals` and `difference`, and `firstValue`.
+
2019-02-16 Zalan Bujtas <za...@apple.com>
[LFC] Apply min/max width constraints to preferred width computation
Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/table/resources/table-utilities.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/table/resources/table-utilities.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/table/resources/table-utilities.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -12,6 +12,16 @@
{
return this._items.length;
}
+
+ tableIndexForRepresentedObject(table, object)
+ {
+ return this._items.indexOf(object);
+ }
+
+ tableRepresentedObjectForIndex(table, index)
+ {
+ return this._items[index];
+ }
};
InspectorTest.TableDelegate = class TableDelegate
Deleted: releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/index-set-expected.txt (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/index-set-expected.txt 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/index-set-expected.txt 2019-02-18 16:17:10 UTC (rev 241714)
@@ -1,153 +0,0 @@
-Tests for WI.IndexSet.
-
-
-== Running test suite: IndexSet
--- Running test case: IndexSet.constructor
-PASS: size should be zero.
-PASS: firstIndex should be NaN.
-PASS: lastIndex should be NaN.
-PASS: Should be [].
-
--- Running test case: IndexSet.constructor array
-Initialize IndexSet with an array.
-PASS: size should be 5.
-PASS: firstIndex should be 0.
-PASS: lastIndex should be 100.
-PASS: Should be [0,1,5,50,100].
-Initialize IndexSet with an array containing duplicate indexes.
-PASS: size should be 5.
-PASS: Should be [0,1,5,50,100].
-
--- Running test case: IndexSet.constructor invalid
-PASS: size should be zero.
-
--- Running test case: IndexSet.prototype.clear
-PASS: size should be zero.
-PASS: firstIndex should be NaN.
-PASS: lastIndex should be NaN.
-PASS: Should be [].
-
--- Running test case: IndexSet.prototype.add
-PASS: size should be 1.
-PASS: has should return true.
-
--- Running test case: IndexSet.prototype.add duplicate
-PASS: size should be 1.
-
--- Running test case: IndexSet.prototype.add invalid
-PASS: size should be zero.
-
--- Running test case: IndexSet.prototype.delete
-Given an IndexSet with values [1,2,3]:
-PASS: delete 3 should succeed.
-PASS: has 3 should return false.
-
--- Running test case: IndexSet.prototype.delete nonexistent
-Given an IndexSet with values [1,2,3]:
-PASS: delete 4 should fail.
-
--- Running test case: IndexSet.prototype.delete invalid
--- Running test case: IndexSet.prototype[Symbol.iterator]
-Given an IndexSet with values [20,1,10,2]:
-1
-2
-10
-20
-
--- Running test case: IndexSet.prototype.indexGreaterThan
-Given an IndexSet with values [1,2]:
-PASS: Index greater than 0 should be 1.
-PASS: Index greater than 1 should be 2.
-PASS: Index greater than 2 should be NaN.
-PASS: Index greater than 3 should be NaN.
-
--- Running test case: IndexSet.prototype.indexLessThan
-Given an IndexSet with values [1,2]:
-PASS: Index less than 0 should be NaN.
-PASS: Index less than 1 should be NaN.
-PASS: Index less than 2 should be 1.
-PASS: Index less than 3 should be 2.
-
--- Running test case: IndexSet.prototype.copy
-PASS: Copy and original should be different objects.
-PASS: Copy and original should have the same values.
-
--- Running test case: IndexSet.prototype.addRange
-Given an IndexSet with values []:
-Add range to an empty IndexSet.
-PASS: Should be [1,2,3] after adding [1,2,3].
-
-Given an IndexSet with values [10,11,12]:
-Add range before the beginning.
-PASS: Should be [0,1,2,10,11,12] after adding [0,1,2].
-
-Given an IndexSet with values [1,2,3]:
-Add range after the end.
-PASS: Should be [1,2,3,10,11,12] after adding [10,11,12].
-
-Given an IndexSet with values [1,5]:
-Add range in the middle.
-PASS: Should be [1,2,3,4,5] after adding [2,3,4].
-
-Given an IndexSet with values [1,3,5]:
-Add range overlapping the middle.
-PASS: Should be [1,2,3,4,5] after adding [2,3,4].
-
-Given an IndexSet with values [3,4,5]:
-Add range overlapping the beginning.
-PASS: Should be [1,2,3,4,5] after adding [1,2,3].
-
-Given an IndexSet with values [1,2,3]:
-Add range overlapping the end.
-PASS: Should be [1,2,3,4,5] after adding [3,4,5].
-
-
--- Running test case: IndexSet.prototype.deleteRange
-Given an IndexSet with values []:
-Remove range from an empty IndexSet.
-PASS: Should be [] after removing [1,2,3].
-
-Given an IndexSet with values [10,11,12]:
-Remove range before the beginning.
-PASS: Should be [10,11,12] after removing [0,1,2].
-
-Given an IndexSet with values [0,1,2]:
-Remove range after the end.
-PASS: Should be [0,1,2] after removing [10,11,12].
-
-Given an IndexSet with values [0,1,2,3]:
-Remove range in the middle.
-PASS: Should be [0,3] after removing [1,2].
-
-Given an IndexSet with values [1,3,5]:
-Remove range overlapping the middle.
-PASS: Should be [1,5] after removing [2,3,4].
-
-Given an IndexSet with values [1,2,3]:
-Remove range overlapping the beginning.
-PASS: Should be [3] after removing [0,1,2].
-
-Given an IndexSet with values [1,2,3]:
-Remove range overlapping the end.
-PASS: Should be [1] after removing [2,3,4].
-
-
--- Running test case: IndexSet.prototype.equals
-PASS: Should trivially equal itself.
-PASS: Copy and original should be equal.
-PASS: Modified copy and original should not be equal.
-
--- Running test case: IndexSet.prototype.difference
-Given an IndexSet with values [], and another IndexSet with values []:
-PASS: Difference between the first and second IndexSet should be [].
-
-Given an IndexSet with values [1,2,3], and another IndexSet with values []:
-PASS: Difference between the first and second IndexSet should be [1,2,3].
-
-Given an IndexSet with values [], and another IndexSet with values [1,2,3]:
-PASS: Difference between the first and second IndexSet should be [].
-
-Given an IndexSet with values [1,2,3], and another IndexSet with values [2,3,4]:
-PASS: Difference between the first and second IndexSet should be [1].
-
-
Deleted: releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/index-set.html (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/index-set.html 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/index-set.html 2019-02-18 16:17:10 UTC (rev 241714)
@@ -1,424 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<script src=""
-<script>
-function test()
-{
- let suite = InspectorTest.createSyncSuite("IndexSet");
-
- function createIndexSet(values = []) {
- if (!Array.isArray(values))
- values = [values];
- InspectorTest.log(`Given an IndexSet with values [${values}]:`);
-
- return new WI.IndexSet(values);
- }
-
- function rangeToArray(startIndex, count) {
- let result = [];
- for (let i = 0; i < count; ++i)
- result.push(startIndex + i);
- return result;
- }
-
- suite.addTestCase({
- name: "IndexSet.constructor",
- test() {
- let indexSet = new WI.IndexSet;
- InspectorTest.expectEqual(indexSet.size, 0, "size should be zero.");
- InspectorTest.expectThat(isNaN(indexSet.firstIndex), "firstIndex should be NaN.");
- InspectorTest.expectThat(isNaN(indexSet.lastIndex), "lastIndex should be NaN.");
- InspectorTest.expectShallowEqual(Array.from(indexSet), [], "Should be [].");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.constructor array",
- test() {
- const values = [5, 1, 0, 100, 50];
- const sortedValues = values.slice().sort((a, b) => a - b);
-
- InspectorTest.log("Initialize IndexSet with an array.");
- {
- let indexSet = new WI.IndexSet(values);
- InspectorTest.expectEqual(indexSet.size, values.length, `size should be ${values.length}.`);
- InspectorTest.expectEqual(indexSet.firstIndex, sortedValues[0], `firstIndex should be ${sortedValues[0]}.`);
- InspectorTest.expectEqual(indexSet.lastIndex, sortedValues.lastValue, `lastIndex should be ${sortedValues.lastValue}.`);
- InspectorTest.expectShallowEqual(Array.from(indexSet), sortedValues, `Should be [${sortedValues}].`);
- }
-
- InspectorTest.log("Initialize IndexSet with an array containing duplicate indexes.");
- {
- let indexSet = new WI.IndexSet(values.concat(values));
- InspectorTest.expectEqual(indexSet.size, values.length, `size should be ${values.length}.`);
- InspectorTest.expectShallowEqual(Array.from(indexSet), sortedValues, `Should be [${sortedValues}].`);
- }
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.constructor invalid",
- test() {
- let indexSet = new WI.IndexSet([-1, 1.5, "abc"]);
- InspectorTest.expectEqual(indexSet.size, 0, "size should be zero.");
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.clear",
- test() {
- let indexSet = new WI.IndexSet([1, 2, 3]);
- indexSet.add(42);
- indexSet.clear();
- InspectorTest.expectEqual(indexSet.size, 0, "size should be zero.");
- InspectorTest.expectThat(isNaN(indexSet.firstIndex), "firstIndex should be NaN.");
- InspectorTest.expectThat(isNaN(indexSet.lastIndex), "lastIndex should be NaN.");
- InspectorTest.expectShallowEqual(Array.from(indexSet), [], "Should be [].");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.add",
- test() {
- let indexSet = new WI.IndexSet;
- indexSet.add(42);
- InspectorTest.expectEqual(indexSet.size, 1, "size should be 1.");
- InspectorTest.expectThat(indexSet.has(42), "has should return true.");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.add duplicate",
- test() {
- let indexSet = new WI.IndexSet;
- indexSet.add(42);
- indexSet.add(42);
- InspectorTest.expectEqual(indexSet.size, 1, "size should be 1.");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.add invalid",
- test() {
- let indexSet = new WI.IndexSet;
- indexSet.add(-1);
- indexSet.add(1.5);
- indexSet.add("abc");
- InspectorTest.expectEqual(indexSet.size, 0, "size should be zero.");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.delete",
- test() {
- let indexSet = createIndexSet([1, 2, 3]);
- const indexToDelete = indexSet.lastIndex;
- let wasDeleted = indexSet.delete(indexToDelete);
- InspectorTest.expectThat(wasDeleted, `delete ${indexToDelete} should succeed.`);
- InspectorTest.expectFalse(indexSet.has(indexToDelete), `has ${indexToDelete} should return false.`);
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.delete nonexistent",
- test() {
- let indexSet = createIndexSet([1, 2, 3]);
- const indexToDelete = indexSet.lastIndex + 1;
- let wasDeleted = indexSet.delete(indexToDelete);
- InspectorTest.expectFalse(wasDeleted, `delete ${indexToDelete} should fail.`);
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.delete invalid",
- test() {
- let indexSet = new WI.IndexSet;
- indexSet.delete(-1);
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype[Symbol.iterator]",
- test() {
- let indexSet = createIndexSet([20, 1, 10, 2]);
- for (let index of indexSet)
- InspectorTest.log(index);
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.indexGreaterThan",
- test() {
- let indexSet = createIndexSet([1, 2]);
- const {firstIndex, lastIndex} = indexSet;
- const indexBefore = firstIndex - 1;
- const indexAfter = lastIndex + 1;
- InspectorTest.expectEqual(indexSet.indexGreaterThan(indexBefore), firstIndex, `Index greater than ${indexBefore} should be ${firstIndex}.`);
- InspectorTest.expectEqual(indexSet.indexGreaterThan(firstIndex), lastIndex, `Index greater than ${firstIndex} should be ${lastIndex}.`);
- InspectorTest.expectThat(isNaN(indexSet.indexGreaterThan(lastIndex)), `Index greater than ${lastIndex} should be NaN.`);
- InspectorTest.expectThat(isNaN(indexSet.indexGreaterThan(indexAfter)), `Index greater than ${indexAfter} should be NaN.`);
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.indexLessThan",
- test() {
- let indexSet = createIndexSet([1, 2]);
- const {firstIndex, lastIndex} = indexSet;
- const indexBefore = firstIndex - 1;
- const indexAfter = lastIndex + 1;
-
- InspectorTest.expectThat(isNaN(indexSet.indexLessThan(indexBefore)), `Index less than ${indexBefore} should be NaN.`);
- InspectorTest.expectThat(isNaN(indexSet.indexLessThan(firstIndex)), `Index less than ${firstIndex} should be NaN.`);
- InspectorTest.expectEqual(indexSet.indexLessThan(lastIndex), firstIndex, `Index less than ${lastIndex} should be ${firstIndex}.`);
- InspectorTest.expectEqual(indexSet.indexLessThan(indexAfter), lastIndex, `Index less than ${indexAfter} should be ${lastIndex}.`);
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.copy",
- test() {
- let original = new WI.IndexSet([1, 2, 3]);
- let copied = original.copy();
- InspectorTest.expectNotEqual(copied, original, "Copy and original should be different objects.");
- InspectorTest.expectShallowEqual(Array.from(copied), Array.from(original), "Copy and original should have the same values.");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.addRange",
- test() {
- function testAddRange({description, initialValues, startIndex, count, expectedValues}) {
- let indexSet = createIndexSet(initialValues || []);
-
- InspectorTest.log(description);
- indexSet.addRange(startIndex, count);
- InspectorTest.expectShallowEqual(Array.from(indexSet), expectedValues, `Should be [${expectedValues}] after adding [${rangeToArray(startIndex, count)}].`);
- InspectorTest.log("");
- }
-
- testAddRange({
- description: "Add range to an empty IndexSet.",
- initialValues: [],
- startIndex: 1,
- count: 3,
- expectedValues: [1, 2, 3],
- });
-
- testAddRange({
- description: "Add range before the beginning.",
- initialValues: [10, 11, 12],
- startIndex: 0,
- count: 3,
- expectedValues: [0, 1, 2, 10, 11, 12],
- });
-
- testAddRange({
- description: "Add range after the end.",
- initialValues: [1, 2, 3],
- startIndex: 10,
- count: 3,
- expectedValues: [1, 2, 3, 10, 11, 12],
- });
-
- testAddRange({
- description: "Add range in the middle.",
- initialValues: [1, 5],
- startIndex: 2,
- count: 3,
- expectedValues: [1, 2, 3, 4, 5],
- });
-
- testAddRange({
- description: "Add range overlapping the middle.",
- initialValues: [1, 3, 5],
- startIndex: 2,
- count: 3,
- expectedValues: [1, 2, 3, 4, 5],
- });
-
- testAddRange({
- description: "Add range overlapping the beginning.",
- initialValues: [3, 4, 5],
- startIndex: 1,
- count: 3,
- expectedValues: [1, 2, 3, 4, 5],
- });
-
- testAddRange({
- description: "Add range overlapping the end.",
- initialValues: [1, 2, 3],
- startIndex: 3,
- count: 3,
- expectedValues: [1, 2, 3, 4, 5],
- });
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.deleteRange",
- test() {
- function testDeleteRange({description, initialValues, startIndex, count, expectedValues}) {
- let indexSet = createIndexSet(initialValues || []);
-
- InspectorTest.log(description);
- indexSet.deleteRange(startIndex, count);
- InspectorTest.expectShallowEqual(Array.from(indexSet), expectedValues, `Should be [${expectedValues}] after removing [${rangeToArray(startIndex, count)}].`);
- InspectorTest.log("");
- }
-
- testDeleteRange({
- description: "Remove range from an empty IndexSet.",
- initialValues: [],
- startIndex: 1,
- count: 3,
- expectedValues: [],
- });
-
- testDeleteRange({
- description: "Remove range before the beginning.",
- initialValues: [10, 11, 12],
- startIndex: 0,
- count: 3,
- expectedValues: [10, 11, 12],
- });
-
- testDeleteRange({
- description: "Remove range after the end.",
- initialValues: [0, 1, 2],
- startIndex: 10,
- count: 3,
- expectedValues: [0, 1, 2],
- });
-
- testDeleteRange({
- description: "Remove range in the middle.",
- initialValues: [0, 1, 2, 3],
- startIndex: 1,
- count: 2,
- expectedValues: [0, 3],
- });
-
- testDeleteRange({
- description: "Remove range overlapping the middle.",
- initialValues: [1, 3, 5],
- startIndex: 2,
- count: 3,
- expectedValues: [1, 5],
- });
-
- testDeleteRange({
- description: "Remove range overlapping the beginning.",
- initialValues: [1, 2, 3],
- startIndex: 0,
- count: 3,
- expectedValues: [3],
- });
-
- testDeleteRange({
- description: "Remove range overlapping the end.",
- initialValues: [1, 2, 3],
- startIndex: 2,
- count: 3,
- expectedValues: [1],
- });
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.equals",
- test() {
- let original = new WI.IndexSet([1, 2, 3]);
- let copied = original.copy();
- InspectorTest.expectThat(original.equals(original), "Should trivially equal itself.");
- InspectorTest.expectThat(original.equals(copied), "Copy and original should be equal.");
-
- copied.delete(1);
- InspectorTest.expectFalse(original.equals(copied), "Modified copy and original should not be equal.");
-
- return true;
- }
- });
-
- suite.addTestCase({
- name: "IndexSet.prototype.difference",
- test() {
- function testDifference({values1, values2, expectedDifference}) {
- let indexSet1 = new WI.IndexSet(values1);
- let indexSet2 = new WI.IndexSet(values2);
-
- InspectorTest.log(`Given an IndexSet with values [${values1}], and another IndexSet with values [${values2}]:`);
-
- let difference = indexSet1.difference(indexSet2);
- InspectorTest.expectShallowEqual(Array.from(difference), expectedDifference, `Difference between the first and second IndexSet should be [${expectedDifference}].`);
- InspectorTest.log("");
- }
-
- testDifference({
- values1: [],
- values2: [],
- expectedDifference: [],
- });
-
- testDifference({
- values1: [1, 2, 3],
- values2: [],
- expectedDifference: [1, 2, 3],
- });
-
- testDifference({
- values1: [],
- values2: [1, 2, 3],
- expectedDifference: [],
- });
-
- testDifference({
- values1: [1, 2, 3],
- values2: [2, 3, 4],
- expectedDifference: [1],
- });
-
- return true;
- }
- });
-
- suite.runTestCasesAndFinish();
-}
-</script>
-</head>
-<body _onLoad_="runTest()">
- <p>Tests for WI.IndexSet.</p>
-</body>
-</html>
Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/set-utilities-expected.txt (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/set-utilities-expected.txt 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/set-utilities-expected.txt 2019-02-18 16:17:10 UTC (rev 241714)
@@ -16,3 +16,28 @@
PASS: a set should be a subset of another set with same and additional values.
PASS: a set should not be a subset of another set with same and different values.
+-- Running test case: Set.prototype.equals
+PASS: an empty set should be equal to another empty set.
+PASS: a set should be equal to another set with the same values.
+PASS: a set should be equal to another set with the same values in a different order.
+PASS: a set should not be a equal to another set with different values.
+PASS: a set should not be equal to another set with same and different values.
+
+-- Running test case: Set.prototype.difference
+Given a Set with values [], and another Set with values []:
+PASS: Set difference should be [].
+
+Given a Set with values [1,2,3], and another Set with values []:
+PASS: Set difference should be [1,2,3].
+
+Given a Set with values [], and another Set with values [1,2,3]:
+PASS: Set difference should be [].
+
+Given a Set with values [1,2,3], and another Set with values [2,3,4]:
+PASS: Set difference should be [1].
+
+
+-- Running test case: Set.prototype.firstValue
+PASS: Set with values [] should have firstValue equal to undefined.
+PASS: Set with values [1,2,3] should have firstValue equal to 1.
+
Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/set-utilities.html (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/set-utilities.html 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/inspector/unit-tests/set-utilities.html 2019-02-18 16:17:10 UTC (rev 241714)
@@ -59,6 +59,85 @@
}
});
+ suite.addTestCase({
+ name: "Set.prototype.equals",
+ test() {
+ function testTrue(a, b, message) {
+ InspectorTest.expectThat((new Set(a)).equals(new Set(b)), message);
+ }
+
+ function testFalse(a, b, message) {
+ InspectorTest.expectFalse((new Set(a)).equals(new Set(b)), message);
+ }
+
+ const object1 = {a: 1};
+ const object2 = {b: 2};
+ const object3 = {c: 3};
+
+ testTrue([], [], "an empty set should be equal to another empty set.");
+ testTrue([1, "a", object1], [1, "a", object1], "a set should be equal to another set with the same values.");
+ testTrue([1, "a", object1], [object1, 1, "a"], "a set should be equal to another set with the same values in a different order.");
+ testFalse([1, "a", object1], [2, "b", object2], "a set should not be a equal to another set with different values.");
+ testFalse([1, 2, "a", "b", object1, object2], [1, 3, "a", "c", object1, object3], "a set should not be equal to another set with same and different values.");
+
+ return true;
+ }
+ });
+
+ suite.addTestCase({
+ name: "Set.prototype.difference",
+ test() {
+ function testDifference({aValues, bValues, expectedDifference}) {
+ let a = new Set(aValues);
+ let b = new Set(bValues);
+
+ InspectorTest.log(`Given a Set with values [${aValues}], and another Set with values [${bValues}]:`);
+
+ let difference = a.difference(b);
+ InspectorTest.expectThat(difference.equals(new Set(expectedDifference)), `Set difference should be [${expectedDifference}].`);
+ InspectorTest.log("");
+ }
+
+ testDifference({
+ aValues: [],
+ bValues: [],
+ expectedDifference: [],
+ });
+
+ testDifference({
+ aValues: [1, 2, 3],
+ bValues: [],
+ expectedDifference: [1, 2, 3],
+ });
+
+ testDifference({
+ aValues: [],
+ bValues: [1, 2, 3],
+ expectedDifference: [],
+ });
+
+ testDifference({
+ aValues: [1, 2, 3],
+ bValues: [2, 3, 4],
+ expectedDifference: [1],
+ });
+
+ return true;
+ }
+ });
+
+ suite.addTestCase({
+ name: "Set.prototype.firstValue",
+ test() {
+ function testFirstValue(values) {
+ InspectorTest.expectEqual(new Set(values).firstValue, values[0], `Set with values [${values}] should have firstValue equal to ${values[0]}.`);
+ }
+
+ testFirstValue([]);
+ testFirstValue([1, 2, 3]);
+ }
+ });
+
suite.runTestCasesAndFinish();
}
</script>
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/ChangeLog (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/ChangeLog 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/ChangeLog 2019-02-18 16:17:10 UTC (rev 241714)
@@ -1,3 +1,119 @@
+2019-02-17 Matt Baker <mattba...@apple.com>
+
+ Web Inspector: Frontend performance is very slow reloading theverge.com - 50% of time in TreeOutline _indexOfTreeElement
+ https://bugs.webkit.org/show_bug.cgi?id=193605
+ <rdar://problem/47403986>
+
+ Reviewed by Devin Rousso.
+
+ SelectionController should track an unordered Set of represented objects
+ instead of an ordered set of indexes. This eliminates the costly and
+ error-prone updates needed to keep the selected indexes in sync as items
+ are added and removed from TreeOutline (and Table, to a far lesser extent).
+
+ The SelectionController interface is largely the same. Class and delegate
+ methods have been renamed to reflect the change from indexes to objects.
+ SelectionController tracks selected items in selection order. For the
+ operations that rely on objects being in insertion order, the controller
+ uses a comparator function provided at construction time.
+
+ * UserInterface/Base/IndexSet.js: Removed.
+ No longer used. SelectionController now uses a plain Set.
+
+ * UserInterface/Base/Utilities.js:
+ (value):
+ (get return):
+ Add utilities previously supplied by IndexSet and used by SelectionController.
+
+ * UserInterface/Controllers/SelectionController.js:
+ (WI.SelectionController):
+ (WI.SelectionController.prototype.get lastSelectedItem):
+ (WI.SelectionController.prototype.get selectedItems):
+ (WI.SelectionController.prototype.set allowsMultipleSelection):
+ (WI.SelectionController.prototype.hasSelectedItem):
+ (WI.SelectionController.prototype.selectItem):
+ (WI.SelectionController.prototype.deselectItem):
+ (WI.SelectionController.prototype.selectAll):
+ (WI.SelectionController.prototype.deselectAll):
+ (WI.SelectionController.prototype.removeSelectedItems):
+ (WI.SelectionController.prototype.reset):
+ (WI.SelectionController.prototype.didRemoveItems):
+ (WI.SelectionController.prototype.handleKeyDown):
+ (WI.SelectionController.prototype.handleItemMouseDown):
+ (WI.SelectionController.prototype._deselectAllAndSelect):
+ (WI.SelectionController.prototype._selectItemsFromArrowKey):
+ (WI.SelectionController.prototype._firstSelectableItem):
+ (WI.SelectionController.prototype._lastSelectableItem):
+ (WI.SelectionController.prototype._previousSelectableItem):
+ (WI.SelectionController.prototype._nextSelectableItem):
+ (WI.SelectionController.prototype._updateSelectedItems):
+ (WI.SelectionController.prototype._addRange):
+ (WI.SelectionController.prototype._deleteRange):
+ (WI.SelectionController.prototype.get numberOfItems): Deleted.
+ (WI.SelectionController.prototype.didInsertItem): Deleted.
+ (WI.SelectionController.prototype.handleItemMouseDown.normalizeRange): Deleted.
+ (WI.SelectionController.prototype._nextSelectableIndex): Deleted.
+ (WI.SelectionController.prototype._previousSelectableIndex): Deleted.
+
+ * UserInterface/Main.html:
+ * UserInterface/Test.html:
+ Remove IndexSet.
+
+ * UserInterface/Views/CookieStorageContentView.js:
+ (WI.CookieStorageContentView.prototype.tableIndexForRepresentedObject):
+ (WI.CookieStorageContentView.prototype.tableRepresentedObjectForIndex):
+
+ * UserInterface/Views/DOMTreeOutline.js:
+ (WI.DOMTreeOutline.prototype.objectForSelection):
+
+ * UserInterface/Views/NetworkTableContentView.js:
+ (WI.NetworkTableContentView.prototype.tableIndexForRepresentedObject):
+ (WI.NetworkTableContentView.prototype.tableRepresentedObjectForIndex):
+
+ * UserInterface/Views/Table.js:
+ (WI.Table):
+ (WI.Table.prototype.get selectedRow):
+ (WI.Table.prototype.get selectedRows):
+ (WI.Table.prototype.isRowSelected):
+ (WI.Table.prototype.selectRow):
+ (WI.Table.prototype.deselectRow):
+ (WI.Table.prototype.removeRow):
+ (WI.Table.prototype.removeSelectedRows):
+ (WI.Table.prototype.selectionControllerSelectionDidChange):
+ (WI.Table.prototype.selectionControllerFirstSelectableItem):
+ (WI.Table.prototype.selectionControllerLastSelectableItem):
+ (WI.Table.prototype.selectionControllerPreviousSelectableItem):
+ (WI.Table.prototype.selectionControllerNextSelectableItem):
+ (WI.Table.prototype._handleMouseDown):
+ (WI.Table.prototype._removeRows):
+ (WI.Table.prototype._indexForRepresentedObject):
+ (WI.Table.prototype._representedObjectForIndex):
+ (WI.Table.prototype.selectionControllerNumberOfItems): Deleted.
+ (WI.Table.prototype.selectionControllerNextSelectableIndex): Deleted.
+ (WI.Table.prototype.selectionControllerPreviousSelectableIndex): Deleted.
+ (WI.Table.prototype._toggleSelectedRowStyle): Deleted.
+
+ * UserInterface/Views/TreeOutline.js:
+ (WI.TreeOutline.compareSiblings):
+ (WI.TreeOutline):
+ (WI.TreeOutline.prototype.get selectedTreeElement):
+ (WI.TreeOutline.prototype.set selectedTreeElement):
+ (WI.TreeOutline.prototype.get selectedTreeElements):
+ (WI.TreeOutline.prototype.removeChildAtIndex):
+ (WI.TreeOutline.prototype.removeChildren):
+ (WI.TreeOutline.prototype._rememberTreeElement):
+ (WI.TreeOutline.prototype.getCachedTreeElement):
+ (WI.TreeOutline.prototype.selectionControllerSelectionDidChange):
+ (WI.TreeOutline.prototype.selectionControllerFirstSelectableItem):
+ (WI.TreeOutline.prototype.selectionControllerLastSelectableItem):
+ (WI.TreeOutline.prototype.selectionControllerPreviousSelectableItem):
+ (WI.TreeOutline.prototype.selectionControllerNextSelectableItem):
+ (WI.TreeOutline.prototype.objectForSelection):
+ (WI.TreeOutline._generateStyleRulesIfNeeded):
+ (WI.TreeOutline.prototype.selectionControllerNextSelectableIndex): Deleted.
+ (WI.TreeOutline.prototype.selectionControllerPreviousSelectableIndex): Deleted.
+ (WI.TreeOutline._generateStyleRulesIfNeeded._indexesForSubtree.numberOfElementsInSubtree): Deleted.
+
2019-02-15 Joseph Pecoraro <pecor...@apple.com>
Web Inspector: Logging a native function to the console, such as `alert`, produces unhandled rejection
Deleted: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Base/IndexSet.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Base/IndexSet.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Base/IndexSet.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2018 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-WI.IndexSet = class IndexSet
-{
- constructor(values)
- {
- console.assert(!values || Array.isArray(values));
-
- this._indexes = [];
-
- if (values) {
- for (let value of values.slice().sort((a, b) => a - b)) {
- if (value === this._indexes.lastValue)
- continue;
- if (this._validateIndex(value))
- this._indexes.push(value);
- }
- }
- }
-
- // Public
-
- get size() { return this._indexes.length; }
-
- get firstIndex()
- {
- return this._indexes.length ? this._indexes[0] : NaN;
- }
-
- get lastIndex()
- {
- return this._indexes.length ? this._indexes.lastValue : NaN;
- }
-
- add(value)
- {
- if (!this._validateIndex(value))
- return;
-
- let index = this._indexes.lowerBound(value);
- if (this._indexes[index] === value)
- return;
-
- this._indexes.insertAtIndex(value, index);
- }
-
- delete(value)
- {
- if (!this._validateIndex(value))
- return false;
-
- if (!this.size)
- return false;
-
- let index = this._indexes.lowerBound(value);
- if (index === this._indexes.length)
- return false;
- this._indexes.splice(index, 1);
- return true;
- }
-
- has(value)
- {
- if (!this.size)
- return false;
-
- let index = this._indexes.lowerBound(value);
- return this._indexes[index] === value;
- }
-
- addRange(startIndex, count)
- {
- if (!this._validateIndex(startIndex))
- return;
-
- console.assert(count > 0);
- if (count <= 0)
- return;
-
- if (count === 1) {
- this.add(startIndex);
- return;
- }
-
- let range = new Array(count);
- for (let i = 0; i < count; ++i)
- range[i] = startIndex + i;
-
- if (!this.size || (this.firstIndex >= range[0] && this.lastIndex <= range.lastValue)) {
- this._indexes = range;
- return;
- }
-
- let start = this._indexes.lowerBound(startIndex);
- let numberToDelete = this._indexes.upperBound(range.lastValue) - start;
- this._indexes.splice(start, numberToDelete, ...range);
- }
-
- deleteRange(startIndex, count)
- {
- if (!this._validateIndex(startIndex))
- return;
-
- console.assert(count > 0);
- if (count <= 0)
- return;
-
- if (!this.size)
- return;
-
- if (count === 1) {
- this.delete(startIndex);
- return;
- }
-
- let lastIndex = startIndex + count - 1;
- if (this.firstIndex >= startIndex && this.lastIndex <= lastIndex) {
- this.clear();
- return;
- }
-
- let start = this._indexes.lowerBound(startIndex);
- let numberToDelete = this._indexes.upperBound(lastIndex) - start;
- this._indexes.splice(start, numberToDelete);
- }
-
- clear()
- {
- this._indexes = [];
- }
-
- copy()
- {
- let indexSet = new WI.IndexSet;
- indexSet._indexes = this._indexes.slice();
- return indexSet;
- }
-
- equals(indexSet)
- {
- console.assert(indexSet instanceof WI.IndexSet);
- if (!(indexSet instanceof WI.IndexSet))
- return false;
-
- if (indexSet === this)
- return true;
-
- return Array.shallowEqual(this._indexes, indexSet._indexes);
- }
-
- difference(indexSet)
- {
- console.assert(indexSet instanceof WI.IndexSet);
-
- if (indexSet === this)
- return new WI.IndexSet;
-
- let result = new WI.IndexSet;
- result._indexes = this._indexes.filter((value) => !indexSet.has(value));
- return result;
- }
-
- indexGreaterThan(value)
- {
- const following = true;
- return this._indexClosestTo(value, following);
- }
-
- indexLessThan(value)
- {
- const following = false;
- return this._indexClosestTo(value, following);
- }
-
- [Symbol.iterator]()
- {
- return this._indexes[Symbol.iterator]();
- }
-
- // Private
-
- _indexClosestTo(value, following)
- {
- if (!this.size)
- return NaN;
-
- if (this.size === 1) {
- if (following)
- return this.firstIndex > value ? this.firstIndex : NaN;
- return this.firstIndex < value ? this.firstIndex : NaN;
- }
-
- let offset = following ? 1 : -1;
- let position = this._indexes.lowerBound(value + offset);
-
- let closestIndex = this._indexes[position];
- if (closestIndex === undefined)
- return NaN;
-
- if (value === closestIndex)
- return NaN;
-
- if (!following && closestIndex > value)
- return NaN;
- return closestIndex;
- }
-
- _validateIndex(value)
- {
- console.assert(Number.isInteger(value) && value >= 0, "Index must be a non-negative integer.");
- return Number.isInteger(value) && value >= 0;
- }
-};
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Base/Utilities.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -118,6 +118,39 @@
}
});
+Object.defineProperty(Set.prototype, "equals",
+{
+ value(other)
+ {
+ return this.size === other.size && this.isSubsetOf(other);
+ }
+});
+
+Object.defineProperty(Set.prototype, "difference",
+{
+ value(other)
+ {
+ if (other === this)
+ return new Set;
+
+ let result = new Set;
+ for (let item of this) {
+ if (!other.has(item))
+ result.add(item);
+ }
+
+ return result;
+ }
+});
+
+Object.defineProperty(Set.prototype, "firstValue",
+{
+ get()
+ {
+ return this.values().next().value;
+ }
+});
+
Object.defineProperty(Set.prototype, "intersects",
{
value(other)
@@ -1456,6 +1489,12 @@
{
value(value, comparator)
{
+ function defaultComparator(a, b)
+ {
+ return a - b;
+ }
+ comparator = comparator || defaultComparator;
+
var index = this.lowerBound(value, comparator);
return index < this.length && comparator(value, this[index]) === 0 ? index : -1;
}
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2018, 2019 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,30 +25,34 @@
WI.SelectionController = class SelectionController extends WI.Object
{
- constructor(delegate)
+ constructor(delegate, comparator)
{
super();
console.assert(delegate);
+ console.assert(typeof comparator === "function");
+
this._delegate = delegate;
+ this._comparator = comparator;
this._allowsEmptySelection = true;
this._allowsMultipleSelection = false;
- this._lastSelectedIndex = NaN;
- this._shiftAnchorIndex = NaN;
- this._selectedIndexes = new WI.IndexSet;
+ this._lastSelectedItem = null;
+ this._shiftAnchorItem = null;
+ this._selectedItems = new Set;
this._suppressSelectionDidChange = false;
- console.assert(this._delegate.selectionControllerNumberOfItems, "SelectionController delegate must implement selectionControllerNumberOfItems.");
- console.assert(this._delegate.selectionControllerNextSelectableIndex, "SelectionController delegate must implement selectionControllerNextSelectableIndex.");
- console.assert(this._delegate.selectionControllerPreviousSelectableIndex, "SelectionController delegate must implement selectionControllerPreviousSelectableIndex.");
+ console.assert(this._delegate.selectionControllerFirstSelectableItem, "SelectionController delegate must implement selectionControllerFirstSelectableItem.");
+ console.assert(this._delegate.selectionControllerLastSelectableItem, "SelectionController delegate must implement selectionControllerLastSelectableItem.");
+ console.assert(this._delegate.selectionControllerNextSelectableItem, "SelectionController delegate must implement selectionControllerNextSelectableItem.");
+ console.assert(this._delegate.selectionControllerPreviousSelectableItem, "SelectionController delegate must implement selectionControllerPreviousSelectableItem.");
}
// Public
get delegate() { return this._delegate; }
- get lastSelectedItem() { return this._lastSelectedIndex; }
- get selectedItems() { return this._selectedIndexes; }
+ get lastSelectedItem() { return this._lastSelectedItem; }
+ get selectedItems() { return this._selectedItems; }
get allowsEmptySelection() { return this._allowsEmptySelection; }
set allowsEmptySelection(flag) { this._allowsEmptySelection = flag; }
@@ -67,225 +71,147 @@
if (this._allowsMultipleSelection)
return;
- if (this._selectedIndexes.size > 1) {
- console.assert(this._lastSelectedIndex >= 0);
- this._updateSelectedItems(new WI.IndexSet([this._lastSelectedIndex]));
- }
+ if (this._selectedItems.size > 1)
+ this._updateSelectedItems(new Set([this._lastSelectedItem]));
}
- get numberOfItems()
+ hasSelectedItem(item)
{
- return this._delegate.selectionControllerNumberOfItems(this);
+ return this._selectedItems.has(item);
}
- hasSelectedItem(index)
+ selectItem(item, extendSelection = false)
{
- return this._selectedIndexes.has(index);
- }
-
- selectItem(index, extendSelection = false)
- {
+ console.assert(item, "Invalid item for selection.");
console.assert(!extendSelection || this._allowsMultipleSelection, "Cannot extend selection with multiple selection disabled.");
- console.assert(index >= 0 && index < this.numberOfItems);
if (!this._allowsMultipleSelection)
extendSelection = false;
- if (this.hasSelectedItem(index)) {
+ if (this.hasSelectedItem(item)) {
if (!extendSelection)
- this._deselectAllAndSelect(index);
+ this._deselectAllAndSelect(item);
return;
}
- let newSelectedItems = extendSelection ? this._selectedIndexes.copy() : new WI.IndexSet;
- newSelectedItems.add(index);
+ this._lastSelectedItem = item;
+ this._shiftAnchorItem = null;
- this._shiftAnchorIndex = NaN;
- this._lastSelectedIndex = index;
+ let newItems = new Set(extendSelection ? this._selectedItems : null);
+ newItems.add(item);
- this._updateSelectedItems(newSelectedItems);
+ this._updateSelectedItems(newItems);
}
- deselectItem(index)
+ deselectItem(item)
{
- console.assert(index >= 0 && index < this.numberOfItems);
+ console.assert(item, "Invalid item for selection.");
- if (!this.hasSelectedItem(index))
+ if (!this.hasSelectedItem(item))
return;
- if (!this._allowsEmptySelection && this._selectedIndexes.size === 1)
+ if (!this._allowsEmptySelection && this._selectedItems.size === 1)
return;
- let newSelectedItems = this._selectedIndexes.copy();
- newSelectedItems.delete(index);
+ let newItems = new Set(this._selectedItems);
+ newItems.delete(item);
- if (this._shiftAnchorIndex === index)
- this._shiftAnchorIndex = NaN;
+ if (this._lastSelectedItem === item) {
+ this._lastSelectedItem = null;
- if (this._lastSelectedIndex === index) {
- this._lastSelectedIndex = NaN;
- if (newSelectedItems.size) {
+ if (newItems.size) {
// Find selected item closest to deselected item.
- let preceding = newSelectedItems.indexLessThan(index);
- let following = newSelectedItems.indexGreaterThan(index);
+ let previous = item;
+ let next = item;
+ while (!this._lastSelectedItem && previous && next) {
+ previous = this._previousSelectableItem(previous);
+ if (this.hasSelectedItem(previous)) {
+ this._lastSelectedItem = previous;
+ break;
+ }
- if (isNaN(preceding))
- this._lastSelectedIndex = following;
- else if (isNaN(following))
- this._lastSelectedIndex = preceding;
- else {
- if ((following - index) < (index - preceding))
- this._lastSelectedIndex = following;
- else
- this._lastSelectedIndex = preceding;
+ next = this._nextSelectableItem(next);
+ if (this.hasSelectedItem(next)) {
+ this._lastSelectedItem = next;
+ break;
+ }
}
}
}
- this._updateSelectedItems(newSelectedItems);
+ if (this._shiftAnchorItem === item)
+ this._shiftAnchorItem = null;
+
+ this._updateSelectedItems(newItems);
}
selectAll()
{
- if (!this.numberOfItems || !this._allowsMultipleSelection)
+ if (!this._allowsMultipleSelection)
return;
- if (this._selectedIndexes.size === this.numberOfItems)
- return;
+ this._lastSelectedItem = this._lastSelectableItem();
- let newSelectedItems = new WI.IndexSet;
- newSelectedItems.addRange(0, this.numberOfItems);
+ let newItems = new Set;
+ this._addRange(newItems, this._firstSelectableItem(), this._lastSelectedItem);
- this._lastSelectedIndex = newSelectedItems.lastIndex;
- if (isNaN(this._shiftAnchorIndex))
- this._shiftAnchorIndex = this._lastSelectedIndex;
+ if (!this._shiftAnchorItem)
+ this._shiftAnchorItem = this._lastSelectedItem;
- this._updateSelectedItems(newSelectedItems);
+ this._updateSelectedItems(newItems);
}
deselectAll()
{
- const index = NaN;
- this._deselectAllAndSelect(index);
+ this._deselectAllAndSelect(null);
}
removeSelectedItems()
{
- let numberOfSelectedItems = this._selectedIndexes.size;
- if (!numberOfSelectedItems)
+ if (!this._selectedItems.size)
return;
+ let orderedSelection = Array.from(this._selectedItems).sort(this._comparator);
+
// Try selecting the item following the selection.
- let lastSelectedIndex = this._selectedIndexes.lastIndex;
- let indexToSelect = this._nextSelectableIndex(lastSelectedIndex);
- if (isNaN(indexToSelect)) {
+ let lastSelectedItem = orderedSelection.lastValue;
+ let itemToSelect = this._nextSelectableItem(lastSelectedItem);
+ if (!itemToSelect) {
// If no item exists after the last item in the selection, try selecting
// a deselected item (hole) within the selection.
- let firstSelectedIndex = this._selectedIndexes.firstIndex;
- if (lastSelectedIndex - firstSelectedIndex > numberOfSelectedItems) {
- indexToSelect = this._nextSelectableIndex(firstSelectedIndex);
- while (this._selectedIndexes.has(indexToSelect))
- indexToSelect = this._nextSelectableIndex(firstSelectedIndex);
- } else {
+ itemToSelect = orderedSelection[0];
+ while (itemToSelect && this.hasSelectedItem(itemToSelect))
+ itemToSelect = this._nextSelectableItem(itemToSelect);
+
+ if (!itemToSelect || this.hasSelectedItem(itemToSelect)) {
// If the selection contains no holes, try selecting the item
// preceding the selection.
- indexToSelect = firstSelectedIndex > 0 ? this._previousSelectableIndex(firstSelectedIndex) : NaN;
+ itemToSelect = this._previousSelectableItem(orderedSelection[0]);
}
}
- this._deselectAllAndSelect(indexToSelect);
+ this._deselectAllAndSelect(itemToSelect);
}
reset()
{
- this._shiftAnchorIndex = NaN;
- this._lastSelectedIndex = NaN;
- this._selectedIndexes.clear();
+ this._lastSelectedItem = null;
+ this._shiftAnchorItem = null;
+ this._selectedItems.clear();
}
- didInsertItem(index)
+ didRemoveItems(items)
{
- let current = this._selectedIndexes.lastIndex;
- while (current >= index) {
- this._selectedIndexes.delete(current);
- this._selectedIndexes.add(current + 1);
+ console.assert(items instanceof Set);
- current = this._selectedIndexes.indexLessThan(current);
- }
+ if (!items.size || !this._selectedItems.size)
+ return;
- if (this._lastSelectedIndex >= index)
- this._lastSelectedIndex += 1;
- if (this._shiftAnchorIndex >= index)
- this._shiftAnchorIndex += 1;
+ this._updateSelectedItems(this._selectedItems.difference(items));
}
- didRemoveItems(indexes)
- {
- if (!indexes)
- return;
-
- console.assert(indexes instanceof WI.IndexSet);
-
- if (!indexes.size || !this._selectedIndexes.size)
- return;
-
- let firstRemovedIndex = indexes.firstIndex;
- if (this._selectedIndexes.lastIndex < firstRemovedIndex)
- return;
-
- let newSelectedIndexes = new WI.IndexSet;
-
- let lastRemovedIndex = indexes.lastIndex;
- if (this._selectedIndexes.firstIndex < lastRemovedIndex) {
- let removedCount = 0;
- let removedIndex = firstRemovedIndex;
-
- this._suppressSelectionDidChange = true;
-
- // Adjust the selected indexes that are in the range between the
- // first and last removed index (inclusive).
- for (let current = this._selectedIndexes.firstIndex; current < lastRemovedIndex; current = this._selectedIndexes.indexGreaterThan(current)) {
- if (this.hasSelectedItem(current)) {
- this.deselectItem(current);
- removedCount++;
- continue;
- }
-
- while (removedIndex < current) {
- removedCount++;
- removedIndex = indexes.indexGreaterThan(removedIndex);
- }
-
- let newIndex = current - removedCount;
- newSelectedIndexes.add(newIndex);
-
- if (this._lastSelectedIndex === current)
- this._lastSelectedIndex = newIndex;
- if (this._shiftAnchorIndex === current)
- this._shiftAnchorIndex = newIndex;
- }
-
- this._suppressSelectionDidChange = false;
- }
-
- let removedCount = indexes.size;
- let current = lastRemovedIndex;
- while (current = this._selectedIndexes.indexGreaterThan(current))
- newSelectedIndexes.add(current - removedCount);
-
- if (this._lastSelectedIndex > lastRemovedIndex)
- this._lastSelectedIndex -= removedCount;
- if (this._shiftAnchorIndex > lastRemovedIndex)
- this._shiftAnchorIndex -= removedCount;
-
- this._selectedIndexes = newSelectedIndexes;
- }
-
handleKeyDown(event)
{
- if (!this.numberOfItems)
- return false;
-
if (event.key === "a" && event.commandOrControlKey) {
this.selectAll();
return true;
@@ -305,8 +231,10 @@
return false;
}
- handleItemMouseDown(index, event)
+ handleItemMouseDown(item, event)
{
+ console.assert(item, "Invalid item for selection.");
+
if (event.button !== 0 || event.ctrlKey)
return;
@@ -313,33 +241,34 @@
// Command (macOS) or Control (Windows) key takes precedence over shift
// whether or not multiple selection is enabled, so handle it first.
if (event.commandOrControlKey) {
- if (this.hasSelectedItem(index))
- this.deselectItem(index);
+ if (this.hasSelectedItem(item))
+ this.deselectItem(item);
else
- this.selectItem(index, this._allowsMultipleSelection);
+ this.selectItem(item, this._allowsMultipleSelection);
return;
}
let shiftExtendSelection = this._allowsMultipleSelection && event.shiftKey;
if (!shiftExtendSelection) {
- this.selectItem(index);
+ this.selectItem(item);
return;
}
- let newSelectedItems = this._selectedIndexes.copy();
+ let newItems = new Set(this._selectedItems);
// Shift-clicking when nothing is selected should cause the first item
// through the clicked item to be selected.
- if (!newSelectedItems.size) {
- this._shiftAnchorIndex = 0;
- this._lastSelectedIndex = index;
- newSelectedItems.addRange(0, index + 1);
- this._updateSelectedItems(newSelectedItems);
+ if (!newItems.size) {
+ this._lastSelectedItem = item;
+ this._shiftAnchorItem = this._firstSelectableItem();
+
+ this._addRange(newItems, this._shiftAnchorItem, this._lastSelectedItem);
+ this._updateSelectedItems(newItems);
return;
}
- if (isNaN(this._shiftAnchorIndex))
- this._shiftAnchorIndex = this._lastSelectedIndex;
+ if (!this._shiftAnchorItem)
+ this._shiftAnchorItem = this._lastSelectedItem;
// Shift-clicking will add to or delete from the current selection, or
// pivot the selection around the anchor (a delete followed by an add).
@@ -347,58 +276,57 @@
// that are necessary, but it is simpler to throw out the previous shift-
// selected range and add the new range between the anchor and clicked item.
- function normalizeRange(startIndex, endIndex) {
- return startIndex > endIndex ? [endIndex, startIndex] : [startIndex, endIndex];
- }
+ let sortItemPair = (a, b) => {
+ return [a, b].sort(this._comparator);
+ };
- if (this._shiftAnchorIndex !== this._lastSelectedIndex) {
- let [startIndex, endIndex] = normalizeRange(this._shiftAnchorIndex, this._lastSelectedIndex);
- newSelectedItems.deleteRange(startIndex, endIndex - startIndex + 1);
+ if (this._shiftAnchorItem !== this._lastSelectedItem) {
+ let [startItem, endItem] = sortItemPair(this._shiftAnchorItem, this._lastSelectedItem);
+ this._deleteRange(newItems, startItem, endItem);
}
- let [startIndex, endIndex] = normalizeRange(this._shiftAnchorIndex, index);
- newSelectedItems.addRange(startIndex, endIndex - startIndex + 1);
+ let [startItem, endItem] = sortItemPair(this._shiftAnchorItem, item);
+ this._addRange(newItems, startItem, endItem);
- this._lastSelectedIndex = index;
+ this._lastSelectedItem = item;
- this._updateSelectedItems(newSelectedItems);
+ this._updateSelectedItems(newItems);
}
// Private
- _deselectAllAndSelect(index)
+ _deselectAllAndSelect(item)
{
- if (!this._selectedIndexes.size)
+ if (!this._selectedItems.size)
return;
- if (this._selectedIndexes.size === 1 && this._selectedIndexes.firstIndex === index)
+ if (this._selectedItems.size === 1 && this.hasSelectedItem(item))
return;
- this._shiftAnchorIndex = NaN;
- this._lastSelectedIndex = index;
+ this._lastSelectedItem = item;
+ this._shiftAnchorItem = null;
- let newSelectedItems = new WI.IndexSet;
- if (!isNaN(index))
- newSelectedItems.add(index);
+ let newItems = new Set;
+ if (item)
+ newItems.add(item);
- this._updateSelectedItems(newSelectedItems);
+ this._updateSelectedItems(newItems);
}
_selectItemsFromArrowKey(goingUp, shiftKey)
{
- if (!this._selectedIndexes.size) {
- let index = goingUp ? this.numberOfItems - 1 : 0;
- this.selectItem(index);
+ if (!this._selectedItems.size) {
+ this.selectItem(goingUp ? this._lastSelectableItem() : this._firstSelectableItem());
return;
}
- let index = goingUp ? this._previousSelectableIndex(this._lastSelectedIndex) : this._nextSelectableIndex(this._lastSelectedIndex);
- if (isNaN(index))
+ let item = goingUp ? this._previousSelectableItem(this._lastSelectedItem) : this._nextSelectableItem(this._lastSelectedItem);
+ if (!item)
return;
let extendSelection = shiftKey && this._allowsMultipleSelection;
- if (!extendSelection || !this.hasSelectedItem(index)) {
- this.selectItem(index, extendSelection);
+ if (!extendSelection || !this.hasSelectedItem(item)) {
+ this.selectItem(item, extendSelection);
return;
}
@@ -405,9 +333,9 @@
// Since the item in the direction of movement is selected, we are either
// extending the selection into the item, or deselecting. Determine which
// by checking whether the item opposite the anchor item is selected.
- let priorIndex = goingUp ? this._nextSelectableIndex(this._lastSelectedIndex) : this._previousSelectableIndex(this._lastSelectedIndex);
- if (!this.hasSelectedItem(priorIndex)) {
- this.deselectItem(this._lastSelectedIndex);
+ let priorItem = goingUp ? this._nextSelectableItem(this._lastSelectedItem) : this._previousSelectableItem(this._lastSelectedItem);
+ if (!priorItem || !this.hasSelectedItem(priorItem)) {
+ this.deselectItem(this._lastSelectedItem);
return;
}
@@ -414,40 +342,74 @@
// The selection is being extended into the item; make it the new
// anchor item then continue searching in the direction of movement
// for an unselected item to select.
- while (!isNaN(index)) {
- if (!this.hasSelectedItem(index)) {
- this.selectItem(index, extendSelection);
+ while (item) {
+ if (!this.hasSelectedItem(item)) {
+ this.selectItem(item, extendSelection);
break;
}
- this._lastSelectedIndex = index;
- index = goingUp ? this._previousSelectableIndex(index) : this._nextSelectableIndex(index);
+ this._lastSelectedItem = item;
+ item = goingUp ? this._previousSelectableItem(item) : this._nextSelectableItem(item);
}
}
- _nextSelectableIndex(index)
+ _firstSelectableItem()
{
- return this._delegate.selectionControllerNextSelectableIndex(this, index);
+ return this._delegate.selectionControllerFirstSelectableItem(this);
}
- _previousSelectableIndex(index)
+ _lastSelectableItem()
{
- return this._delegate.selectionControllerPreviousSelectableIndex(this, index);
+ return this._delegate.selectionControllerLastSelectableItem(this);
}
- _updateSelectedItems(indexes)
+ _previousSelectableItem(item)
{
- if (this._selectedIndexes.equals(indexes))
- return;
+ return this._delegate.selectionControllerPreviousSelectableItem(this, item);
+ }
- let oldSelectedIndexes = this._selectedIndexes.copy();
- this._selectedIndexes = indexes;
+ _nextSelectableItem(item)
+ {
+ return this._delegate.selectionControllerNextSelectableItem(this, item);
+ }
+ _updateSelectedItems(items)
+ {
+ let oldSelectedItems = this._selectedItems;
+ this._selectedItems = items;
+
if (this._suppressSelectionDidChange || !this._delegate.selectionControllerSelectionDidChange)
return;
- let deselectedItems = oldSelectedIndexes.difference(indexes);
- let selectedItems = indexes.difference(oldSelectedIndexes);
- this._delegate.selectionControllerSelectionDidChange(this, deselectedItems, selectedItems);
+ let deselectedItems = oldSelectedItems.difference(items);
+ let selectedItems = items.difference(oldSelectedItems);
+ if (deselectedItems.size || selectedItems.size)
+ this._delegate.selectionControllerSelectionDidChange(this, deselectedItems, selectedItems);
}
+
+ _addRange(items, firstItem, lastItem)
+ {
+ let current = firstItem;
+ while (current) {
+ items.add(current);
+ if (current === lastItem)
+ break;
+ current = this._nextSelectableItem(current);
+ }
+
+ console.assert(!lastItem || items.has(lastItem), "End of range could not be reached.");
+ }
+
+ _deleteRange(items, firstItem, lastItem)
+ {
+ let current = firstItem;
+ while (current) {
+ items.delete(current);
+ if (current === lastItem)
+ break;
+ current = this._nextSelectableItem(current);
+ }
+
+ console.assert(!lastItem || !items.has(lastItem), "End of range could not be reached.");
+ }
};
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Main.html (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Main.html 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Main.html 2019-02-18 16:17:10 UTC (rev 241714)
@@ -275,7 +275,6 @@
<script src=""
<script src=""
<script src=""
- <script src=""
<script src=""
<script src=""
<script src=""
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Test.html (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Test.html 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Test.html 2019-02-18 16:17:10 UTC (rev 241714)
@@ -38,7 +38,6 @@
<script src=""
<script src=""
<script src=""
- <script src=""
<script src=""
<script src=""
<script src=""
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/CookieStorageContentView.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/CookieStorageContentView.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/CookieStorageContentView.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -75,6 +75,19 @@
// Table dataSource
+ tableIndexForRepresentedObject(table, object)
+ {
+ let index = this._cookies.indexOf(object);
+ console.assert(index >= 0);
+ return index;
+ }
+
+ tableRepresentedObjectForIndex(table, index)
+ {
+ console.assert(index >= 0 && index < this._cookies.length);
+ return this._cookies[index];
+ }
+
tableNumberOfRows(table)
{
return this._cookies.length;
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -319,6 +319,23 @@
return true;
}
+ // Protected
+
+ objectForSelection(treeElement)
+ {
+ if (treeElement instanceof WI.DOMTreeElement && treeElement.isCloseTag()) {
+ // SelectionController requires every selectable item to be unique.
+ // The DOMTreeElement for a close tag has the same represented object
+ // as it's parent (the open tag). Return a proxy object associated
+ // with the tree element for the close tag so it can be selected.
+ if (!treeElement.__closeTagProxyObject)
+ treeElement.__closeTagProxyObject = {__proxyObjectTreeElement: treeElement};
+ return treeElement.__closeTagProxyObject;
+ }
+
+ return super.objectForSelection(treeElement);
+ }
+
// Private
_revealAndSelectNode(node, omitFocus)
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -327,6 +327,17 @@
// Table dataSource
+ tableIndexForRepresentedObject(table, object)
+ {
+ return this._filteredEntries.indexOf(object);
+ }
+
+ tableRepresentedObjectForIndex(table, index)
+ {
+ console.assert(index >=0 && index < this._filteredEntries.length);
+ return this._filteredEntries[index];
+ }
+
tableNumberOfRows(table)
{
return this._filteredEntries.length;
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/Table.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/Table.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/Table.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -87,7 +87,7 @@
this._columnWidths = null; // Calculated in _resizeColumnsAndFiller.
this._fillerHeight = 0; // Calculated in _resizeColumnsAndFiller.
- this._selectionController = new WI.SelectionController(this);
+ this._selectionController = new WI.SelectionController(this, (a, b) => this._indexForRepresentedObject(a) - this._indexForRepresentedObject(b));
this._resizers = [];
this._currentResizer = null;
@@ -113,6 +113,9 @@
this._visibleRowIndexStart = NaN;
this._visibleRowIndexEnd = NaN;
+ console.assert(this._dataSource.tableIndexForRepresentedObject, "Table data source must implement tableIndexForRepresentedObject.");
+ console.assert(this._dataSource.tableRepresentedObjectForIndex, "Table data source must implement tableRepresentedObjectForIndex.");
+
console.assert(this._delegate.tablePopulateCell, "Table delegate must implement tablePopulateCell.");
}
@@ -125,12 +128,17 @@
get selectedRow()
{
- return this._selectionController.lastSelectedItem;
+ let item = this._selectionController.lastSelectedItem;
+ let index = this._indexForRepresentedObject(item);
+ return index >= 0 ? index : NaN;
}
get selectedRows()
{
- return Array.from(this._selectionController.selectedItems);
+ let rowIndexes = [];
+ for (let item of this._selectionController.selectedItems)
+ rowIndexes.push(this._indexForRepresentedObject(item));
+ return rowIndexes;
}
get scrollContainer() { return this._scrollContainerElement; }
@@ -236,7 +244,7 @@
isRowSelected(rowIndex)
{
- return this._selectionController.hasSelectedItem(rowIndex);
+ return this._selectionController.hasSelectedItem(this._representedObjectForIndex(rowIndex));
}
reloadData()
@@ -313,12 +321,12 @@
selectRow(rowIndex, extendSelection = false)
{
- this._selectionController.selectItem(rowIndex, extendSelection);
+ this._selectionController.selectItem(this._representedObjectForIndex(rowIndex), extendSelection);
}
deselectRow(rowIndex)
{
- this._selectionController.deselectItem(rowIndex);
+ this._selectionController.deselectItem(this._representedObjectForIndex(rowIndex));
}
selectAll()
@@ -338,20 +346,20 @@
if (this.isRowSelected(rowIndex))
this.deselectRow(rowIndex);
- let rowIndexes = new WI.IndexSet([rowIndex]);
- this._removeRows(rowIndexes);
+ this._removeRows(new Set([this._representedObjectForIndex(rowIndex)]));
}
removeSelectedRows()
{
+ let selectedItems = this._selectionController.selectedItems;
+ if (!selectedItems.size)
+ return;
+
// Change the selection before removing rows. This matches the behavior
// of macOS Finder (in list and column modes) when removing selected items.
- let oldSelectedItems = this._selectionController.selectedItems.copy();
-
this._selectionController.removeSelectedItems();
- if (!oldSelectedItems.equals(this._selectionController.selectedItems))
- this._removeRows(oldSelectedItems);
+ this._removeRows(selectedItems);
}
revealRow(rowIndex)
@@ -597,13 +605,22 @@
selectionControllerSelectionDidChange(controller, deselectedItems, selectedItems)
{
- if (deselectedItems.size)
- this._toggleSelectedRowStyle(deselectedItems, false);
- if (selectedItems.size)
- this._toggleSelectedRowStyle(selectedItems, true);
+ for (let item of deselectedItems) {
+ let rowIndex = this._indexForRepresentedObject(item);
+ let row = this._cachedRows.get(rowIndex);
+ if (row)
+ row.classList.toggle("selected", false);
+ }
+ for (let item of selectedItems) {
+ let rowIndex = this._indexForRepresentedObject(item);
+ let row = this._cachedRows.get(rowIndex);
+ if (row)
+ row.classList.toggle("selected", true);
+ }
+
if (selectedItems.size === 1) {
- let rowIndex = selectedItems.firstIndex;
+ let rowIndex = this._indexForRepresentedObject(selectedItems.firstValue);
if (!this._isRowVisible(rowIndex))
this.revealRow(rowIndex);
}
@@ -612,25 +629,32 @@
this._delegate.tableSelectionDidChange(this);
}
- selectionControllerNumberOfItems(controller)
+ selectionControllerFirstSelectableItem(controller)
{
- return this.numberOfRows;
+ return this._representedObjectForIndex(0);
}
- selectionControllerNextSelectableIndex(controller, index)
+ selectionControllerLastSelectableItem(controller)
{
- if (index >= this.numberOfRows - 1)
- return NaN;
- return index + 1;
+ return this._representedObjectForIndex(this.numberOfRows - 1);
}
- selectionControllerPreviousSelectableIndex(controller, index)
+ selectionControllerPreviousSelectableItem(controller, item)
{
- if (index <= 0)
- return NaN;
- return index - 1;
+ let index = this._indexForRepresentedObject(item);
+ console.assert(index >= 0 && index < this.numberOfRows);
+
+ return index > 0 ? this._representedObjectForIndex(index - 1) : null;
}
+ selectionControllerNextSelectableItem(controller, item)
+ {
+ let index = this._indexForRepresentedObject(item);
+ console.assert(index >= 0 && index < this.numberOfRows);
+
+ return index < this.numberOfRows - 1 ? this._representedObjectForIndex(index + 1) : null;
+ }
+
// Resizer delegate
resizerDragStarted(resizer)
@@ -1295,7 +1319,7 @@
return;
}
- this._selectionController.handleItemMouseDown(rowIndex, event);
+ this._selectionController.handleItemMouseDown(this._representedObjectForIndex(rowIndex), event);
}
_handleContextMenu(event)
@@ -1374,7 +1398,7 @@
}
}
- _removeRows(rowIndexes)
+ _removeRows(representedObjects)
{
let removed = 0;
@@ -1387,8 +1411,15 @@
}
};
- for (let index = rowIndexes.firstIndex; index <= rowIndexes.lastIndex; ++index) {
- if (rowIndexes.has(index)) {
+ let rowIndexes = [];
+ for (let object of representedObjects)
+ rowIndexes.push(this._indexForRepresentedObject(object));
+
+ rowIndexes.sort((a, b) => a - b);
+
+ let lastIndex = rowIndexes.lastValue;
+ for (let index = rowIndexes[0]; index <= lastIndex; ++index) {
+ if (rowIndexes.binaryIndexOf(index) >= 0) {
let row = this._cachedRows.get(index);
if (row) {
this._cachedRows.delete(index);
@@ -1405,28 +1436,29 @@
if (!removed)
return;
- for (let index = rowIndexes.lastIndex + 1; index < this._cachedNumberOfRows; ++index)
+ for (let index = lastIndex + 1; index < this._cachedNumberOfRows; ++index)
adjustRowAtIndex(index);
this._cachedNumberOfRows -= removed;
console.assert(this._cachedNumberOfRows >= 0);
- this._selectionController.didRemoveItems(rowIndexes);
+ this._selectionController.didRemoveItems(representedObjects);
if (this._delegate.tableDidRemoveRows) {
- this._delegate.tableDidRemoveRows(this, Array.from(rowIndexes));
+ this._delegate.tableDidRemoveRows(this, rowIndexes);
console.assert(this._cachedNumberOfRows === this._dataSource.tableNumberOfRows(this), "Table data source should update after removing rows.");
}
}
- _toggleSelectedRowStyle(rowIndexes, flag)
+ _indexForRepresentedObject(object)
{
- for (let index of rowIndexes) {
- let row = this._cachedRows.get(index);
- if (row)
- row.classList.toggle("selected", flag);
- }
+ return this.dataSource.tableIndexForRepresentedObject(this, object);
}
+
+ _representedObjectForIndex(index)
+ {
+ return this.dataSource.tableRepresentedObjectForIndex(this, index);
+ }
};
WI.Table.SortOrder = {
Modified: releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js (241713 => 241714)
--- releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js 2019-02-18 16:17:00 UTC (rev 241713)
+++ releases/WebKitGTK/webkit-2.24/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js 2019-02-18 16:17:10 UTC (rev 241714)
@@ -56,8 +56,55 @@
this._cachedNumberOfDescendents = 0;
this._previousSelectedTreeElement = null;
- this._selectionController = new WI.SelectionController(this);
+ let comparator = (a, b) => {
+ function getLevel(treeElement) {
+ let level = 0;
+ while (treeElement = treeElement.parent)
+ level++;
+ return level;
+ }
+
+ function compareSiblings(s, t) {
+ return s.parent.children.indexOf(s) - s.parent.children.indexOf(t);
+ }
+
+ // Translate represented objects to TreeElements, which have the
+ // hierarchical information needed to perform the comparison.
+ a = this.getCachedTreeElement(a);
+ b = this.getCachedTreeElement(b);
+ if (!a || !b)
+ return 0;
+
+ if (a.parent === b.parent)
+ return compareSiblings(a, b);
+
+ let aLevel = getLevel(a);
+ let bLevel = getLevel(b);
+ while (aLevel > bLevel) {
+ if (a.parent === b)
+ return 1;
+ a = a.parent;
+ aLevel--;
+ }
+ while (bLevel > aLevel) {
+ if (b.parent === a)
+ return -1;
+ b = b.parent;
+ bLevel--;
+ }
+
+ while (a.parent !== b.parent) {
+ a = a.parent;
+ b = b.parent;
+ }
+
+ console.assert(a.parent === b.parent, "Missing common ancestor for TreeElements.", a, b);
+ return compareSiblings(a, b);
+ };
+
+ this._selectionController = new WI.SelectionController(this, comparator);
+
this._itemWasSelectedByUser = false;
this._processingSelectionChange = false;
this._suppressNextSelectionDidChangeEvent = false;
@@ -103,16 +150,14 @@
get selectedTreeElement()
{
- let selectedIndex = this._selectionController.lastSelectedItem;
- return this._treeElementAtIndex(selectedIndex) || null;
+ return this.getCachedTreeElement(this._selectionController.lastSelectedItem);
}
set selectedTreeElement(treeElement)
{
- if (treeElement) {
- let index = this._indexOfTreeElement(treeElement);
- this._selectionController.selectItem(index);
- } else
+ if (treeElement)
+ this._selectionController.selectItem(this.objectForSelection(treeElement));
+ else
this._selectionController.deselectAll();
}
@@ -120,8 +165,8 @@
{
if (this.allowsMultipleSelection) {
let treeElements = [];
- for (let index of this._selectionController.selectedItems)
- treeElements.push(this._treeElementAtIndex(index));
+ for (let representedObject of this._selectionController.selectedItems)
+ treeElements.push(this.getCachedTreeElement(representedObject));
return treeElements;
}
@@ -323,13 +368,10 @@
parent.select(true, false);
}
- let removedIndexes = null;
-
let treeOutline = child.treeOutline;
if (treeOutline) {
treeOutline._forgetTreeElement(child);
treeOutline._forgetChildrenRecursive(child);
- removedIndexes = treeOutline._indexesForSubtree(child);
}
if (child.previousSibling)
@@ -345,10 +387,8 @@
child.nextSibling = null;
child.previousSibling = null;
- if (treeOutline) {
- treeOutline._selectionController.didRemoveItems(removedIndexes);
+ if (treeOutline)
treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementRemoved, {element: child});
- }
}
removeChild(child, suppressOnDeselect, suppressSelectSibling)
@@ -383,8 +423,6 @@
treeOutline._forgetChildrenRecursive(child);
}
- let removedIndexes = treeOutline._indexesForSubtree(child);
-
child._detach();
child.treeOutline = null;
child.parent = null;
@@ -393,10 +431,8 @@
this.children.shift();
- if (treeOutline) {
- treeOutline._selectionController.didRemoveItems(removedIndexes);
+ if (treeOutline)
treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementRemoved, {element: child});
- }
}
}
@@ -413,12 +449,6 @@
// add the element
elements.push(element);
this._cachedNumberOfDescendents++;
-
- let index = this._indexOfTreeElement(element);
- if (index >= 0) {
- console.assert(!element.selected, "TreeElement should not be selected before being inserted.");
- this._selectionController.didInsertItem(index);
- }
}
_forgetTreeElement(element)
@@ -447,6 +477,13 @@
if (!representedObject)
return null;
+ // SelectionController requires every selectable object to be unique.
+ // A TreeOutline subclass where multiple TreeElements may be associated
+ // with one represented object can override objectForSelection, and return
+ // a proxy object that is associated with a single TreeElement.
+ if (representedObject.__proxyObjectTreeElement)
+ return representedObject.__proxyObjectTreeElement;
+
if (representedObject.__treeElementIdentifier) {
// If this representedObject has a tree element identifier, and it is a known TreeElement
// in our tree we can just return that tree element.
@@ -806,25 +843,27 @@
{
this._processingSelectionChange = true;
- for (let index of deselectedItems) {
- let treeElement = this._treeElementAtIndex(index);
- console.assert(treeElement, "Missing TreeElement for deselected index " + index);
- if (treeElement) {
- if (treeElement.listItemElement)
- treeElement.listItemElement.classList.remove("selected");
- treeElement.deselect();
- }
+ for (let representedObject of deselectedItems) {
+ let treeElement = this.getCachedTreeElement(representedObject);
+ if (!treeElement)
+ continue;
+
+ if (treeElement.listItemElement)
+ treeElement.listItemElement.classList.remove("selected");
+
+ treeElement.deselect();
}
- for (let index of selectedItems) {
- let treeElement = this._treeElementAtIndex(index);
- console.assert(treeElement, "Missing TreeElement for selected index " + index);
- if (treeElement) {
- if (treeElement.listItemElement)
- treeElement.listItemElement.classList.add("selected");
- const omitFocus = true;
- treeElement.select(omitFocus);
- }
+ for (let representedObject of selectedItems) {
+ let treeElement = this.getCachedTreeElement(representedObject);
+ if (!treeElement)
+ continue;
+
+ if (treeElement.listItemElement)
+ treeElement.listItemElement.classList.add("selected");
+
+ const omitFocus = true;
+ treeElement.select(omitFocus);
}
let selectedTreeElement = this.selectedTreeElement;
@@ -843,44 +882,71 @@
this._processingSelectionChange = false;
}
- selectionControllerNextSelectableIndex(controller, index)
+ selectionControllerFirstSelectableItem(controller)
{
- let treeElement = this._treeElementAtIndex(index);
+ let firstChild = this.children[0];
+ if (firstChild.selectable)
+ return firstChild.representedObject;
+ return this.selectionControllerNextSelectableItem(controller, firstChild.representedObject);
+ }
+
+ selectionControllerLastSelectableItem(controller)
+ {
+ let treeElement = this.children.lastValue;
+ while (treeElement.expanded && treeElement.children.length)
+ treeElement = treeElement.children.lastValue;
+
+ let item = this.objectForSelection(treeElement);
+ if (treeElement.selectable)
+ return item;
+ return this.selectionControllerPreviousSelectableItem(controller, item);
+ }
+
+ selectionControllerPreviousSelectableItem(controller, item)
+ {
+ let treeElement = this.getCachedTreeElement(item);
+ console.assert(treeElement, "Missing TreeElement for representedObject.", item);
if (!treeElement)
- return NaN;
+ return null;
const skipUnrevealed = true;
const stayWithin = null;
const dontPopulate = true;
- while (treeElement = treeElement.traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate)) {
+ while (treeElement = treeElement.traversePreviousTreeElement(skipUnrevealed, stayWithin, dontPopulate)) {
if (treeElement.selectable)
- return this._indexOfTreeElement(treeElement);
+ return this.objectForSelection(treeElement);
}
- return NaN;
+ return null;
}
- selectionControllerPreviousSelectableIndex(controller, index)
+ selectionControllerNextSelectableItem(controller, item)
{
- let treeElement = this._treeElementAtIndex(index);
+ let treeElement = this.getCachedTreeElement(item);
+ console.assert(treeElement, "Missing TreeElement for representedObject.", item);
if (!treeElement)
- return NaN;
+ return null;
const skipUnrevealed = true;
const stayWithin = null;
const dontPopulate = true;
- while (treeElement = treeElement.traversePreviousTreeElement(skipUnrevealed, stayWithin, dontPopulate)) {
+ while (treeElement = treeElement.traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate)) {
if (treeElement.selectable)
- return this._indexOfTreeElement(treeElement);
+ return this.objectForSelection(treeElement);
}
- return NaN;
+ return null;
}
// Protected
+ objectForSelection(treeElement)
+ {
+ return treeElement.representedObject;
+ }
+
selectTreeElementInternal(treeElement, suppressNotification = false, selectedByUser = false)
{
if (this._processingSelectionChange)
@@ -1022,54 +1088,11 @@
return;
}
- let index = this._indexOfTreeElement(treeElement);
- if (isNaN(index))
- return;
-
this._itemWasSelectedByUser = true;
- this._selectionController.handleItemMouseDown(index, event);
+ this._selectionController.handleItemMouseDown(this.objectForSelection(treeElement), event);
this._itemWasSelectedByUser = false;
}
- _indexOfTreeElement(treeElement)
- {
- const skipUnrevealed = false;
- const stayWithin = null;
- const dontPopulate = true;
-
- let index = 0;
- let current = this.children[0];
- while (current) {
- if (treeElement === current)
- return index;
-
- current = current.traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate);
- ++index;
- }
-
- console.assert(false, "Unable to get index for tree element.", treeElement);
- return NaN;
- }
-
- _treeElementAtIndex(index)
- {
- const skipUnrevealed = false;
- const stayWithin = null;
- const dontPopulate = true;
-
- let current = 0;
- let treeElement = this.children[0];
- while (treeElement) {
- if (current === index)
- return treeElement;
-
- treeElement = treeElement.traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate);
- ++current;
- }
-
- return null;
- }
-
_dispatchSelectionDidChangeEvent()
{
let selectedByUser = this._itemWasSelectedByUser;
@@ -1082,34 +1105,6 @@
this.dispatchEventToListeners(WI.TreeOutline.Event.SelectionDidChange, {selectedByUser});
}
-
- _indexesForSubtree(treeElement)
- {
- let treeOutline = treeElement.treeOutline;
- if (!treeOutline)
- return null;
-
- function numberOfElementsInSubtree(treeElement) {
- let elements = treeElement.root ? Array.from(treeElement.children) : [treeElement];
- let count = 0;
- while (elements.length) {
- let child = elements.pop();
- if (child.hidden)
- continue;
-
- count++;
- elements = elements.concat(child.children);
- }
- return count;
- }
-
- let firstChild = treeElement.root ? treeElement.children[0] : treeElement;
- let startIndex = treeOutline._indexOfTreeElement(firstChild);
- let count = numberOfElementsInSubtree(treeElement);
- let indexes = new WI.IndexSet;
- indexes.addRange(startIndex, count);
- return indexes;
- }
};
WI.TreeOutline._styleElement = null;