config.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. define([
  4. 'base/js/utils',
  5. ],
  6. function(utils) {
  7. "use strict";
  8. var ConfigSection = function(section_name, options) {
  9. this.section_name = section_name;
  10. this.base_url = options.base_url;
  11. this.data = {};
  12. var that = this;
  13. /* .loaded is a promise, fulfilled the first time the config is loaded
  14. * from the server. Code can do:
  15. * conf.loaded.then(function() { ... using conf.data ... });
  16. */
  17. this._one_load_finished = false;
  18. this.loaded = new Promise(function(resolve, reject) {
  19. that._finish_firstload = resolve;
  20. });
  21. };
  22. ConfigSection.prototype.api_url = function() {
  23. return utils.url_path_join(this.base_url, 'api/config',
  24. utils.encode_uri_components(this.section_name));
  25. };
  26. ConfigSection.prototype._load_done = function() {
  27. if (!this._one_load_finished) {
  28. this._one_load_finished = true;
  29. this._finish_firstload();
  30. }
  31. };
  32. ConfigSection.prototype.load = function() {
  33. var that = this;
  34. return utils.promising_ajax(this.api_url(), {
  35. cache: false,
  36. type: "GET",
  37. dataType: "json",
  38. }).then(function(data) {
  39. that.data = data;
  40. that._load_done();
  41. return data;
  42. });
  43. };
  44. /**
  45. * Modify the config values stored. Update the local data immediately,
  46. * send the change to the server, and use the updated data from the server
  47. * when the reply comes.
  48. */
  49. ConfigSection.prototype.update = function(newdata) {
  50. $.extend(true, this.data, newdata); // true -> recursive update
  51. var that = this;
  52. return utils.promising_ajax(this.api_url(), {
  53. processData: false,
  54. type : "PATCH",
  55. data: JSON.stringify(newdata),
  56. dataType : "json",
  57. contentType: 'application/json',
  58. }).then(function(data) {
  59. that.data = data;
  60. that._load_done();
  61. return data;
  62. });
  63. };
  64. var ConfigWithDefaults = function(section, defaults, classname) {
  65. this.section = section;
  66. this.defaults = defaults;
  67. this.classname = classname;
  68. };
  69. ConfigWithDefaults.prototype._class_data = function() {
  70. if (this.classname) {
  71. return this.section.data[this.classname] || {};
  72. } else {
  73. return this.section.data;
  74. }
  75. };
  76. /**
  77. * Wait for config to have loaded, then get a value or the default.
  78. * Returns a promise.
  79. */
  80. ConfigWithDefaults.prototype.get = function(key) {
  81. var that = this;
  82. return this.section.loaded.then(function() {
  83. return that.get_sync(key);
  84. });
  85. };
  86. /**
  87. * Return a config value. If config is not yet loaded, return the default
  88. * instead of waiting for it to load.
  89. */
  90. ConfigWithDefaults.prototype.get_sync = function(key) {
  91. var data = this._class_data();
  92. if (key === undefined) {
  93. // no key specified, return full config data
  94. return $.extend(true, {}, this.defaults, data);
  95. }
  96. var value = data[key];
  97. if (value !== undefined) {
  98. if (typeof value == 'object') {
  99. // merge with defaults if it's an object
  100. return $.extend(true, {}, this.defaults[key], value);
  101. } else {
  102. return value;
  103. }
  104. }
  105. return this.defaults[key];
  106. };
  107. /**
  108. * Set a config value. Send the update to the server, and change our
  109. * local copy of the data immediately.
  110. * Returns a promise which is fulfilled when the server replies to the
  111. * change.
  112. */
  113. ConfigWithDefaults.prototype.set = function(key, value) {
  114. var d = {};
  115. d[key] = value;
  116. if (this.classname) {
  117. var d2 = {};
  118. d2[this.classname] = d;
  119. return this.section.update(d2);
  120. } else {
  121. return this.section.update(d);
  122. }
  123. };
  124. return {ConfigSection: ConfigSection,
  125. ConfigWithDefaults: ConfigWithDefaults,
  126. };
  127. });