diff --git a/core/js/dist/login.js b/core/js/dist/login.js
index 34b02711c2e70cb8ace7fdec225f11b1441e1668..45a7be6facbe32cd0ecbf923a3ba6e6953ea43bb 100644
Binary files a/core/js/dist/login.js and b/core/js/dist/login.js differ
diff --git a/core/js/dist/login.js.map b/core/js/dist/login.js.map
index 8c14ae9d5bba112a58beebdedfe4b6115301ea0b..06e1c8f8abd566d3cab6297cd73ae4c32f889fbf 100644
Binary files a/core/js/dist/login.js.map and b/core/js/dist/login.js.map differ
diff --git a/core/js/dist/main.js b/core/js/dist/main.js
index b71fa7fcdff879c871913f91f2ab77dea66abb2c..008d97e2b4584a408639b7e83ab60a9ceb7e12b8 100644
Binary files a/core/js/dist/main.js and b/core/js/dist/main.js differ
diff --git a/core/js/dist/main.js.map b/core/js/dist/main.js.map
index 04bf5079184e6e9f975877b60c7c21d0d489b896..9a0e1c518d8ee9f9c9236bad944163cba15e5b36 100644
Binary files a/core/js/dist/main.js.map and b/core/js/dist/main.js.map differ
diff --git a/core/js/js.js b/core/js/js.js
index 4a7f035db6122b8f7f0685d72db82d7f71b78f45..127d293cd4cabd0931a2fcb65675be2d542a7959 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -81,39 +81,6 @@ Object.assign(window.OC, {
 		return OC._capabilities;
 	},
 
-	/**
-	 * get the absolute path to an image file
-	 * if no extension is given for the image, it will automatically decide
-	 * between .png and .svg based on what the browser supports
-	 * @param {string} app the app id to which the image belongs
-	 * @param {string} file the name of the image file
-	 * @return {string}
-	 */
-	imagePath:function(app,file){
-		if(file.indexOf('.')==-1){//if no extension is given, use svg
-			file+='.svg';
-		}
-		return OC.filePath(app,'img',file);
-	},
-
-	/**
-	 * URI-Encodes a file path but keep the path slashes.
-	 *
-	 * @param path path
-	 * @return encoded path
-	 */
-	encodePath: function(path) {
-		if (!path) {
-			return path;
-		}
-		var parts = path.split('/');
-		var result = [];
-		for (var i = 0; i < parts.length; i++) {
-			result.push(encodeURIComponent(parts[i]));
-		}
-		return result.join('/');
-	},
-
 	/**
 	 * Loads translations for the given app asynchronously.
 	 *
@@ -125,102 +92,6 @@ Object.assign(window.OC, {
 		return OC.L10N.load(app, callback);
 	},
 
-	/**
-	 * Returns the base name of the given path.
-	 * For example for "/abc/somefile.txt" it will return "somefile.txt"
-	 *
-	 * @param {String} path
-	 * @return {String} base name
-	 */
-	basename: function(path) {
-		return path.replace(/\\/g,'/').replace( /.*\//, '' );
-	},
-
-	/**
-	 * Returns the dir name of the given path.
-	 * For example for "/abc/somefile.txt" it will return "/abc"
-	 *
-	 * @param {String} path
-	 * @return {String} dir name
-	 */
-	dirname: function(path) {
-		return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');
-	},
-
-	/**
-	 * Returns whether the given paths are the same, without
-	 * leading, trailing or doubled slashes and also removing
-	 * the dot sections.
-	 *
-	 * @param {String} path1 first path
-	 * @param {String} path2 second path
-	 * @return {bool} true if the paths are the same
-	 *
-	 * @since 9.0
-	 */
-	isSamePath: function(path1, path2) {
-		var filterDot = function(p) {
-			return p !== '.';
-		};
-		var pathSections1 = _.filter((path1 || '').split('/'), filterDot);
-		var pathSections2 = _.filter((path2 || '').split('/'), filterDot);
-		path1 = OC.joinPaths.apply(OC, pathSections1);
-		path2 = OC.joinPaths.apply(OC, pathSections2);
-		return path1 === path2;
-	},
-
-	/**
-	 * Join path sections
-	 *
-	 * @param {...String} path sections
-	 *
-	 * @return {String} joined path, any leading or trailing slash
-	 * will be kept
-	 *
-	 * @since 8.2
-	 */
-	joinPaths: function() {
-		if (arguments.length < 1) {
-			return '';
-		}
-		var path = '';
-		// convert to array
-		var args = Array.prototype.slice.call(arguments);
-		// discard empty arguments
-		args = _.filter(args, function(arg) {
-			return arg.length > 0;
-		});
-		if (args.length < 1) {
-			return '';
-		}
-
-		var lastArg = args[args.length - 1];
-		var leadingSlash = args[0].charAt(0) === '/';
-		var trailingSlash = lastArg.charAt(lastArg.length - 1) === '/';
-		var sections = [];
-		var i;
-		for (i = 0; i < args.length; i++) {
-			sections = sections.concat(args[i].split('/'));
-		}
-		var first = !leadingSlash;
-		for (i = 0; i < sections.length; i++) {
-			if (sections[i] !== '') {
-				if (first) {
-					first = false;
-				} else {
-					path += '/';
-				}
-				path += sections[i];
-			}
-		}
-
-		if (trailingSlash) {
-			// add it back
-			path += '/';
-		}
-		return path;
-	},
-
 	/**
 	 * Parses a URL query string into a JS map
 	 * @param {string} queryString query string in the format param1=1234&param2=abcde&param3=xyz
diff --git a/core/src/OC/index.js b/core/src/OC/index.js
index 6a9fea3c7b7c96e3bea2c09465cd368cfa2e2cd0..9838e63b0f8c689915ca32f452046ee68847c997 100644
--- a/core/src/OC/index.js
+++ b/core/src/OC/index.js
@@ -24,6 +24,13 @@ import Apps from './apps'
 import {AppConfig, appConfig} from './appconfig'
 import appswebroots from './appswebroots'
 import Backbone from './backbone'
+import {
+	basename,
+	dirname,
+	encodePath,
+	isSamePath,
+	joinPaths,
+} from './path'
 import Config from './config'
 import {
 	coreApps,
@@ -55,9 +62,10 @@ import {
 import {isUserAdmin} from './admin'
 import L10N from './l10n'
 import {
+	filePath,
 	generateUrl,
 	getRootPath,
-	filePath,
+	imagePath,
 	linkTo,
 	linkToOCS,
 	linkToRemote,
@@ -125,6 +133,15 @@ export default {
 	showMenu,
 	unregisterMenu,
 
+	/*
+	 * Path helpers
+	 */
+	basename,
+	encodePath,
+	dirname,
+	isSamePath,
+	joinPaths,
+
 	msg,
 	Notification,
 	PasswordConfirmation,
@@ -132,11 +149,12 @@ export default {
 	search,
 	Util,
 	debug,
+	filePath,
 	generateUrl,
 	get: get(window),
 	set: set(window),
 	getRootPath,
-	filePath,
+	imagePath,
 	redirect,
 	reload,
 	requestToken: getRequestToken(),
diff --git a/core/src/OC/path.js b/core/src/OC/path.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef58caf4850dd4f284347ad8fdd5306587c9e835
--- /dev/null
+++ b/core/src/OC/path.js
@@ -0,0 +1,123 @@
+/*
+ * @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/>.
+ */
+
+/**
+ * URI-Encodes a file path but keep the path slashes.
+ *
+ * @param {String} path
+ * @return {String} encoded path
+ */
+export const encodePath = path => {
+	if (!path) {
+		return path
+	}
+	const parts = path.split('/')
+	const result = []
+	for (let i = 0; i < parts.length; i++) {
+		result.push(encodeURIComponent(parts[i]))
+	}
+	return result.join('/')
+}
+
+/**
+ * Returns the base name of the given path.
+ * For example for "/abc/somefile.txt" it will return "somefile.txt"
+ *
+ * @param {String} path
+ * @return {String} base name
+ */
+export const basename = path => path.replace(/\\/g, '/').replace(/.*\//, '')
+
+/**
+ * Returns the dir name of the given path.
+ * For example for "/abc/somefile.txt" it will return "/abc"
+ *
+ * @param {String} path
+ * @return {String} dir name
+ */
+export const dirname = path => path.replace(/\\/g, '/').replace(/\/[^\/]*$/, '')
+
+/**
+ * Returns whether the given paths are the same, without
+ * leading, trailing or doubled slashes and also removing
+ * the dot sections.
+ *
+ * @param {String} path1 first path
+ * @param {String} path2 second path
+ * @return {bool} true if the paths are the same
+ *
+ * @since 9.0
+ */
+export const isSamePath = (path1, path2) => {
+	const pathSections1 = (path1 || '').split('/').filter(p => p !== '.')
+	const pathSections2 = (path2 || '').split('/').filter(p => p !== '.')
+	path1 = joinPaths.apply(undefined, pathSections1)
+	path2 = joinPaths.apply(undefined, pathSections2)
+
+	return path1 === path2
+}
+
+/**
+ * Join path sections
+ *
+ * @param {...String} path sections
+ *
+ * @return {String} joined path, any leading or trailing slash
+ * will be kept
+ *
+ * @since 8.2
+ */
+export const joinPaths = (...args) => {
+	if (arguments.length < 1) {
+		return ''
+	}
+
+	// discard empty arguments
+	const nonEmptyArgs = args.filter(arg => arg.length > 0)
+	if (nonEmptyArgs.length < 1) {
+		return ''
+	}
+
+	const lastArg = nonEmptyArgs[nonEmptyArgs.length - 1]
+	const leadingSlash = nonEmptyArgs[0].charAt(0) === '/'
+	const trailingSlash = lastArg.charAt(lastArg.length - 1) === '/';
+	const sections = nonEmptyArgs.reduce((acc, section) => acc.concat(section.split('/')), [])
+
+	let first = !leadingSlash
+	const path = sections.reduce((acc, section) => {
+		if (section === '') {
+			return acc
+		}
+
+		if (first) {
+			first = false
+			return acc + section
+		}
+
+		return acc + '/' + section
+	}, '')
+
+	if (trailingSlash) {
+		// add it back
+		return path + '/'
+	}
+	return path
+}
diff --git a/core/src/OC/routing.js b/core/src/OC/routing.js
index 8c7a7d7e1cd2d43a5002bbc62ca287bb59786fdf..145f075c1b2ffa517033447577f9b73e57b0815e 100644
--- a/core/src/OC/routing.js
+++ b/core/src/OC/routing.js
@@ -98,6 +98,24 @@ export const generateUrl = (url, params, options) => {
 	return getRootPath() + '/index.php' + _build(url, params);
 }
 
+/**
+ * get the absolute path to an image file
+ * if no extension is given for the image, it will automatically decide
+ * between .png and .svg based on what the browser supports
+ *
+ * @param {string} app the app id to which the image belongs
+ * @param {string} file the name of the image file
+ * @return {string}
+ */
+export const imagePath = (app, file) => {
+	if (file.indexOf('.') === -1) {
+		//if no extension is given, use svg
+		return filePath(app, 'img', file + '.svg')
+	}
+
+	return filePath(app, 'img', file)
+}
+
 /**
  * Get the absolute url for a file in an app
  * @param {string} app the id of the app