Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: Tools/GardeningServer/lib/util.html

Issue 526633002: Apply object updates from the network without blowing away object identity or UI attributes. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Initial Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!--
2 Copyright 2014 The Chromium Authors. All rights reserved.
3 Use of this source code is governed by a BSD-style license that can be
4 found in the LICENSE file.
5 -->
6
7 <link rel="import" href="sugar.html">
8
9 <script>
10
11 var util = util || {};
ojan 2014/09/02 04:08:02 I have an allergy to generic util namespaces. They
Jeffrey Yasskin 2014/09/02 21:45:51 Done.
12
13 (function () {
14 'use strict';
15
16 // Returns true if |updateLeft| can do a field-wise merge from |source| to |targ et|.
17 // We assume |target| and |source| have the same type.
18 // If they're arrays, true if the elements have a |fingerprint| property.
Jeffrey Yasskin 2014/08/30 03:07:24 Other possible names for the |fingerprint| propert
ojan 2014/09/02 04:08:02 I probalby would go with key, but fingerprint is f
Jeffrey Yasskin 2014/09/02 21:45:51 Done.
19 // If they're objects, true if they're not null. (null should be assigned).
20 // Otherwise, false.
21 util.canUpdateLeft = function(target, source) {
ojan 2014/09/02 04:08:02 This is only used in side this file, so no need to
Jeffrey Yasskin 2014/09/02 21:45:51 Right, although it made it a little easier to desc
22 if (Array.isArray(target)) {
23 if (target.length === 0) {
24 // If both arrays are empty, do the no-op merge instead of changing the
25 // object identity.
26 return source.length === 0 || source[0].fingerprint !== undefined;
27 }
28 return target[0].fingerprint !== undefined;
29 } else if (target === null || source === null) {
30 return false;
31 } else if (typeof target === 'object') {
32 return true;
33 }
34 return false;
35 };
36
37 // |target| and |source| must have the same type, which must return true from
38 // util.canUpdateLeft(). An array is treated the same as a dictionary where the
39 // key of an object is its fingerprint. This function will:
40 //
41 // * Ignore elements listed in an object's constructor's |uiStateProperties| ar ray.
42 // * Remove elements from |target| whose key isn't in |source|.
43 // * Copy elements from |source| whose key isn't in |target| or which are !canU pdateLeft().
44 // In particular, we copy |null| rather than trying to merge it.
45 // * If a matching element defines an |updateLeft| method, call that to let typ es customize the update process.
46 // * Call updateLeft recursively for other matching elements.
47 util.updateLeft = function(target, source)
Jeffrey Yasskin 2014/08/30 03:07:24 Other names for |updateLeft| include |assign|, |in
ojan 2014/09/02 04:08:02 updateLeft sgtm
48 {
49 if (!util.canUpdateLeft(target, source)) {
50 throw new TypeError('Unexpected types to updateLeft(): ' +
51 [target, source].map(JSON.stringify).join(', '));
52 }
53
54 if (target.updateLeft) {
55 target.updateLeft(source);
56 return;
57 }
58
59 function updateByIndices(targetIndex, sourceIndex) {
60 if (util.canUpdateLeft(target[targetIndex], source[sourceIndex])) {
61 util.updateLeft(target[targetIndex], source[sourceIndex]);
62 } else {
63 target[targetIndex] = source[sourceIndex];
64 }
65 }
66
67 function indicesByFingerprint(array) {
ojan 2014/09/02 04:08:02 Since this isn't using any closed variables, it co
Jeffrey Yasskin 2014/09/02 21:45:51 Done.
68 var indices = {};
69 array.forEach(function(elem, index) {
70 indices[elem.fingerprint] = index;
71 });
72 return indices;
73 }
74
75 if (Array.isArray(target)) {
76 var sourceIndices = indicesByFingerprint(source);
ojan 2014/09/02 04:08:02 This would be a bit easier to read if you move the
Jeffrey Yasskin 2014/09/02 21:45:51 Done. I decided to pull these all the way out of u
77 // Remove elements from |target| that aren't in |source|.
78 target.remove(function(elem) {
79 return !sourceIndices.hasOwnProperty(elem.fingerprint);
80 });
81
82 var targetIndices = indicesByFingerprint(target);
83 Object.keys(sourceIndices, function(fingerprint, sourceIndex) {
84 if (targetIndices.hasOwnProperty(fingerprint)) {
85 // Recursively update elements that are present in both arrays.
86 updateByIndices(targetIndices[fingerprint], sourceIndex);
87 } else {
88 // And add elements in |source| that weren't in |target|. Because this
89 // adds to the end, it doesn't mess up |targetIndices|.
90 target.push(source[sourceIndex]);
91 }
92 });
93
94 // Sort |target| into the same order as |source|.
95 target.sort(function(a, b) {
96 return sourceIndices[a.fingerprint] - sourceIndices[b.fingerprint];
97 });
98 } else {
99 // They're objects. Prepare to filter out properties that reflect local UI
100 // state that wasn't loaded from the server.
101 var uiStateProperties = target.constructor.uiStateProperties;
Jeffrey Yasskin 2014/08/30 03:07:24 |uiStateProperties| could be |transientProperties|
ojan 2014/09/02 04:08:02 transient sgtm.
Jeffrey Yasskin 2014/09/02 21:45:51 Done.
102 var isUiStateProperty = function(name) {
103 return uiStateProperties && uiStateProperties.indexOf(name) !== -1;
104 };
105
106 // Remove elements from |target| that aren't in |source|.
107 Object.keys(target, function(key) {
108 if (isUiStateProperty(key))
109 return;
110 if (!source.hasOwnProperty(key))
111 delete target[key];
112 });
113
114 Object.keys(source, function(key, sourceValue) {
115 if (isUiStateProperty(key))
116 return;
117 if (target.hasOwnProperty(key)) {
118 // Recursively update elements that are present in both arrays.
119 updateByIndices(key, key);
120 } else {
121 // And add elements in |source| that weren't in |target|.
122 target[key] = sourceValue;
123 }
124 });
125 }
126 };
127
128 })();
129
130 </script>
OLDNEW
« no previous file with comments | « Tools/GardeningServer/lib/test/util-tests.html ('k') | Tools/GardeningServer/model/ct-commit-list.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698