Content.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5. /**
  6. * Licensed Materials - Property of IBM
  7. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2019, 2020
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. */
  10. define(['underscore', '../lib/@waca/dashboard-common/dist/core/APIFactory', './ContentAPISpec', '../api/ContentAPI', '../features/FeatureLoader', '../dashboard/util/PropertyLayoutHelper', '../features/content/state/impl/StateImpl', '../features/content/internalModels/InternalModels', '../features/content/contentFilter/ContentFilter', '../features/content/serializer/Serializer', '../dashboard/util/DashboardSpecHelper'], function (_, APIFactory, ContentAPISpec, ContentAPI, FeatureLoader, PropertyLayoutHelper, State, InternalModels, ContentFilter, Serializer, DashboardSpecHelper) {
  11. var Content = function (_ContentAPISpec) {
  12. _inherits(Content, _ContentAPISpec);
  13. function Content(options) {
  14. _classCallCheck(this, Content);
  15. var _this = _possibleConstructorReturn(this, _ContentAPISpec.call(this));
  16. _this.boardModel = options.boardModel;
  17. _this.layoutModel = options.layoutModel;
  18. _this.profile = options.profile;
  19. _this.creationTransctionToken = options.transactionToken;
  20. _this.contentFeatureCollection = options.contentFeatureCollection || [];
  21. // TODO: revisit this
  22. // The widget model can be resolved based on the layout model and the boardModel
  23. // The only time it is passed in here is for the case of the LiveWidgetPreview
  24. // where we need to create a content API for a widget model that is disconnected
  25. _this.widgetModel = options.widgetModel;
  26. _this.contentMap = {};
  27. _this.container = options.container;
  28. _this.featureLoaderClass = options.featureLoaderClass || FeatureLoader;
  29. _this.featureLoader = options.featureLoader;
  30. _this.canvas = options.canvas;
  31. _this.dashboardFeatures = options.dashboardFeatures;
  32. _this.transaction = _this.dashboardFeatures.getFeature('Transaction');
  33. _this.lifeCycleManager = _this.dashboardFeatures.getFeature('LifeCycle');
  34. _this.logger = _this.dashboardFeatures.getFeature('Logger');
  35. _this.contentFactory = _this.dashboardFeatures.getFeature('ContentFactory');
  36. if (!_this.featureLoader) {
  37. _this.createFeatureLoader();
  38. }
  39. _this._updateContentModelFeatures();
  40. var model = _this._getModel();
  41. model.on('add:item', _this.onAddItem, _this);
  42. model.on('remove:item', _this.onRemoveItem, _this);
  43. model.on('change:parent', _this.onChangeParent, _this);
  44. model.on('pre:remove:item', _this.preRemoveItem, _this);
  45. return _this;
  46. }
  47. /**
  48. * In this method we are directly modifing the content model
  49. * (ContentModel.js) instance's "features" property object.
  50. * Eventually ContentModel will go away at which point the following
  51. * will required to be changed to not modify another object's instance
  52. * @private
  53. */
  54. Content.prototype._updateContentModelFeatures = function _updateContentModelFeatures() {
  55. var _this2 = this;
  56. var getLoadedFeatures = this.featureLoader.getLoadedFeatures.bind(this.featureLoader);
  57. var _getModel$getContentM = this._getModel().getContentModel(),
  58. contentModelFeatures = _getModel$getContentM.features;
  59. var IGNORE_CONTENT_FEATURES = ['toJSON', 'Serializer'];
  60. contentModelFeatures.toJSON = function () {
  61. var loadedFeatures = getLoadedFeatures();
  62. var featureNames = Object.keys(loadedFeatures).concat(Object.keys(contentModelFeatures)).filter(function (item) {
  63. return IGNORE_CONTENT_FEATURES.indexOf(item) === -1;
  64. });
  65. var features = {};
  66. featureNames.forEach(function (featureName) {
  67. var feature = null;
  68. if (loadedFeatures[featureName] && typeof loadedFeatures[featureName].toJSON === 'function') {
  69. feature = loadedFeatures[featureName].toJSON();
  70. } else if (contentModelFeatures[featureName]) {
  71. feature = contentModelFeatures[featureName];
  72. } else {
  73. _this2.logger.info('Data for feature "' + featureName + '" is not persisted');
  74. }
  75. if (feature && Object.keys(feature).length > 0) {
  76. features[featureName] = feature;
  77. }
  78. });
  79. if (features.hasOwnProperty('Models.internal')) {
  80. features['Models_internal'] = features['Models.internal'];
  81. delete features['Models.internal'];
  82. }
  83. return features;
  84. };
  85. };
  86. Content.prototype.onAddItem = function onAddItem(payload) {
  87. var newModelId = payload.value.parameter.model.id;
  88. //currently, in getContentInstance(), we will auto-generate the missing contentInstance.
  89. this.getContentInstance(newModelId, false, payload.data ? payload.data.transactionToken : null);
  90. };
  91. Content.prototype.preRemoveItem = function preRemoveItem(payload) {
  92. var childId = payload.value.parameter;
  93. var contentImpl = this.getContentInstance(childId);
  94. if (contentImpl) {
  95. var content = contentImpl.getAPI();
  96. var contentViewDom = content.getFeature('ContentViewDOM');
  97. var contentNode = contentViewDom && contentViewDom.getNode();
  98. if (contentNode) {
  99. var dashboardAPI = this.dashboardFeatures.getFeature('API');
  100. var controller = dashboardAPI.getFeature('InteractionController.internal');
  101. controller.selectionHandler.deselectNode(contentNode);
  102. }
  103. }
  104. };
  105. Content.prototype.onRemoveItem = function onRemoveItem(payload) {
  106. var childId = payload.value.parameter;
  107. var contentImpl = this.getContentInstance(childId);
  108. if (contentImpl) {
  109. contentImpl.destroy();
  110. delete this.contentMap[childId];
  111. }
  112. };
  113. Content.prototype.onChangeParent = function onChangeParent(payload) {
  114. var newParentId = payload.value.parameter.parentId;
  115. if (this.getContainer().getId() !== newParentId) {
  116. var newContainerInst = this.canvas.getRootContentInstance().getContentInstance(newParentId);
  117. this.moveToContainer(newContainerInst);
  118. }
  119. };
  120. /**
  121. * create the feature loader, and register core features before initialization,
  122. * the core features includes:
  123. * - state
  124. * - Models.internal
  125. * - ContentFilter
  126. * - Serializer
  127. */
  128. Content.prototype.createFeatureLoader = function createFeatureLoader() {
  129. var type = this.getType();
  130. var types = [type];
  131. if (type !== this._getModel().type) {
  132. types.push(this._getModel().type);
  133. }
  134. this.featureLoader = new this.featureLoaderClass({
  135. featureParams: {
  136. // todo - we should not pass the dashboard API to the features like this
  137. dashboardAPI: this.dashboardFeatures.getFeature('API'),
  138. content: this.getAPI(),
  139. featureSpecs: this._getModel().getContentModel().features,
  140. transactionToken: this.creationTransctionToken
  141. },
  142. externalFeatures: this.dashboardFeatures,
  143. lifeCycleManager: this.lifeCycleManager,
  144. types: types,
  145. parentAPI: this
  146. });
  147. // State feature is a core feature that requires to be available prior to initialize
  148. this.featureLoader.registerFeature('state', new State({
  149. logger: this.logger
  150. }), {
  151. 'containerId': 'com.ibm.bi.dashboard.content-features',
  152. 'name': 'state',
  153. 'types': ['widget']
  154. });
  155. this.featureLoader.registerFeature('Models.internal', new InternalModels({
  156. widgetModel: this.widgetModel,
  157. layoutModel: this.layoutModel
  158. }), {
  159. 'containerId': 'com.ibm.bi.dashboard.content-features',
  160. 'name': 'InternalModels'
  161. });
  162. // Content filter is required to be available before initialization
  163. this.featureLoader.registerFeature('ContentFilter', new ContentFilter({
  164. content: this,
  165. logger: this.logger
  166. }), {
  167. 'containerId': 'com.ibm.bi.dashboard.content-features',
  168. 'name': 'ContentFilter'
  169. });
  170. // Content serializer is required to be available before initialization,
  171. // as the toJSON can be called in the middle of creation of a content
  172. this.featureLoader.registerFeature('Serializer', new Serializer({
  173. layoutModel: this.layoutModel,
  174. content: this,
  175. logger: this.logger
  176. }), {
  177. 'containerId': 'com.ibm.bi.dashboard.content-features.Serializer',
  178. 'name': 'Serializer'
  179. });
  180. this._createdFeatureLoader = true;
  181. };
  182. Content.prototype.initialize = function initialize() {
  183. var _this3 = this;
  184. if (!this._initializePromise) {
  185. var promises = [];
  186. promises.push(this.featureLoader.loadFeaturesFromArray(this.contentFeatureCollection));
  187. var items = this._getModelItems();
  188. if (items) {
  189. // Walk the children and initialize the child content
  190. items.forEach(function (element) {
  191. var childContent = _this3.getContentInstance(element.id, true, _this3.creationTransctionToken);
  192. if (childContent) {
  193. promises.push(childContent.initialize());
  194. }
  195. });
  196. }
  197. this._initializePromise = Promise.all(promises);
  198. }
  199. return this._initializePromise.then(function () {
  200. return _this3.getAPI();
  201. });
  202. };
  203. Content.prototype.registerFeatures = function registerFeatures(features) {
  204. return this.featureLoader.loadFeaturesFromArray(features);
  205. };
  206. /**
  207. * A function to manually register a feature. Could be used by the dashboard framework to register low level features.
  208. * This method should be exposed through the content API interface
  209. * @param {String} name
  210. * @param {Object} instance
  211. * @param {Object} spec
  212. */
  213. Content.prototype.registerFeature = function registerFeature(name, instance, spec, skipInitialization) {
  214. var _this4 = this;
  215. return this.initialize().then(function () {
  216. return _this4.featureLoader.registerFeature(name, instance, spec, skipInitialization);
  217. });
  218. };
  219. Content.prototype.getAPI = function getAPI() {
  220. if (!this.api) {
  221. this.api = APIFactory.createAPI(this, [ContentAPI]);
  222. }
  223. return this.api;
  224. };
  225. Content.prototype.destroyContentMap = function destroyContentMap() {
  226. var _this5 = this;
  227. Object.keys(this.contentMap).forEach(function (childID) {
  228. var childContent = _this5.contentMap[childID];
  229. childContent && childContent.destroy && childContent.destroy();
  230. });
  231. };
  232. Content.prototype.destroy = function destroy() {
  233. var model = this._getModel();
  234. model.off('add:item', this.onAddItem, this);
  235. model.off('remove:item', this.onRemoveItem, this);
  236. model.off('change:parent', this.onChangeParent, this);
  237. this.destroyContentMap();
  238. if (this._createdFeatureLoader) {
  239. this.featureLoader.destroy();
  240. }
  241. this.featureLoader = null;
  242. this.dashboardFeatures = null;
  243. this.boardModel = null;
  244. this.layoutModel = null;
  245. this.widgetModel = null;
  246. this.contentMap = null;
  247. this.canvas = null;
  248. this.api = null;
  249. };
  250. Content.prototype.getId = function getId() {
  251. return this._getModel().getId();
  252. };
  253. Content.prototype._getWidgetModel = function _getWidgetModel() {
  254. if (!this.widgetModel) {
  255. this.widgetModel = this.boardModel.getWidgetModel(this.getId());
  256. }
  257. return this.widgetModel;
  258. };
  259. Content.prototype.getType = function getType() {
  260. var type = this.layoutModel.type;
  261. var widgetModel = this._getWidgetModel();
  262. if (widgetModel) {
  263. type += '.' + widgetModel.type;
  264. }
  265. return type;
  266. };
  267. Content.prototype.addContent = function addContent(options, transactionToken) {
  268. var _this6 = this;
  269. if (_.isNumber(options.position)) {
  270. var beforeContent = this.getChildren()[options.position];
  271. options.insertBefore = beforeContent && beforeContent.getId();
  272. }
  273. if (options.content) {
  274. return this._getContentSpec(options.content).then(function (spec) {
  275. if (spec) {
  276. options.type = options.content.getType();
  277. spec.layout = spec.layout[0];
  278. options.spec = spec;
  279. }
  280. return _this6._addModel(options, transactionToken);
  281. });
  282. }
  283. return this._addModel(options, transactionToken);
  284. };
  285. Content.prototype._addModel = function _addModel(options, transactionToken) {
  286. var _this7 = this;
  287. //Todo: temporary until all uses are updated to use the properties
  288. options.properties = Object.assign(options.properties || {}, options.layout);
  289. delete options.layout;
  290. return this.contentFactory.addModel(options, {
  291. boardModel: this.boardModel,
  292. canvas: this.canvas,
  293. canvasContent: this
  294. }, transactionToken).then(function (modelId) {
  295. return _this7.getContentInstance(modelId).initialize();
  296. }).then(function (contentApi) {
  297. var properties = options.properties || {};
  298. Object.keys(properties).forEach(function (propertyName) {
  299. contentApi.setPropertyValue(propertyName, properties[propertyName], transactionToken);
  300. });
  301. return contentApi;
  302. });
  303. };
  304. Content.prototype._getContentSpec = function _getContentSpec(content) {
  305. // This is a unique case for addContent where the added content may be coming from a different dashboard.
  306. // Conscious choice not to expose a content api to get the dashboard api since:
  307. // 1. This can go away when the Serializer is able to return the currently missing dashboard level information relating to a content. See DashboardSpecHelper for specifics.
  308. // 2. Worried it may be abused, especially in content features.
  309. var dashboard = content.getFeature('Models.internal').getLayoutModel().boardModel.dashboardApi;
  310. var layoutController = dashboard.getFeature('LegacyViewControllers').getLayoutController();
  311. return layoutController.getInteractionController().then(function (controller) {
  312. var specHelper = new DashboardSpecHelper(controller);
  313. var contentSpec = specHelper.getContentsToJSONSpec(content).spec;
  314. return specHelper.validateDashboardSpec(contentSpec);
  315. });
  316. };
  317. Content.prototype.removeChildContent = function removeChildContent(id, transactionToken) {
  318. // Content can only delete its children.. make sure the content belongs to this container before deleting it
  319. var content = this.getContentInstance(id);
  320. if (content) {
  321. this.boardModel.removeLayouts(id, 'api', this._convertOptions(transactionToken));
  322. }
  323. };
  324. Content.prototype.removeContentReference = function removeContentReference(content) {
  325. delete this.contentMap[content.getId()];
  326. };
  327. Content.prototype.addContentReference = function addContentReference(content) {
  328. this.contentMap[content.getId()] = content;
  329. };
  330. Content.prototype.moveToContainer = function moveToContainer(newContainerInst) {
  331. this.container.removeContentReference(this);
  332. this.container = newContainerInst;
  333. newContainerInst.addContentReference(this);
  334. };
  335. Content.prototype.moveContent = function moveContent(containerId, contentIdList, transactionToken, insertBeforeMap) {
  336. var _this8 = this;
  337. var containerInst = containerId === this.getId() ? this : this.getContentInstance(containerId);
  338. if (containerInst) {
  339. var moveOptions = {
  340. updateArray: []
  341. };
  342. var contentInstList = contentIdList.map(function (id) {
  343. return _this8.canvas.getContentInstance(id);
  344. });
  345. contentInstList.forEach(function (content) {
  346. if (content) {
  347. var id = content.getId();
  348. var contentEntry = {
  349. id: id,
  350. parentId: containerInst.getId()
  351. };
  352. if (insertBeforeMap && insertBeforeMap[id]) {
  353. contentEntry.insertBefore = insertBeforeMap[id];
  354. }
  355. moveOptions.updateArray.push(contentEntry);
  356. content.moveToContainer(containerInst);
  357. }
  358. });
  359. if (moveOptions.updateArray.length > 0) {
  360. this.layoutModel.getTopLayoutModel().updateModel(moveOptions, null, this._convertOptions(transactionToken));
  361. }
  362. return contentInstList.map(function (instance) {
  363. return instance.getAPI();
  364. });
  365. } else {
  366. this.logger.error('cannot find container ' + containerId);
  367. }
  368. };
  369. Content.prototype.removeContent = function removeContent(id, transactionToken) {
  370. this.removeChildContent(id, transactionToken);
  371. };
  372. Content.prototype.getContentInstance = function getContentInstance(id, doNotInitialize, transactionToken) {
  373. var content = this.contentMap[id];
  374. var items = this._getModelItems();
  375. if (!content && items) {
  376. var matchedModel = items.find(function (model) {
  377. return model.id === id;
  378. });
  379. if (matchedModel) {
  380. // TODO -- we should not get here but it is ok for now
  381. // All direct children content API should be available and initialized
  382. // Today, we will get here, if a widget was added in authoring, and someone is trying to get the content API
  383. // The right way is to go through the content API to add content which will give the parent content to properly create and initalize, or use model event to monitor the add/remove of content
  384. content = this.contentFactory.createContent({
  385. contentFeatureCollection: this.contentFeatureCollection,
  386. dashboardFeatures: this.dashboardFeatures,
  387. boardModel: this.boardModel,
  388. layoutModel: matchedModel,
  389. featureLoaderClass: this.featureLoaderClass,
  390. canvas: this.canvas,
  391. container: this,
  392. profile: this.profile,
  393. transactionToken: transactionToken,
  394. type: matchedModel.type
  395. });
  396. APIFactory.setParentChildRelation(this.canvas, content);
  397. if (!doNotInitialize) {
  398. content.initialize();
  399. }
  400. this.contentMap[id] = content;
  401. } else {
  402. // Ask the children to find the instance;
  403. for (var i = 0; i < items.length && !content; i++) {
  404. var contentInstance = this.getContentInstance(items[i].id, false, transactionToken);
  405. content = contentInstance.getContentInstance(id, doNotInitialize, transactionToken);
  406. }
  407. }
  408. }
  409. return content;
  410. };
  411. Content.prototype.getContentPosition = function getContentPosition(id) {
  412. var position = -1;
  413. var items = this._getModelItems();
  414. if (items && items.length) {
  415. position = items.findIndex(function (model) {
  416. return model.id === id;
  417. });
  418. if (position === -1) {
  419. // Find the instance from children and return its position
  420. for (var i = 0; i < items.length && position === -1; i++) {
  421. var contentInstance = this.getContentInstance(items[i].id);
  422. position = contentInstance.getContentPosition(id);
  423. }
  424. }
  425. }
  426. return position;
  427. };
  428. Content.prototype.getContent = function getContent(id) {
  429. var content = this.getContentInstance(id);
  430. return content ? content.getAPI() : null;
  431. };
  432. Content.prototype.getContainer = function getContainer() {
  433. var containerInst = this.getContainerInstance();
  434. return containerInst && containerInst.getAPI();
  435. };
  436. Content.prototype.getContainerInstance = function getContainerInstance() {
  437. return this.container;
  438. };
  439. Content.prototype.getChildren = function getChildren() {
  440. var _this9 = this;
  441. var items = this._getModelItems() || [];
  442. return items.map(function (item) {
  443. return _this9.getContent(item.id);
  444. });
  445. };
  446. Content.prototype.findContent = function findContent() {
  447. var _this10 = this;
  448. var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  449. if (_.isEmpty(selector)) {
  450. selector.type = 'widget';
  451. }
  452. var contents = [];
  453. var items = this._getModelItems();
  454. if (items) {
  455. items.forEach(function (item) {
  456. var content = _this10.getContent(item.id);
  457. var contentFilter = content.getFeature('ContentFilter');
  458. if (contentFilter.match({ selector: selector, layout: item })) {
  459. contents.push(content);
  460. }
  461. contents.push.apply(contents, content.findContent(selector));
  462. });
  463. }
  464. return contents;
  465. };
  466. Content.prototype._convertOptions = function _convertOptions(transactionToken) {
  467. var oldOptions = {
  468. skipUndoRedo: true
  469. };
  470. if (transactionToken && transactionToken.transactionId) {
  471. oldOptions.undoRedoTransactionId = transactionToken.transactionId;
  472. oldOptions.transactionToken = transactionToken;
  473. }
  474. return oldOptions;
  475. };
  476. Content.prototype.getPropertyLayoutList = function getPropertyLayoutList() {
  477. var properties = this.getFeature('Properties');
  478. var layoutList = properties.getPropertyLayoutList();
  479. var propertyList = this.getPropertyList();
  480. return PropertyLayoutHelper.getExpandedLayoutList(layoutList, propertyList, this.profile);
  481. };
  482. Content.prototype.getPropertyNameList = function getPropertyNameList() {
  483. var properties = this.getFeature('Properties');
  484. return properties.getPropertyList().map(function (prop) {
  485. return prop.id;
  486. });
  487. };
  488. // TODO: the third param options should always be only transactionToken
  489. // but currently in several places we call setPropertyValue with
  490. // the `options` being transactionToken + some other options, we should avoid pollute transactionToken
  491. Content.prototype.setPropertyValue = function setPropertyValue(name, value, options) {
  492. var property = this.getPropertyList().find(function (property) {
  493. return property.id === name;
  494. });
  495. if (property) {
  496. return property.setPropertyValue(value, options);
  497. } else {
  498. return this._getModel().getContentModel().setPropertyValue(name, value, options);
  499. }
  500. };
  501. Content.prototype.getPropertyValue = function getPropertyValue(name) {
  502. var property = this.getPropertyList().find(function (property) {
  503. return property.id === name;
  504. });
  505. if (property) {
  506. return property.getPropertyValue();
  507. } else {
  508. return this._getModel().getContentModel().getPropertyValue(name);
  509. }
  510. };
  511. Content.prototype.__getPropertyValueFunc = function __getPropertyValueFunc(getterFunction, property) {
  512. var propValue = void 0;
  513. if (getterFunction) {
  514. propValue = getterFunction();
  515. } else {
  516. propValue = this._getModel().getContentModel().getPropertyValue(property.id);
  517. }
  518. // Use == instead of === to check for both null and underfined
  519. if (propValue == null && property.defaultValue != null) {
  520. propValue = property.defaultValue;
  521. }
  522. return propValue;
  523. };
  524. Content.prototype.getPropertyList = function getPropertyList() {
  525. var _this11 = this;
  526. var propertiesFeature = this.getFeature('Properties');
  527. if (!propertiesFeature) {
  528. return [];
  529. }
  530. var properties = propertiesFeature.getPropertyList();
  531. // Default any missing get/set methods
  532. // This is the case for any new property added through the property provider
  533. var _loop = function _loop(i) {
  534. var property = properties[i];
  535. if (!property.isGetterSet) {
  536. // Make sure we don't set the getPropertyValue over and over against
  537. // The property list get s called everytime..
  538. property.isGetterSet = true;
  539. var originalPropertyGetter = property.getPropertyValue && property.getPropertyValue.bind(property);
  540. property.getPropertyValue = _this11.__getPropertyValueFunc.bind(_this11, originalPropertyGetter, property);
  541. }
  542. if (!property.setPropertyValue) {
  543. // If a setPropertyValue is not defined, we assume it is a new property added by a feature provider
  544. // in this case will tag it to support api events
  545. property.setPropertyValue = function (value, options) {
  546. _this11._getModel().getContentModel().setPropertyValue(property.id, value, options);
  547. };
  548. }
  549. };
  550. for (var i = 0; i < properties.length; i++) {
  551. _loop(i);
  552. }
  553. return properties;
  554. };
  555. Content.prototype.getFeature = function getFeature(id) {
  556. if (this.featureLoader) {
  557. return this.featureLoader.getFeature(id);
  558. }
  559. };
  560. Content.prototype.setFeatureEnabled = function setFeatureEnabled(id, isEnabled) {
  561. if (this.featureLoader) {
  562. this.featureLoader.setFeatureEnabled(id, isEnabled);
  563. }
  564. };
  565. Content.prototype._getModel = function _getModel() {
  566. return this.layoutModel;
  567. };
  568. Content.prototype._getModelItems = function _getModelItems() {
  569. return this.layoutModel.items;
  570. };
  571. return Content;
  572. }(ContentAPISpec);
  573. return Content;
  574. });
  575. //# sourceMappingURL=Content.js.map