| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| <link rel="import" href="/tracing/base/settings.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.model', function() { |
| var Settings = tr.b.Settings; |
| |
| /** |
| * A way to persist settings specific to parts of a trace model. |
| * |
| * This object should not be persisted because it builds up internal data |
| * structures that map model objects to settings keys. It should thus be |
| * created for the duration of whatever interaction(s) you're going to do with |
| * model settings, and then discarded. |
| * |
| * This system works on a notion of an object key: for an object's key, it |
| * considers all the other keys in the model. If it is unique, then the key is |
| * persisted to tr.b.Settings. However, if it is not unique, then the |
| * setting is stored on the object itself. Thus, objects with unique keys will |
| * be persisted across page reloads, whereas objects with nonunique keys will |
| * not. |
| */ |
| function ModelSettings(model) { |
| this.model = model; |
| this.objectsByKey_ = []; |
| this.nonuniqueKeys_ = []; |
| this.buildObjectsByKeyMap_(); |
| this.removeNonuniqueKeysFromSettings_(); |
| this.ephemeralSettingsByGUID_ = {}; |
| } |
| |
| ModelSettings.prototype = { |
| buildObjectsByKeyMap_: function() { |
| var objects = []; |
| this.model.iterateAllPersistableObjects(function(o) { |
| objects.push(o); |
| }); |
| |
| var objectsByKey = {}; |
| var NONUNIQUE_KEY = 'nonuniqueKey'; |
| for (var i = 0; i < objects.length; i++) { |
| var object = objects[i]; |
| var objectKey = object.getSettingsKey(); |
| if (!objectKey) |
| continue; |
| if (objectsByKey[objectKey] === undefined) { |
| objectsByKey[objectKey] = object; |
| continue; |
| } |
| objectsByKey[objectKey] = NONUNIQUE_KEY; |
| } |
| |
| var nonuniqueKeys = {}; |
| tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey) { |
| if (objectsByKey[objectKey] !== NONUNIQUE_KEY) |
| return; |
| delete objectsByKey[objectKey]; |
| nonuniqueKeys[objectKey] = true; |
| }); |
| |
| this.nonuniqueKeys = nonuniqueKeys; |
| this.objectsByKey_ = objectsByKey; |
| }, |
| |
| removeNonuniqueKeysFromSettings_: function() { |
| var settings = Settings.get('trace_model_settings', {}); |
| var settingsChanged = false; |
| tr.b.dictionaryKeys(settings).forEach(function(objectKey) { |
| if (!this.nonuniqueKeys[objectKey]) |
| return; |
| settingsChanged = true; |
| delete settings[objectKey]; |
| }, this); |
| if (settingsChanged) |
| Settings.set('trace_model_settings', settings); |
| }, |
| |
| hasUniqueSettingKey: function(object) { |
| var objectKey = object.getSettingsKey(); |
| if (!objectKey) |
| return false; |
| return this.objectsByKey_[objectKey] !== undefined; |
| }, |
| |
| getSettingFor: function(object, objectLevelKey, defaultValue) { |
| var objectKey = object.getSettingsKey(); |
| if (!objectKey || !this.objectsByKey_[objectKey]) { |
| var settings = this.getEphemeralSettingsFor_(object); |
| var ephemeralValue = settings[objectLevelKey]; |
| if (ephemeralValue !== undefined) |
| return ephemeralValue; |
| return defaultValue; |
| } |
| |
| var settings = Settings.get('trace_model_settings', {}); |
| if (!settings[objectKey]) |
| settings[objectKey] = {}; |
| var value = settings[objectKey][objectLevelKey]; |
| if (value !== undefined) |
| return value; |
| return defaultValue; |
| }, |
| |
| setSettingFor: function(object, objectLevelKey, value) { |
| var objectKey = object.getSettingsKey(); |
| if (!objectKey || !this.objectsByKey_[objectKey]) { |
| this.getEphemeralSettingsFor_(object)[objectLevelKey] = value; |
| return; |
| } |
| |
| var settings = Settings.get('trace_model_settings', {}); |
| if (!settings[objectKey]) |
| settings[objectKey] = {}; |
| if (settings[objectKey][objectLevelKey] === value) |
| return; |
| settings[objectKey][objectLevelKey] = value; |
| Settings.set('trace_model_settings', settings); |
| }, |
| |
| getEphemeralSettingsFor_: function(object) { |
| if (object.guid === undefined) |
| throw new Error('Only objects with GUIDs can be persisted'); |
| if (this.ephemeralSettingsByGUID_[object.guid] === undefined) |
| this.ephemeralSettingsByGUID_[object.guid] = {}; |
| return this.ephemeralSettingsByGUID_[object.guid]; |
| } |
| }; |
| |
| return { |
| ModelSettings: ModelSettings |
| }; |
| }); |
| </script> |