aboutsummaryrefslogtreecommitdiffstats
path: root/core/src
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2019-02-01 08:20:03 +0100
committerGitHub <noreply@github.com>2019-02-01 08:20:03 +0100
commitdc3b44c02dc316215f10eb1e92d1b09328465470 (patch)
treea44609185e85074414a60dfe62a0936d75adb600 /core/src
parent2124ff65b673698dcb305b835b3ba4bbd438c074 (diff)
parent3d1a3b66442698601597d4f777d47d5f0ea744c2 (diff)
downloadnextcloud-server-dc3b44c02dc316215f10eb1e92d1b09328465470.tar.gz
nextcloud-server-dc3b44c02dc316215f10eb1e92d1b09328465470.zip
Merge pull request #13956 from nextcloud/refactor/oc-plugins-msg-notifications-II
Move OC.Plugins, OC.msg and OC.Notification to the server bundle
Diffstat (limited to 'core/src')
-rw-r--r--core/src/OC/index.js6
-rw-r--r--core/src/OC/msg.js117
-rw-r--r--core/src/OC/notification.js232
-rw-r--r--core/src/OC/plugins.js89
4 files changed, 444 insertions, 0 deletions
diff --git a/core/src/OC/index.js b/core/src/OC/index.js
index ba63780a879..9d416f687a2 100644
--- a/core/src/OC/index.js
+++ b/core/src/OC/index.js
@@ -25,6 +25,9 @@ import Backbone from './backbone'
import ContactsMenu from './contactsmenu'
import EventSource from './eventsource'
import L10N from './l10n'
+import msg from './msg'
+import Notification from './notification'
+import Plugins from './plugins'
/** @namespace OC */
export default {
@@ -34,4 +37,7 @@ export default {
ContactsMenu,
EventSource,
L10N,
+ msg,
+ Notification,
+ Plugins,
}
diff --git a/core/src/OC/msg.js b/core/src/OC/msg.js
new file mode 100644
index 00000000000..1d43b4375e7
--- /dev/null
+++ b/core/src/OC/msg.js
@@ -0,0 +1,117 @@
+/* global t */
+
+/*
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import $ from 'jquery';
+
+/**
+ * A little class to manage a status field for a "saving" process.
+ * It can be used to display a starting message (e.g. "Saving...") and then
+ * replace it with a green success message or a red error message.
+ *
+ * @namespace OC.msg
+ */
+export default {
+ /**
+ * Displayes a "Saving..." message in the given message placeholder
+ *
+ * @param {Object} selector Placeholder to display the message in
+ */
+ startSaving: function (selector) {
+ this.startAction(selector, t('core', 'Saving...'));
+ },
+
+ /**
+ * Displayes a custom message in the given message placeholder
+ *
+ * @param {Object} selector Placeholder to display the message in
+ * @param {string} message Plain text message to display (no HTML allowed)
+ */
+ startAction: function (selector, message) {
+ $(selector).text(message)
+ .removeClass('success')
+ .removeClass('error')
+ .stop(true, true)
+ .show();
+ },
+
+ /**
+ * Displayes an success/error message in the given selector
+ *
+ * @param {Object} selector Placeholder to display the message in
+ * @param {Object} response Response of the server
+ * @param {Object} response.data Data of the servers response
+ * @param {string} response.data.message Plain text message to display (no HTML allowed)
+ * @param {string} response.status is being used to decide whether the message
+ * is displayed as an error/success
+ */
+ finishedSaving: function (selector, response) {
+ this.finishedAction(selector, response);
+ },
+
+ /**
+ * Displayes an success/error message in the given selector
+ *
+ * @param {Object} selector Placeholder to display the message in
+ * @param {Object} response Response of the server
+ * @param {Object} response.data Data of the servers response
+ * @param {string} response.data.message Plain text message to display (no HTML allowed)
+ * @param {string} response.status is being used to decide whether the message
+ * is displayed as an error/success
+ */
+ finishedAction: function (selector, response) {
+ if (response.status === "success") {
+ this.finishedSuccess(selector, response.data.message);
+ } else {
+ this.finishedError(selector, response.data.message);
+ }
+ },
+
+ /**
+ * Displayes an success message in the given selector
+ *
+ * @param {Object} selector Placeholder to display the message in
+ * @param {string} message Plain text success message to display (no HTML allowed)
+ */
+ finishedSuccess: function (selector, message) {
+ $(selector).text(message)
+ .addClass('success')
+ .removeClass('error')
+ .stop(true, true)
+ .delay(3000)
+ .fadeOut(900)
+ .show();
+ },
+
+ /**
+ * Displayes an error message in the given selector
+ *
+ * @param {Object} selector Placeholder to display the message in
+ * @param {string} message Plain text error message to display (no HTML allowed)
+ */
+ finishedError: function (selector, message) {
+ $(selector).text(message)
+ .addClass('error')
+ .removeClass('success')
+ .show();
+ }
+}
diff --git a/core/src/OC/notification.js b/core/src/OC/notification.js
new file mode 100644
index 00000000000..73220c71bdd
--- /dev/null
+++ b/core/src/OC/notification.js
@@ -0,0 +1,232 @@
+/*
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import _ from 'underscore'
+import $ from 'jquery'
+
+/**
+ * @todo Write documentation
+ * @namespace OC.Notification
+ */
+export default {
+ queuedNotifications: [],
+ getDefaultNotificationFunction: null,
+
+ /**
+ * @type Array<int>
+ * @description array of notification timers
+ */
+ notificationTimers: [],
+
+ /**
+ * @param callback
+ * @todo Write documentation
+ */
+ setDefault: function (callback) {
+ this.getDefaultNotificationFunction = callback;
+ },
+
+ /**
+ * Hides a notification.
+ *
+ * If a row is given, only hide that one.
+ * If no row is given, hide all notifications.
+ *
+ * @param {jQuery} [$row] notification row
+ * @param {Function} [callback] callback
+ */
+ hide: function ($row, callback) {
+ var self = this;
+ var $notification = $('#notification');
+
+ if (_.isFunction($row)) {
+ // first arg is the callback
+ callback = $row;
+ $row = undefined;
+ }
+
+ if (!$row) {
+ console.warn('Missing argument $row in OC.Notification.hide() call, caller needs to be adjusted to only dismiss its own notification');
+ // assume that the row to be hidden is the first one
+ $row = $notification.find('.row:first');
+ }
+
+ if ($row && $notification.find('.row').length > 1) {
+ // remove the row directly
+ $row.remove();
+ if (callback) {
+ callback.call();
+ }
+ return;
+ }
+
+ _.defer(function () {
+ // fade out is supposed to only fade when there is a single row
+ // however, some code might call hide() and show() directly after,
+ // which results in more than one element
+ // in this case, simply delete that one element that was supposed to
+ // fade out
+ //
+ // FIXME: remove once all callers are adjusted to only hide their own notifications
+ if ($notification.find('.row').length > 1) {
+ $row.remove();
+ return;
+ }
+
+ // else, fade out whatever was present
+ $notification.fadeOut('400', function () {
+ if (self.isHidden()) {
+ if (self.getDefaultNotificationFunction) {
+ self.getDefaultNotificationFunction.call();
+ }
+ }
+ if (callback) {
+ callback.call();
+ }
+ $notification.empty();
+ });
+ });
+ },
+
+ /**
+ * Shows a notification as HTML without being sanitized before.
+ * If you pass unsanitized user input this may lead to a XSS vulnerability.
+ * Consider using show() instead of showHTML()
+ *
+ * @param {string} html Message to display
+ * @param {Object} [options] options
+ * @param {string} [options.type] notification type
+ * @param {int} [options.timeout=0] timeout value, defaults to 0 (permanent)
+ * @return {jQuery} jQuery element for notification row
+ */
+ showHtml: function (html, options) {
+ options = options || {};
+ _.defaults(options, {
+ timeout: 0
+ });
+
+ var self = this;
+ var $notification = $('#notification');
+ if (this.isHidden()) {
+ $notification.fadeIn().css('display', 'inline-block');
+ }
+ var $row = $('<div class="row"></div>');
+ if (options.type) {
+ $row.addClass('type-' + options.type);
+ }
+ if (options.type === 'error') {
+ // add a close button
+ var $closeButton = $('<a class="action close icon-close" href="#"></a>');
+ $closeButton.attr('alt', t('core', 'Dismiss'));
+ $row.append($closeButton);
+ $closeButton.one('click', function () {
+ self.hide($row);
+ return false;
+ });
+ $row.addClass('closeable');
+ }
+
+ $row.prepend(html);
+ $notification.append($row);
+
+ if (options.timeout > 0) {
+ // register timeout to vanish notification
+ this.notificationTimers.push(setTimeout(function () {
+ self.hide($row);
+ }, (options.timeout * 1000)));
+ }
+
+ return $row;
+ },
+
+ /**
+ * Shows a sanitized notification
+ *
+ * @param {string} text Message to display
+ * @param {Object} [options] options
+ * @param {string} [options.type] notification type
+ * @param {int} [options.timeout=0] timeout value, defaults to 0 (permanent)
+ * @return {jQuery} jQuery element for notification row
+ */
+ show: function (text, options) {
+ return this.showHtml($('<div/>').text(text).html(), options);
+ },
+
+ /**
+ * Updates (replaces) a sanitized notification.
+ *
+ * @param {string} text Message to display
+ * @return {jQuery} JQuery element for notificaiton row
+ */
+ showUpdate: function (text) {
+ var $notification = $('#notification');
+ // sanitise
+ var $html = $('<div/>').text(text).html();
+
+ // new notification
+ if (text && $notification.find('.row').length == 0) {
+ return this.showHtml($html);
+ }
+
+ var $row = $('<div class="row"></div>').prepend($html);
+
+ // just update html in notification
+ $notification.html($row);
+
+ return $row;
+ },
+
+ /**
+ * Shows a notification that disappears after x seconds, default is
+ * 7 seconds
+ *
+ * @param {string} text Message to show
+ * @param {array} [options] options array
+ * @param {int} [options.timeout=7] timeout in seconds, if this is 0 it will show the message permanently
+ * @param {boolean} [options.isHTML=false] an indicator for HTML notifications (true) or text (false)
+ * @param {string} [options.type] notification type
+ */
+ showTemporary: function (text, options) {
+ var defaults = {
+ isHTML: false,
+ timeout: 7
+ };
+ options = options || {};
+ // merge defaults with passed in options
+ _.defaults(options, defaults);
+
+ var $row;
+ if (options.isHTML) {
+ $row = this.showHtml(text, options);
+ } else {
+ $row = this.show(text, options);
+ }
+ return $row;
+ },
+
+ /**
+ * Returns whether a notification is hidden.
+ * @return {boolean}
+ */
+ isHidden: function () {
+ return !$("#notification").find('.row').length;
+ }
+}
diff --git a/core/src/OC/plugins.js b/core/src/OC/plugins.js
new file mode 100644
index 00000000000..dd25610c2db
--- /dev/null
+++ b/core/src/OC/plugins.js
@@ -0,0 +1,89 @@
+/*
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @namespace OC.Plugins
+ */
+export default {
+
+ /**
+ * @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);
+ }
+ }
+ }
+
+} \ No newline at end of file