fileactions.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. /*
  2. * Copyright (c) 2014
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. (function() {
  11. var TEMPLATE_FILE_ACTION_TRIGGER =
  12. '<a class="action action-{{nameLowerCase}}" href="#" data-action="{{name}}">' +
  13. '{{#if icon}}<img class="svg" alt="{{altText}}" src="{{icon}}" />{{/if}}' +
  14. '{{#if displayName}}<span> {{displayName}}</span>{{/if}}' +
  15. '</a>';
  16. /**
  17. * Construct a new FileActions instance
  18. * @constructs FileActions
  19. * @memberof OCA.Files
  20. */
  21. var FileActions = function() {
  22. this.initialize();
  23. };
  24. FileActions.TYPE_DROPDOWN = 0;
  25. FileActions.TYPE_INLINE = 1;
  26. FileActions.prototype = {
  27. /** @lends FileActions.prototype */
  28. actions: {},
  29. defaults: {},
  30. icons: {},
  31. /**
  32. * @deprecated
  33. */
  34. currentFile: null,
  35. /**
  36. * Dummy jquery element, for events
  37. */
  38. $el: null,
  39. /**
  40. * List of handlers to be notified whenever a register() or
  41. * setDefault() was called.
  42. *
  43. * @member {Function[]}
  44. */
  45. _updateListeners: {},
  46. _fileActionTriggerTemplate: null,
  47. /**
  48. * @private
  49. */
  50. initialize: function() {
  51. this.clear();
  52. // abusing jquery for events until we get a real event lib
  53. this.$el = $('<div class="dummy-fileactions hidden"></div>');
  54. $('body').append(this.$el);
  55. this._showMenuClosure = _.bind(this._showMenu, this);
  56. },
  57. /**
  58. * Adds an event handler
  59. *
  60. * @param {String} eventName event name
  61. * @param {Function} callback
  62. */
  63. on: function(eventName, callback) {
  64. this.$el.on(eventName, callback);
  65. },
  66. /**
  67. * Removes an event handler
  68. *
  69. * @param {String} eventName event name
  70. * @param Function callback
  71. */
  72. off: function(eventName, callback) {
  73. this.$el.off(eventName, callback);
  74. },
  75. /**
  76. * Notifies the event handlers
  77. *
  78. * @param {String} eventName event name
  79. * @param {Object} data data
  80. */
  81. _notifyUpdateListeners: function(eventName, data) {
  82. this.$el.trigger(new $.Event(eventName, data));
  83. },
  84. /**
  85. * Merges the actions from the given fileActions into
  86. * this instance.
  87. *
  88. * @param {OCA.Files.FileActions} fileActions instance of OCA.Files.FileActions
  89. */
  90. merge: function(fileActions) {
  91. var self = this;
  92. // merge first level to avoid unintended overwriting
  93. _.each(fileActions.actions, function(sourceMimeData, mime) {
  94. var targetMimeData = self.actions[mime];
  95. if (!targetMimeData) {
  96. targetMimeData = {};
  97. }
  98. self.actions[mime] = _.extend(targetMimeData, sourceMimeData);
  99. });
  100. this.defaults = _.extend(this.defaults, fileActions.defaults);
  101. this.icons = _.extend(this.icons, fileActions.icons);
  102. },
  103. /**
  104. * @deprecated use #registerAction() instead
  105. */
  106. register: function(mime, name, permissions, icon, action, displayName) {
  107. return this.registerAction({
  108. name: name,
  109. mime: mime,
  110. permissions: permissions,
  111. icon: icon,
  112. actionHandler: action,
  113. displayName: displayName || name
  114. });
  115. },
  116. /**
  117. * Register action
  118. *
  119. * @param {OCA.Files.FileAction} action object
  120. */
  121. registerAction: function (action) {
  122. var mime = action.mime;
  123. var name = action.name;
  124. var actionSpec = {
  125. action: action.actionHandler,
  126. name: name,
  127. displayName: action.displayName,
  128. mime: mime,
  129. order: action.order || 0,
  130. icon: action.icon,
  131. permissions: action.permissions,
  132. type: action.type || FileActions.TYPE_DROPDOWN,
  133. altText: action.altText || ''
  134. };
  135. if (_.isUndefined(action.displayName)) {
  136. actionSpec.displayName = t('files', name);
  137. }
  138. if (_.isFunction(action.render)) {
  139. actionSpec.render = action.render;
  140. }
  141. if (!this.actions[mime]) {
  142. this.actions[mime] = {};
  143. }
  144. this.actions[mime][name] = actionSpec;
  145. this.icons[name] = action.icon;
  146. this._notifyUpdateListeners('registerAction', {action: action});
  147. },
  148. /**
  149. * Clears all registered file actions.
  150. */
  151. clear: function() {
  152. this.actions = {};
  153. this.defaults = {};
  154. this.icons = {};
  155. this.currentFile = null;
  156. this._updateListeners = [];
  157. },
  158. /**
  159. * Sets the default action for a given mime type.
  160. *
  161. * @param {String} mime mime type
  162. * @param {String} name action name
  163. */
  164. setDefault: function (mime, name) {
  165. this.defaults[mime] = name;
  166. this._notifyUpdateListeners('setDefault', {defaultAction: {mime: mime, name: name}});
  167. },
  168. /**
  169. * Returns a map of file actions handlers matching the given conditions
  170. *
  171. * @param {string} mime mime type
  172. * @param {string} type "dir" or "file"
  173. * @param {int} permissions permissions
  174. *
  175. * @return {Object.<string,OCA.Files.FileActions~actionHandler>} map of action name to action spec
  176. */
  177. get: function (mime, type, permissions) {
  178. var actions = this.getActions(mime, type, permissions);
  179. var filteredActions = {};
  180. $.each(actions, function (name, action) {
  181. filteredActions[name] = action.action;
  182. });
  183. return filteredActions;
  184. },
  185. /**
  186. * Returns an array of file actions matching the given conditions
  187. *
  188. * @param {string} mime mime type
  189. * @param {string} type "dir" or "file"
  190. * @param {int} permissions permissions
  191. *
  192. * @return {Array.<OCA.Files.FileAction>} array of action specs
  193. */
  194. getActions: function (mime, type, permissions) {
  195. var actions = {};
  196. if (this.actions.all) {
  197. actions = $.extend(actions, this.actions.all);
  198. }
  199. if (type) {//type is 'dir' or 'file'
  200. if (this.actions[type]) {
  201. actions = $.extend(actions, this.actions[type]);
  202. }
  203. }
  204. if (mime) {
  205. var mimePart = mime.substr(0, mime.indexOf('/'));
  206. if (this.actions[mimePart]) {
  207. actions = $.extend(actions, this.actions[mimePart]);
  208. }
  209. if (this.actions[mime]) {
  210. actions = $.extend(actions, this.actions[mime]);
  211. }
  212. }
  213. var filteredActions = {};
  214. $.each(actions, function (name, action) {
  215. if (action.permissions & permissions) {
  216. filteredActions[name] = action;
  217. }
  218. });
  219. return filteredActions;
  220. },
  221. /**
  222. * Returns the default file action handler for the given conditions
  223. *
  224. * @param {string} mime mime type
  225. * @param {string} type "dir" or "file"
  226. * @param {int} permissions permissions
  227. *
  228. * @return {OCA.Files.FileActions~actionHandler} action handler
  229. *
  230. * @deprecated use getDefaultFileAction instead
  231. */
  232. getDefault: function (mime, type, permissions) {
  233. var defaultActionSpec = this.getDefaultFileAction(mime, type, permissions);
  234. if (defaultActionSpec) {
  235. return defaultActionSpec.action;
  236. }
  237. return undefined;
  238. },
  239. /**
  240. * Returns the default file action handler for the given conditions
  241. *
  242. * @param {string} mime mime type
  243. * @param {string} type "dir" or "file"
  244. * @param {int} permissions permissions
  245. *
  246. * @return {OCA.Files.FileActions~actionHandler} action handler
  247. * @since 8.2
  248. */
  249. getDefaultFileAction: function(mime, type, permissions) {
  250. var mimePart;
  251. if (mime) {
  252. mimePart = mime.substr(0, mime.indexOf('/'));
  253. }
  254. var name = false;
  255. if (mime && this.defaults[mime]) {
  256. name = this.defaults[mime];
  257. } else if (mime && this.defaults[mimePart]) {
  258. name = this.defaults[mimePart];
  259. } else if (type && this.defaults[type]) {
  260. name = this.defaults[type];
  261. } else {
  262. name = this.defaults.all;
  263. }
  264. var actions = this.getActions(mime, type, permissions);
  265. return actions[name];
  266. },
  267. /**
  268. * Default function to render actions
  269. *
  270. * @param {OCA.Files.FileAction} actionSpec file action spec
  271. * @param {boolean} isDefault true if the action is a default one,
  272. * false otherwise
  273. * @param {OCA.Files.FileActionContext} context action context
  274. */
  275. _defaultRenderAction: function(actionSpec, isDefault, context) {
  276. if (!isDefault) {
  277. var params = {
  278. name: actionSpec.name,
  279. nameLowerCase: actionSpec.name.toLowerCase(),
  280. displayName: actionSpec.displayName,
  281. icon: actionSpec.icon,
  282. altText: actionSpec.altText,
  283. };
  284. if (_.isFunction(actionSpec.icon)) {
  285. params.icon = actionSpec.icon(context.$file.attr('data-file'));
  286. }
  287. var $actionLink = this._makeActionLink(params, context);
  288. context.$file.find('a.name>span.fileactions').append($actionLink);
  289. $actionLink.addClass('permanent');
  290. return $actionLink;
  291. }
  292. },
  293. /**
  294. * Renders the action link element
  295. *
  296. * @param {Object} params action params
  297. */
  298. _makeActionLink: function(params) {
  299. if (!this._fileActionTriggerTemplate) {
  300. this._fileActionTriggerTemplate = Handlebars.compile(TEMPLATE_FILE_ACTION_TRIGGER);
  301. }
  302. return $(this._fileActionTriggerTemplate(params));
  303. },
  304. /**
  305. * Displays the file actions dropdown menu
  306. *
  307. * @param {string} fileName file name
  308. * @param {OCA.Files.FileActionContext} context rendering context
  309. */
  310. _showMenu: function(fileName, context) {
  311. var menu;
  312. var $trigger = context.$file.closest('tr').find('.fileactions .action-menu');
  313. $trigger.addClass('open');
  314. menu = new OCA.Files.FileActionsMenu();
  315. context.$file.find('td.filename').append(menu.$el);
  316. menu.$el.on('afterHide', function() {
  317. context.$file.removeClass('mouseOver');
  318. $trigger.removeClass('open');
  319. menu.remove();
  320. });
  321. context.$file.addClass('mouseOver');
  322. menu.show(context);
  323. },
  324. /**
  325. * Renders the menu trigger on the given file list row
  326. *
  327. * @param {Object} $tr file list row element
  328. * @param {OCA.Files.FileActionContext} context rendering context
  329. */
  330. _renderMenuTrigger: function($tr, context) {
  331. // remove previous
  332. $tr.find('.action-menu').remove();
  333. var $el = this._renderInlineAction({
  334. name: 'menu',
  335. displayName: '',
  336. icon: OC.imagePath('core', 'actions/more'),
  337. altText: t('files', 'Actions'),
  338. action: this._showMenuClosure
  339. }, false, context);
  340. $el.addClass('permanent');
  341. },
  342. /**
  343. * Renders the action element by calling actionSpec.render() and
  344. * registers the click event to process the action.
  345. *
  346. * @param {OCA.Files.FileAction} actionSpec file action to render
  347. * @param {boolean} isDefault true if the action is a default action,
  348. * false otherwise
  349. * @param {OCA.Files.FileActionContext} context rendering context
  350. */
  351. _renderInlineAction: function(actionSpec, isDefault, context) {
  352. var renderFunc = actionSpec.render || _.bind(this._defaultRenderAction, this);
  353. var $actionEl = renderFunc(actionSpec, isDefault, context);
  354. if (!$actionEl || !$actionEl.length) {
  355. return;
  356. }
  357. $actionEl.on(
  358. 'click', {
  359. a: null
  360. },
  361. function(event) {
  362. event.stopPropagation();
  363. event.preventDefault();
  364. if ($actionEl.hasClass('open')) {
  365. return;
  366. }
  367. var $file = $(event.target).closest('tr');
  368. if ($file.hasClass('busy')) {
  369. return;
  370. }
  371. var currentFile = $file.find('td.filename');
  372. var fileName = $file.attr('data-file');
  373. context.fileActions.currentFile = currentFile;
  374. // also set on global object for legacy apps
  375. window.FileActions.currentFile = currentFile;
  376. var callContext = _.extend({}, context);
  377. if (!context.dir && context.fileList) {
  378. callContext.dir = $file.attr('data-path') || context.fileList.getCurrentDirectory();
  379. }
  380. if (!context.fileInfoModel && context.fileList) {
  381. callContext.fileInfoModel = context.fileList.getModelForFile(fileName);
  382. if (!callContext.fileInfoModel) {
  383. console.warn('No file info model found for file "' + fileName + '"');
  384. }
  385. }
  386. actionSpec.action(
  387. fileName,
  388. callContext
  389. );
  390. }
  391. );
  392. $actionEl.tooltip({placement:'top'});
  393. return $actionEl;
  394. },
  395. /**
  396. * Trigger the given action on the given file.
  397. *
  398. * @param {string} actionName action name
  399. * @param {OCA.Files.FileInfoModel} fileInfoModel file info model
  400. * @param {OCA.Files.FileList} [fileList] file list, for compatibility with older action handlers [DEPRECATED]
  401. *
  402. * @return {boolean} true if the action handler was called, false otherwise
  403. *
  404. * @since 8.2
  405. */
  406. triggerAction: function(actionName, fileInfoModel, fileList) {
  407. var actionFunc;
  408. var actions = this.get(
  409. fileInfoModel.get('mimetype'),
  410. fileInfoModel.isDirectory() ? 'dir' : 'file',
  411. fileInfoModel.get('permissions')
  412. );
  413. if (actionName) {
  414. actionFunc = actions[actionName];
  415. } else {
  416. actionFunc = this.getDefault(
  417. fileInfoModel.get('mimetype'),
  418. fileInfoModel.isDirectory() ? 'dir' : 'file',
  419. fileInfoModel.get('permissions')
  420. );
  421. }
  422. if (!actionFunc) {
  423. actionFunc = actions['Download'];
  424. }
  425. if (!actionFunc) {
  426. return false;
  427. }
  428. var context = {
  429. fileActions: this,
  430. fileInfoModel: fileInfoModel,
  431. dir: fileInfoModel.get('path')
  432. };
  433. var fileName = fileInfoModel.get('name');
  434. this.currentFile = fileName;
  435. // also set on global object for legacy apps
  436. window.FileActions.currentFile = fileName;
  437. if (fileList) {
  438. // compatibility with action handlers that expect these
  439. context.fileList = fileList;
  440. context.$file = fileList.findFileEl(fileName);
  441. }
  442. actionFunc(fileName, context);
  443. },
  444. /**
  445. * Display file actions for the given element
  446. * @param parent "td" element of the file for which to display actions
  447. * @param triggerEvent if true, triggers the fileActionsReady on the file
  448. * list afterwards (false by default)
  449. * @param fileList OCA.Files.FileList instance on which the action is
  450. * done, defaults to OCA.Files.App.fileList
  451. */
  452. display: function (parent, triggerEvent, fileList) {
  453. if (!fileList) {
  454. console.warn('FileActions.display() MUST be called with a OCA.Files.FileList instance');
  455. return;
  456. }
  457. this.currentFile = parent;
  458. var self = this;
  459. var $tr = parent.closest('tr');
  460. var actions = this.getActions(
  461. this.getCurrentMimeType(),
  462. this.getCurrentType(),
  463. this.getCurrentPermissions()
  464. );
  465. var nameLinks;
  466. if ($tr.data('renaming')) {
  467. return;
  468. }
  469. // recreate fileactions container
  470. nameLinks = parent.children('a.name');
  471. nameLinks.find('.fileactions, .nametext .action').remove();
  472. nameLinks.append('<span class="fileactions" />');
  473. var defaultAction = this.getDefaultFileAction(
  474. this.getCurrentMimeType(),
  475. this.getCurrentType(),
  476. this.getCurrentPermissions()
  477. );
  478. var context = {
  479. $file: $tr,
  480. fileActions: this,
  481. fileList: fileList
  482. };
  483. $.each(actions, function (name, actionSpec) {
  484. if (actionSpec.type === FileActions.TYPE_INLINE) {
  485. self._renderInlineAction(
  486. actionSpec,
  487. defaultAction && actionSpec.name === defaultAction.name,
  488. context
  489. );
  490. }
  491. });
  492. this._renderMenuTrigger($tr, context);
  493. if (triggerEvent){
  494. fileList.$fileList.trigger(jQuery.Event("fileActionsReady", {fileList: fileList, $files: $tr}));
  495. }
  496. },
  497. getCurrentFile: function () {
  498. return this.currentFile.parent().attr('data-file');
  499. },
  500. getCurrentMimeType: function () {
  501. return this.currentFile.parent().attr('data-mime');
  502. },
  503. getCurrentType: function () {
  504. return this.currentFile.parent().attr('data-type');
  505. },
  506. getCurrentPermissions: function () {
  507. return this.currentFile.parent().data('permissions');
  508. },
  509. /**
  510. * Register the actions that are used by default for the files app.
  511. */
  512. registerDefaultActions: function() {
  513. this.registerAction({
  514. name: 'Download',
  515. displayName: t('files', 'Download'),
  516. order: -20,
  517. mime: 'all',
  518. permissions: OC.PERMISSION_READ,
  519. icon: function () {
  520. return OC.imagePath('core', 'actions/download');
  521. },
  522. actionHandler: function (filename, context) {
  523. var dir = context.dir || context.fileList.getCurrentDirectory();
  524. var isDir = context.$file.attr('data-type') === 'dir';
  525. var url = context.fileList.getDownloadUrl(filename, dir, isDir);
  526. var downloadFileaction = $(context.$file).find('.fileactions .action-download');
  527. // don't allow a second click on the download action
  528. if(downloadFileaction.hasClass('disabled')) {
  529. return;
  530. }
  531. if (url) {
  532. var disableLoadingState = function() {
  533. context.fileList.showFileBusyState(filename, false);
  534. };
  535. context.fileList.showFileBusyState(filename, true);
  536. OCA.Files.Files.handleDownload(url, disableLoadingState);
  537. }
  538. }
  539. });
  540. this.registerAction({
  541. name: 'Rename',
  542. displayName: t('files', 'Rename'),
  543. mime: 'all',
  544. order: -30,
  545. permissions: OC.PERMISSION_UPDATE,
  546. icon: function() {
  547. return OC.imagePath('core', 'actions/rename');
  548. },
  549. actionHandler: function (filename, context) {
  550. context.fileList.rename(filename);
  551. }
  552. });
  553. this.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
  554. var dir = context.$file.attr('data-path') || context.fileList.getCurrentDirectory();
  555. context.fileList.changeDirectory(OC.joinPaths(dir, filename));
  556. });
  557. this.registerAction({
  558. name: 'Delete',
  559. displayName: function(context) {
  560. var mountType = context.$file.attr('data-mounttype');
  561. var deleteTitle = t('files', 'Delete');
  562. if (mountType === 'external-root') {
  563. deleteTitle = t('files', 'Disconnect storage');
  564. } else if (mountType === 'shared-root') {
  565. deleteTitle = t('files', 'Unshare');
  566. }
  567. return deleteTitle;
  568. },
  569. mime: 'all',
  570. order: 1000,
  571. // permission is READ because we show a hint instead if there is no permission
  572. permissions: OC.PERMISSION_DELETE,
  573. icon: function() {
  574. return OC.imagePath('core', 'actions/delete');
  575. },
  576. actionHandler: function(fileName, context) {
  577. // if there is no permission to delete do nothing
  578. if((context.$file.data('permissions') & OC.PERMISSION_DELETE) === 0) {
  579. return;
  580. }
  581. context.fileList.do_delete(fileName, context.dir);
  582. $('.tipsy').remove();
  583. }
  584. });
  585. this.setDefault('dir', 'Open');
  586. }
  587. };
  588. OCA.Files.FileActions = FileActions;
  589. /**
  590. * Replaces the download icon with a loading spinner and vice versa
  591. * - also adds the class disabled to the passed in element
  592. *
  593. * @param downloadButtonElement download fileaction
  594. * @param {boolean} showIt whether to show the spinner(true) or to hide it(false)
  595. */
  596. OCA.Files.FileActions.updateFileActionSpinner = function(downloadButtonElement, showIt) {
  597. var icon = downloadButtonElement.find('img'),
  598. sourceImage = icon.attr('src');
  599. if(showIt) {
  600. downloadButtonElement.addClass('disabled');
  601. icon.attr('src', sourceImage.replace('actions/download.svg', 'loading-small.gif'));
  602. } else {
  603. downloadButtonElement.removeClass('disabled');
  604. icon.attr('src', sourceImage.replace('loading-small.gif', 'actions/download.svg'));
  605. }
  606. };
  607. /**
  608. * File action attributes.
  609. *
  610. * @todo make this a real class in the future
  611. * @typedef {Object} OCA.Files.FileAction
  612. *
  613. * @property {String} name identifier of the action
  614. * @property {(String|OCA.Files.FileActions~displayNameFunction)} displayName
  615. * display name string for the action, or function that returns the display name.
  616. * Defaults to the name given in name property
  617. * @property {String} mime mime type
  618. * @property {int} permissions permissions
  619. * @property {(Function|String)} icon icon path to the icon or function
  620. * that returns it
  621. * @property {OCA.Files.FileActions~renderActionFunction} [render] optional rendering function
  622. * @property {OCA.Files.FileActions~actionHandler} actionHandler action handler function
  623. */
  624. /**
  625. * File action context attributes.
  626. *
  627. * @typedef {Object} OCA.Files.FileActionContext
  628. *
  629. * @property {Object} $file jQuery file row element
  630. * @property {OCA.Files.FileActions} fileActions file actions object
  631. * @property {OCA.Files.FileList} fileList file list object
  632. */
  633. /**
  634. * Render function for actions.
  635. * The function must render a link element somewhere in the DOM
  636. * and return it. The function should NOT register the event handler
  637. * as this will be done after the link was returned.
  638. *
  639. * @callback OCA.Files.FileActions~renderActionFunction
  640. * @param {OCA.Files.FileAction} actionSpec action definition
  641. * @param {Object} $row row container
  642. * @param {boolean} isDefault true if the action is the default one,
  643. * false otherwise
  644. * @return {Object} jQuery link object
  645. */
  646. /**
  647. * Display name function for actions.
  648. * The function returns the display name of the action using
  649. * the given context information..
  650. *
  651. * @callback OCA.Files.FileActions~displayNameFunction
  652. * @param {OCA.Files.FileActionContext} context action context
  653. * @return {String} display name
  654. */
  655. /**
  656. * Action handler function for file actions
  657. *
  658. * @callback OCA.Files.FileActions~actionHandler
  659. * @param {String} fileName name of the file on which the action must be performed
  660. * @param context context
  661. * @param {String} context.dir directory of the file
  662. * @param {OCA.Files.FileInfoModel} fileInfoModel file info model
  663. * @param {Object} [context.$file] jQuery element of the file [DEPRECATED]
  664. * @param {OCA.Files.FileList} [context.fileList] the FileList instance on which the action occurred [DEPRECATED]
  665. * @param {OCA.Files.FileActions} context.fileActions the FileActions instance on which the action occurred
  666. */
  667. // global file actions to be used by all lists
  668. OCA.Files.fileActions = new OCA.Files.FileActions();
  669. OCA.Files.legacyFileActions = new OCA.Files.FileActions();
  670. // for backward compatibility
  671. //
  672. // legacy apps are expecting a stateful global FileActions object to register
  673. // their actions on. Since legacy apps are very likely to break with other
  674. // FileList views than the main one ("All files"), actions registered
  675. // through window.FileActions will be limited to the main file list.
  676. // @deprecated use OCA.Files.FileActions instead
  677. window.FileActions = OCA.Files.legacyFileActions;
  678. window.FileActions.register = function (mime, name, permissions, icon, action, displayName) {
  679. console.warn('FileActions.register() is deprecated, please use OCA.Files.fileActions.register() instead', arguments);
  680. OCA.Files.FileActions.prototype.register.call(
  681. window.FileActions, mime, name, permissions, icon, action, displayName
  682. );
  683. };
  684. window.FileActions.display = function (parent, triggerEvent, fileList) {
  685. fileList = fileList || OCA.Files.App.fileList;
  686. console.warn('FileActions.display() is deprecated, please use OCA.Files.fileActions.register() which automatically redisplays actions', mime, name);
  687. OCA.Files.FileActions.prototype.display.call(window.FileActions, parent, triggerEvent, fileList);
  688. };
  689. })();