// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. define([ 'base/js/utils', ], function(utils) { "use strict"; var ConfigSection = function(section_name, options) { this.section_name = section_name; this.base_url = options.base_url; this.data = {}; var that = this; /* .loaded is a promise, fulfilled the first time the config is loaded * from the server. Code can do: * conf.loaded.then(function() { ... using conf.data ... }); */ this._one_load_finished = false; this.loaded = new Promise(function(resolve, reject) { that._finish_firstload = resolve; }); }; ConfigSection.prototype.api_url = function() { return utils.url_path_join(this.base_url, 'api/config', utils.encode_uri_components(this.section_name)); }; ConfigSection.prototype._load_done = function() { if (!this._one_load_finished) { this._one_load_finished = true; this._finish_firstload(); } }; ConfigSection.prototype.load = function() { var that = this; return utils.promising_ajax(this.api_url(), { cache: false, type: "GET", dataType: "json", }).then(function(data) { that.data = data; that._load_done(); return data; }); }; /** * Modify the config values stored. Update the local data immediately, * send the change to the server, and use the updated data from the server * when the reply comes. */ ConfigSection.prototype.update = function(newdata) { $.extend(true, this.data, newdata); // true -> recursive update var that = this; return utils.promising_ajax(this.api_url(), { processData: false, type : "PATCH", data: JSON.stringify(newdata), dataType : "json", contentType: 'application/json', }).then(function(data) { that.data = data; that._load_done(); return data; }); }; var ConfigWithDefaults = function(section, defaults, classname) { this.section = section; this.defaults = defaults; this.classname = classname; }; ConfigWithDefaults.prototype._class_data = function() { if (this.classname) { return this.section.data[this.classname] || {}; } else { return this.section.data; } }; /** * Wait for config to have loaded, then get a value or the default. * Returns a promise. */ ConfigWithDefaults.prototype.get = function(key) { var that = this; return this.section.loaded.then(function() { return that.get_sync(key); }); }; /** * Return a config value. If config is not yet loaded, return the default * instead of waiting for it to load. */ ConfigWithDefaults.prototype.get_sync = function(key) { var data = this._class_data(); if (key === undefined) { // no key specified, return full config data return $.extend(true, {}, this.defaults, data); } var value = data[key]; if (value !== undefined) { if (typeof value == 'object') { // merge with defaults if it's an object return $.extend(true, {}, this.defaults[key], value); } else { return value; } } return this.defaults[key]; }; /** * Set a config value. Send the update to the server, and change our * local copy of the data immediately. * Returns a promise which is fulfilled when the server replies to the * change. */ ConfigWithDefaults.prototype.set = function(key, value) { var d = {}; d[key] = value; if (this.classname) { var d2 = {}; d2[this.classname] = d; return this.section.update(d2); } else { return this.section.update(d); } }; return {ConfigSection: ConfigSection, ConfigWithDefaults: ConfigWithDefaults, }; });