@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
349 lines (301 loc) • 10 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2009-2021 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
/*global Promise */// declare unusual global vars for JSLint/SAPUI5 validation
// Provides class sap.ui.core.util.Export
sap.ui.define([
'sap/ui/core/Control',
'./ExportRow',
'./File',
'sap/base/Log',
'./ExportColumn', // convenience dependency for legacy code that uses global names
'./ExportType' // convenience dependency for legacy code that uses global names
],
function(Control, ExportRow, File, Log) {
'use strict';
// Utility functions to add jQuery Promise methods to a standard ES6 Promise object for compatibility reasons
function wrapCallback(fnCallback, oContext) {
if (fnCallback) {
return function() {
return fnCallback.apply(oContext, arguments);
};
} else {
return fnCallback;
}
}
function printJqPromiseDeprecationWarning(sMethodName) {
Log.warning("Usage of deprecated jQuery Promise method: '" + sMethodName + "'. " +
"Please use the standard Promise methods 'then' / 'catch' instead!", "", "sap.ui.core.util.Export");
}
// Adds the jQuery Promise methods 'done', 'fail', 'always', 'pipe' and 'state' to the Promise object (and all promise objects created by itself).
function createJqCompatiblePromise(fnPromise, oContext) {
var oOriginalPromise = new Promise(fnPromise);
// if no context is set, use the promise as context
oContext = oContext || oOriginalPromise;
// track the promise state (for state method)
var bResolved = false, bRejected = false;
oOriginalPromise.then(function(v) {
bResolved = true;
return v;
}, function(e) {
bRejected = true;
throw e;
});
// save original standard methods
var mOriginalMethods = {
then: oOriginalPromise.then,
"catch": oOriginalPromise["catch"]
};
function makePromiseJqCompatible(oPromise) {
// Wrap standard promise methods
oPromise.then = function(fnSuccessCallback, fnErrorCallback) {
// TODO: handle multiple arguments + array of callbacks
var aArgs = [ wrapCallback(fnSuccessCallback, oContext), wrapCallback(fnErrorCallback, oContext) ];
return makePromiseJqCompatible(mOriginalMethods.then.apply(oPromise, aArgs), oContext);
};
oPromise["catch"] = function(fnCallback) {
var aArgs = [ wrapCallback(fnCallback, oContext) ];
return makePromiseJqCompatible(mOriginalMethods["catch"].apply(oPromise, aArgs), oContext);
};
// Map jQuery Promise methods to standard methods and add a deprecation warning
[ {
jq: "done",
es6: "then"
}, {
jq: "fail",
es6: "catch"
}, {
jq: "always",
es6: "then"
}].forEach(function(mConfig) {
oPromise[mConfig.jq] = function() {
printJqPromiseDeprecationWarning(mConfig.jq);
var oReturnPromise = null;
Array.prototype.concat.apply([], arguments).forEach(function(fnCallback) {
var fnWrappedCallback = wrapCallback(fnCallback, oContext);
var fnFinalCallback = function(v) {
fnWrappedCallback.apply(this, arguments);
return v;
};
var aArgs = [ fnFinalCallback ];
if (mConfig.jq === "always") {
// use same callback for success / error handler
aArgs.push(fnFinalCallback);
}
if (!oReturnPromise) {
oReturnPromise = mOriginalMethods[mConfig.es6].apply(oPromise, aArgs);
} else {
oReturnPromise = oReturnPromise[mConfig.es6].apply(oReturnPromise, aArgs);
}
});
return makePromiseJqCompatible(oReturnPromise, oContext);
};
});
oPromise.pipe = function(fnDoneCallback, fnFailCallback) {
printJqPromiseDeprecationWarning("pipe");
return oPromise.then(fnDoneCallback, fnFailCallback);
};
oPromise.state = function() {
printJqPromiseDeprecationWarning("state");
if (bResolved) {
return "resolved";
} else if (bRejected) {
return "rejected";
} else {
return "pending";
}
};
return oPromise;
}
return makePromiseJqCompatible(oOriginalPromise);
}
/**
* Constructor for a new Export.
*
* @param {string} [sId] id for the new control, generated automatically if no id is given
* @param {object} [mSettings] initial settings for the new control
*
* @class
* Export provides the possibility to generate a list of data in a specific format / type, e.g. CSV to use it in other programs / applications.
* @extends sap.ui.core.Control
*
* @author SAP SE
* @version 1.87.1
* @since 1.22.0
*
* @public
* @deprecated Since version 1.73
* @alias sap.ui.core.util.Export
*/
var Export = Control.extend('sap.ui.core.util.Export', {
metadata: {
// ---- object ----
publicMethods: [
// methods
"generate", "saveFile"
],
// ---- control specific ----
library: "sap.ui.core",
aggregations: {
/**
* Type that generates the content.
*/
exportType: {
type: 'sap.ui.core.util.ExportType',
multiple: false
},
/**
* Columns for the Export.
*/
columns: {
type: 'sap.ui.core.util.ExportColumn',
multiple: true,
bindable : 'bindable'
},
/**
* Rows of the Export.
*/
rows: {
type: 'sap.ui.core.util.ExportRow',
multiple: true,
bindable: 'bindable'
},
/**
* Template row used for the export
*/
_template: {
type: 'sap.ui.core.util.ExportRow',
multiple: false,
visibility: 'hidden'
}
}
},
renderer: null // this control class has no renderer, it is a non-visual control
});
// The aggregation is only to get the data / contexts. no actual rows will be created so no template/factory is needed here
Export.getMetadata().getAggregation("rows")._doesNotRequireFactory = true;
/**
* @private
*/
Export.prototype.init = function() {
this._oPromise = null;
this._fnResolvePromise = null;
this._oRowBindingArgs = null;
};
/**
* @private
*/
Export.prototype.exit = function() {
delete this._oPromise;
delete this._fnResolvePromise;
delete this._oRowBindingArgs;
};
/**
* Creates the row template using the defined columns
*
* @return {sap.ui.core.util.ExportRow} row template
* @private
*/
Export.prototype._createRowTemplate = function() {
var oTemplate = new ExportRow(this.getId() + "-row"),
aCols = this.getColumns();
for (var i = 0, l = aCols.length; i < l; i++) {
var oColTemplate = aCols[i].getTemplate();
if (oColTemplate) {
oTemplate.addCell(oColTemplate.clone("col" + i));
}
}
return oTemplate;
};
Export.prototype.bindAggregation = function(sName, oBindingInfo) {
if (sName === 'rows') {
// skip binding the aggregation for now.
// will be bound when generating and unbound afterwards
this._oRowBindingArgs = arguments;
return this;
}
return Control.prototype.bindAggregation.apply(this, arguments);
};
/**
* Called when the row aggregation gets updated
*
* @private
*/
Export.prototype.updateRows = function(sReason) {
if (sReason === 'change' && this._fnResolvePromise) {
// generate the file
var sContent = this.getExportType()._generate(this);
// template and rows aren't needed anymore, cleans up bindings, etc.
this.destroyAggregation('_template');
this.unbindAggregation('rows');
// resolve promise to notify listeners
this._fnResolvePromise(sContent);
// clear promise related objects
this._oPromise = null;
this._fnResolvePromise = null;
}
};
/**
* Generates the file content and returns a Promise
* with the instance as context (this).<br>
* The promise will be resolved with the generated content
* as a string.
*
* <p><b>Please note: The return value was changed from jQuery Promises to standard ES6 Promises.
* jQuery specific Promise methods ('done', 'fail', 'always', 'pipe' and 'state') are still available but should not be used.
* Please use only the standard methods 'then' and 'catch'!</b></p>
*
* @return {Promise} Promise object
*
* @public
*/
Export.prototype.generate = function() {
var that = this;
if (!this._oPromise) {
this._oPromise = createJqCompatiblePromise(function(resolve, reject) {
that._fnResolvePromise = resolve;
if (!that.hasModel()) {
reject("Generate is not possible beause no model was set.");
} else {
// setup row-template
var oTemplate = that._createRowTemplate();
that.setAggregation('_template', oTemplate, true);
// bind row aggregation (this.bindAggregation would do nothing)
Control.prototype.bindAggregation.apply(that, that._oRowBindingArgs);
// triggers data loading for OData.
// TODO: find a cleaner solution (when $count is not supported)
if (that.getBinding("rows")) {
that.getBinding("rows").getContexts(0, that.getBinding("rows").getLength());
}
}
}, this);
}
return this._oPromise;
};
/**
* Generates the file content, triggers a download / save action and
* returns a Promise with the instance as context (this).<br>
* The promise will be resolved with the generated content
* as a string.
* <p><b>For information about browser support, see <code>sap.ui.core.util.File.save</code></b></p>
*
* <p><b>Please note: The return value was changed from jQuery Promises to standard ES6 Promises.
* jQuery specific Promise methods ('done', 'fail', 'always', 'pipe' and 'state') are still available but should not be used.
* Please use only the standard methods 'then' and 'catch'!</b></p>
*
* @param {string} [sFileName="data"] The file name
* @return {Promise} Promise object
*
* @public
*/
Export.prototype.saveFile = function(sFileName) {
return this.generate().then(function(sContent) {
var oExportType = this.getExportType();
// Trigger the save action
File.save(sContent, sFileName || "data", oExportType.getFileExtension(), oExportType.getMimeType(), oExportType.getCharset(), oExportType.getByteOrderMark());
});
};
return Export;
});