]> source.dussan.org Git - nextcloud-server.git/commitdiff
Simple Plugin system for Javascript
authorVincent Petry <pvince81@owncloud.com>
Mon, 1 Dec 2014 15:17:28 +0000 (16:17 +0100)
committerVincent Petry <pvince81@owncloud.com>
Mon, 1 Dec 2014 15:20:44 +0000 (16:20 +0100)
apps/files/js/filelist.js
apps/files_sharing/js/app.js
apps/files_sharing/js/public.js
apps/files_sharing/js/share.js
apps/files_sharing/js/sharedfilelist.js
apps/files_sharing/tests/js/shareSpec.js
apps/files_sharing/tests/js/sharedfilelistSpec.js
apps/files_trashbin/js/filelist.js
core/js/js.js
core/js/tests/specHelper.js
core/js/tests/specs/coreSpec.js

index bec0155e90e2df227e619e020c4a79f21814f887..cd20dc71c29cf5fee26b3d15c3ff533d1d7bfdce 100644 (file)
                        }
 
                        this.$el = $el;
+                       if (options.id) {
+                               this.id = options.id;
+                       }
                        this.$container = options.scrollContainer || $(window);
                        this.$table = $el.find('table:first');
                        this.$fileList = $el.find('#fileList');
                                        self.scrollTo(options.scrollTo);
                                });
                        }
+
+                       OC.Plugins.attach('OCA.Files.FileList', this);
                },
 
                /**
                        // TODO: also unregister other event handlers
                        this.fileActions.off('registerAction', this._onFileActionsUpdated);
                        this.fileActions.off('setDefault', this._onFileActionsUpdated);
+                       OC.Plugins.detach('OCA.Files.FileList', this);
                },
 
                /**
index 1314304c567b6e54f44685abe604a74b30728c81..ff6997ab12fa221301a35db3f4922d39a66acee7 100644 (file)
@@ -30,6 +30,7 @@ OCA.Sharing.App = {
                this._inFileList = new OCA.Sharing.FileList(
                        $el,
                        {
+                               id: 'shares.self',
                                scrollContainer: $('#app-content'),
                                sharedWithUser: true,
                                fileActions: this._createFileActions()
@@ -49,6 +50,7 @@ OCA.Sharing.App = {
                this._outFileList = new OCA.Sharing.FileList(
                        $el,
                        {
+                               id: 'shares.others',
                                scrollContainer: $('#app-content'),
                                sharedWithUser: false,
                                fileActions: this._createFileActions()
@@ -68,6 +70,7 @@ OCA.Sharing.App = {
                this._linkFileList = new OCA.Sharing.FileList(
                        $el,
                        {
+                               id: 'shares.link',
                                scrollContainer: $('#app-content'),
                                linksOnly: true,
                                fileActions: this._createFileActions()
index 0627ed6ab54dbcaabf45e7148bd654d9e7fed476..2ddcd84d4c120cc4b72268153265ee41bc39167f 100644 (file)
@@ -53,6 +53,7 @@ OCA.Sharing.PublicApp = {
                        this.fileList = new OCA.Files.FileList(
                                $el,
                                {
+                                       id: 'files.public',
                                        scrollContainer: $(window),
                                        dragOptions: dragOptions,
                                        folderDropOptions: folderDropOptions,
@@ -61,6 +62,9 @@ OCA.Sharing.PublicApp = {
                        );
                        this.files = OCA.Files.Files;
                        this.files.initialize();
+                       // TODO: move to PublicFileList.initialize() once
+                       // the code was split into a separate class
+                       OC.Plugins.attach('OCA.Sharing.PublicFileList', this.fileList);
                }
 
                var mimetype = $('#mimetype').val();
index 8474c66d4b83fe54769a4553f0bc79d181a26adf..bbd107e070ee99b79d188c07e8c96d23870f7760 100644 (file)
         */
        OCA.Sharing.Util = {
                /**
-                * Initialize the sharing app overrides of the default
-                * file list.
+                * Initialize the sharing plugin.
                 *
                 * Registers the "Share" file action and adds additional
                 * DOM attributes for the sharing file info.
                 *
-                * @param {OCA.Files.FileActions} fileActions file actions to extend
+                * @param {OCA.Files.FileList} fileList file list to be extended
                 */
-               initialize: function(fileActions) {
-                       if (OCA.Files.FileList) {
-                               var oldCreateRow = OCA.Files.FileList.prototype._createRow;
-                               OCA.Files.FileList.prototype._createRow = function(fileData) {
-                                       var tr = oldCreateRow.apply(this, arguments);
-                                       var sharePermissions = fileData.permissions;
-                                       if (fileData.mountType && fileData.mountType === "external-root"){
-                                               // for external storages we cant use the permissions of the mountpoint
-                                               // instead we show all permissions and only use the share permissions from the mountpoint to handle resharing
-                                               sharePermissions = sharePermissions | (OC.PERMISSION_ALL & ~OC.PERMISSION_SHARE);
-                                       }
-                                       if (fileData.type === 'file') {
-                                               // files can't be shared with delete permissions
-                                               sharePermissions = sharePermissions & ~OC.PERMISSION_DELETE;
-                                       }
-                                       tr.attr('data-share-permissions', sharePermissions);
-                                       if (fileData.shareOwner) {
-                                               tr.attr('data-share-owner', fileData.shareOwner);
-                                               // user should always be able to rename a mount point
-                                               if (fileData.isShareMountPoint) {
-                                                       tr.attr('data-permissions', fileData.permissions | OC.PERMISSION_UPDATE);
-                                               }
-                                       }
-                                       if (fileData.recipientsDisplayName) {
-                                               tr.attr('data-share-recipients', fileData.recipientsDisplayName);
-                                       }
-                                       return tr;
-                               };
+               attach: function(fileList) {
+                       if (fileList.id === 'trashbin') {
+                               return;
                        }
+                       var fileActions = fileList.fileActions;
+                       var oldCreateRow = fileList._createRow;
+                       fileList._createRow = function(fileData) {
+                               var tr = oldCreateRow.apply(this, arguments);
+                               var sharePermissions = fileData.permissions;
+                               if (fileData.mountType && fileData.mountType === "external-root"){
+                                       // for external storages we cant use the permissions of the mountpoint
+                                       // instead we show all permissions and only use the share permissions from the mountpoint to handle resharing
+                                       sharePermissions = sharePermissions | (OC.PERMISSION_ALL & ~OC.PERMISSION_SHARE);
+                               }
+                               if (fileData.type === 'file') {
+                                       // files can't be shared with delete permissions
+                                       sharePermissions = sharePermissions & ~OC.PERMISSION_DELETE;
+                               }
+                               tr.attr('data-share-permissions', sharePermissions);
+                               if (fileData.shareOwner) {
+                                       tr.attr('data-share-owner', fileData.shareOwner);
+                                       // user should always be able to rename a mount point
+                                       if (fileData.isShareMountPoint) {
+                                               tr.attr('data-permissions', fileData.permissions | OC.PERMISSION_UPDATE);
+                                       }
+                               }
+                               if (fileData.recipientsDisplayName) {
+                                       tr.attr('data-share-recipients', fileData.recipientsDisplayName);
+                               }
+                               return tr;
+                       };
 
                        // use delegate to catch the case with multiple file lists
-                       $('#content').delegate('#fileList', 'fileActionsReady', function(ev){
+                       fileList.$el.on('fileActionsReady', function(ev){
                                var fileList = ev.fileList;
                                var $files = ev.$files;
 
        };
 })();
 
-$(document).ready(function() {
-       // FIXME: HACK: do not init when running unit tests, need a better way
-       if (!window.TESTING) {
-               if (!_.isUndefined(OC.Share) && !_.isUndefined(OCA.Files)) {
-                       OCA.Sharing.Util.initialize(OCA.Files.fileActions);
-               }
-       }
-});
+OC.Plugins.register('OCA.Files.FileList', OCA.Sharing.Util);
 
index 7a7c24993c0d6f9d130e9ad41e7e1552a090998e..bd26b13b78a7baf9aa8e5bb1ea9da03e0a690898 100644 (file)
@@ -55,6 +55,7 @@
                        if (options && options.linksOnly) {
                                this._linksOnly = true;
                        }
+                       OC.Plugins.attach('OCA.Sharing.FileList', this);
                },
 
                _renderRow: function() {
index 2cf5dc47b6349b5e005180fd9276e53b8f643392..d64d4ea8137d7bdee64e0d1cb413adebea1af74b 100644 (file)
@@ -41,12 +41,12 @@ describe('OCA.Sharing.Util tests', function() {
                $('#content').append($div);
 
                var fileActions = new OCA.Files.FileActions();
-               OCA.Sharing.Util.initialize(fileActions);
                fileList = new OCA.Files.FileList(
                        $div, {
                                fileActions : fileActions
                        }
                );
+               OCA.Sharing.Util.attach(fileList);
 
                testFiles = [{
                        id: 1,
index dc6931af6e8d43c0be2bbf5d3e7236bbc3378664..d85c0ab6dcac2f2e042e7eba8be9ba3fe5275eff 100644 (file)
@@ -50,7 +50,6 @@ describe('OCA.Sharing.FileList tests', function() {
                // the sharing code
                oldFileListPrototype = _.extend({}, OCA.Files.FileList.prototype);
                fileActions = new OCA.Files.FileActions();
-               OCA.Sharing.Util.initialize(fileActions);
        });
        afterEach(function() {
                OCA.Files.FileList.prototype = oldFileListPrototype;
@@ -72,6 +71,7 @@ describe('OCA.Sharing.FileList tests', function() {
                                        sharedWithUser: true
                                }
                        );
+                       OCA.Sharing.Util.attach(fileList);
 
                        fileList.reload();
 
@@ -193,6 +193,7 @@ describe('OCA.Sharing.FileList tests', function() {
                                        sharedWithUser: false
                                }
                        );
+                       OCA.Sharing.Util.attach(fileList);
 
                        fileList.reload();
 
@@ -433,6 +434,7 @@ describe('OCA.Sharing.FileList tests', function() {
                                        linksOnly: true
                                }
                        );
+                       OCA.Sharing.Util.attach(fileList);
 
                        fileList.reload();
 
@@ -580,6 +582,7 @@ describe('OCA.Sharing.FileList tests', function() {
                                        fileActions: fileActions
                                }
                        );
+                       OCA.Sharing.Util.attach(fileList);
                });
 
                it('external storage root folder', function () {
index a3631a2d0fe740d1c87cb75c2887c3af010fccae..04e9da23dc1ed77f489e296569371a6da5edef55 100644 (file)
@@ -64,6 +64,7 @@
                                return parts;
                        };
 
+                       OC.Plugins.attach('OCA.Trashbin.FileList', this);
                        return result;
                },
 
index eb2f10b51f06897e2c247556177921be83f873bf..cc3a548de283a64152c366587b1b266092fe8293 100644 (file)
@@ -498,6 +498,87 @@ var OC={
        }
 };
 
+/**
+ * @namespace OC.Plugins
+ */
+OC.Plugins = {
+       /**
+        * @type Array.<OC.Plugin>
+        */
+       _plugins: {},
+
+       /**
+        * Register plugin
+        *
+        * @param {String} targetName app name / class name to hook into
+        * @param {OC.Plugin} plugin
+        */
+       register: function(targetName, plugin) {
+               var plugins = this._plugins[targetName];
+               if (!plugins) {
+                       plugins = this._plugins[targetName] = [];
+               }
+               plugins.push(plugin);
+       },
+
+       /**
+        * Returns all plugin registered to the given target
+        * name / app name / class name.
+        *
+        * @param {String} targetName app name / class name to hook into
+        * @return {Array.<OC.Plugin>} array of plugins
+        */
+       getPlugins: function(targetName) {
+               return this._plugins[targetName] || [];
+       },
+
+       /**
+        * Call attach() on all plugins registered to the given target name.
+        *
+        * @param {String} targetName app name / class name
+        * @param {Object} object to be extended
+        * @param {Object} [options] options
+        */
+       attach: function(targetName, targetObject, options) {
+               var plugins = this.getPlugins(targetName);
+               for (var i = 0; i < plugins.length; i++) {
+                       if (plugins[i].attach) {
+                               plugins[i].attach(targetObject, options);
+                       }
+               }
+       },
+
+       /**
+        * Call detach() on all plugins registered to the given target name.
+        *
+        * @param {String} targetName app name / class name
+        * @param {Object} object to be extended
+        * @param {Object} [options] options
+        */
+       detach: function(targetName, targetObject, options) {
+               var plugins = this.getPlugins(targetName);
+               for (var i = 0; i < plugins.length; i++) {
+                       if (plugins[i].detach) {
+                               plugins[i].detach(targetObject, options);
+                       }
+               }
+       },
+
+       /**
+        * Plugin
+        *
+        * @todo make this a real class in the future
+        * @typedef {Object} OC.Plugin
+        *
+        * @property {String} name plugin name
+        * @property {Function} attach function that will be called when the
+        * plugin is attached
+        * @property {Function} [detach] function that will be called when the
+        * plugin is detached
+        */
+
+};
+
 /**
  * @namespace OC.search
  */
index 4111b6763d985095824148fe26d04a0af8dcfff2..59c2a99645f2815e1929879d3c9b6a450679b367 100644 (file)
@@ -120,6 +120,9 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
                if (!OC.TestUtil) {
                        OC.TestUtil = TestUtil;
                }
+
+               // reset plugins
+               OC.Plugins._plugins = [];
        });
 
        afterEach(function() {
index 2c5c22905b0c492fd007a5edb779ccea7b454dbe..08395f4d4c23e55555a19154739da8dd04821d55 100644 (file)
@@ -655,5 +655,36 @@ describe('Core base tests', function() {
                        ]);
                });
        });
+       describe('Plugins', function() {
+               var plugin;
+
+               beforeEach(function() {
+                       plugin = {
+                               name: 'Some name',
+                               attach: function(obj) {
+                                       obj.attached = true;
+                               },
+
+                               detach: function(obj) {
+                                       obj.attached = false;
+                               }
+                       };
+                       OC.Plugins.register('OC.Test.SomeName', plugin);
+               });
+               it('attach plugin to object', function() {
+                       var obj = {something: true};
+                       OC.Plugins.attach('OC.Test.SomeName', obj);
+                       expect(obj.attached).toEqual(true);
+                       OC.Plugins.detach('OC.Test.SomeName', obj);
+                       expect(obj.attached).toEqual(false);
+               });
+               it('only call handler for target name', function() {
+                       var obj = {something: true};
+                       OC.Plugins.attach('OC.Test.SomeOtherName', obj);
+                       expect(obj.attached).not.toBeDefined();
+                       OC.Plugins.detach('OC.Test.SomeOtherName', obj);
+                       expect(obj.attached).not.toBeDefined();
+               });
+       });
 });