mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-17 14:37:58 +00:00
* textcolor: fixed plugin bugs, added translation for zh * image: fixed default.jpg src bug * added 'ru' support for seaf edit * rm aloha-0.22.3 and ununsed files in aloha-0.22.7
743 lines
23 KiB
JavaScript
Executable File
743 lines
23 KiB
JavaScript
Executable File
/* repositorymanager.js is part of Aloha Editor project http://aloha-editor.org
|
|
*
|
|
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
|
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
|
* Contributors http://aloha-editor.org/contribution.php
|
|
*
|
|
* Aloha Editor is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or any later version.
|
|
*
|
|
* Aloha Editor 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* As an additional permission to the GNU GPL version 2, you may distribute
|
|
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
|
* source code without the copy of the GNU GPL normally required,
|
|
* provided you include this license notice and a URL through which
|
|
* recipients can access the Corresponding Source.
|
|
*/
|
|
define([
|
|
'jquery',
|
|
'util/class',
|
|
'aloha/core',
|
|
'aloha/console',
|
|
'aloha/repositoryobjects' // Provides Aloha.RepositoryFolder
|
|
], function (
|
|
$,
|
|
Class,
|
|
Aloha,
|
|
Console,
|
|
__unused__
|
|
) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Given an input set, returns a new set which is a range of the input set
|
|
* that maps to the given predicate.
|
|
*
|
|
* Prefers native Array.prototype.filter() where available (after JavaScript
|
|
* 1.6).
|
|
*
|
|
* @param {Array} domain
|
|
* @param {function:boolean} predicate
|
|
* @return {Array} Sub set of domain
|
|
*/
|
|
var filter = (function (native) {
|
|
return (native
|
|
? function (domain, predicate) {
|
|
return domain.filter(predicate);
|
|
}
|
|
: function (domain, predicate) {
|
|
var codomain = [];
|
|
var i;
|
|
for (i = 0; i < domain.length; i++) {
|
|
if (predicate(domain[i])) {
|
|
codomain.push(domain[i]);
|
|
}
|
|
}
|
|
return codomain;
|
|
}
|
|
);
|
|
}('filter' in Array.prototype));
|
|
|
|
/**
|
|
* Bundles results, and meta information in preparation for the JSON Reader.
|
|
*
|
|
* Used with query().
|
|
*
|
|
* @param {Array.<Document|Folder>} items Results, collected from all
|
|
* repositories.
|
|
* @param {object<string, number>} meta Optional object containing metainfo.
|
|
* @return {object} Result object.
|
|
*/
|
|
function bundle(items, meta) {
|
|
var result = {
|
|
items: items,
|
|
results: items.length
|
|
};
|
|
if (meta) {
|
|
result.numItems = meta.numItems;
|
|
result.hasMoreItems = meta.hasMoreItems;
|
|
result.timeout = meta.timeout;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Passes all the results we have collected to the client through the
|
|
* callback it specified.
|
|
*
|
|
* TODO: Implement sorting based on repository specification sort
|
|
* items by weight.
|
|
* items.sort(function (a, b) {
|
|
* return (b.weight || 0) - (a.weight || 0);
|
|
* });
|
|
*
|
|
* @param {function} callback Callback specified by client when invoking
|
|
* the query method.
|
|
* @param {Array.<Document|Folder>|object<string, number>} results
|
|
*/
|
|
function report(callback, results) {
|
|
callback(results);
|
|
}
|
|
|
|
/**
|
|
* Predicates; used to filter lists of repositories based on whether they
|
|
* implement a method or not.
|
|
*
|
|
* @type {object<string, function(Repository):boolean}
|
|
*/
|
|
var repositoryFilters = {
|
|
query: function (repository) {
|
|
return typeof repository.query === 'function';
|
|
},
|
|
getChildren: function (repository) {
|
|
return typeof repository.getChildren === 'function';
|
|
},
|
|
getSelectedFolder: function (repository) {
|
|
return typeof repository.getSelectedFolder === 'function';
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Repository Manager.
|
|
*
|
|
* @namespace Aloha
|
|
* @class RepositoryManager
|
|
* @singleton
|
|
*/
|
|
var RepositoryManager = Class.extend({
|
|
|
|
repositories: [],
|
|
|
|
settings: (Aloha.settings && Aloha.settings.repositories) || {},
|
|
|
|
initialized: false,
|
|
|
|
/**
|
|
* Initializes all registered repositories.
|
|
*
|
|
* ???
|
|
* |
|
|
* v
|
|
*
|
|
* Warning: testing has shown that repositories are maybe not loaded yet
|
|
* (found that case in IE7), so don't rely on that in this init
|
|
* function.
|
|
*
|
|
* ^
|
|
* |
|
|
* !!!
|
|
*/
|
|
init: function () {
|
|
var manager = this;
|
|
if (typeof manager.settings.timeout === 'undefined') {
|
|
manager.settings.timeout = 5000;
|
|
}
|
|
var i;
|
|
for (i = 0; i < manager.repositories.length; i++) {
|
|
manager.initRepository(manager.repositories[i]);
|
|
}
|
|
manager.initialized = true;
|
|
},
|
|
|
|
/**
|
|
* Registers a Repository.
|
|
*
|
|
* If the repositorie is registered after the Repository Manager is
|
|
* initialized it will be automatically initialized.
|
|
*
|
|
* @param {Repository} repository Repository to register.
|
|
*/
|
|
register: function (repository) {
|
|
var manager = this;
|
|
if (!manager.getRepository(repository.repositoryId)) {
|
|
manager.repositories.push(repository);
|
|
if (manager.initialized) {
|
|
manager.initRepository(repository);
|
|
}
|
|
} else {
|
|
Console.warn(manager, 'A repository with name "'
|
|
+ repository.repositoryId
|
|
+ '" already registerd. Ignoring this.');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Initializes a repository.
|
|
*
|
|
* @param {Repository} repository Repository to initialize.
|
|
*/
|
|
initRepository: function (repository) {
|
|
var manager = this;
|
|
if (!repository.settings) {
|
|
repository.settings = {};
|
|
}
|
|
if (manager.settings[repository.repositoryId]) {
|
|
$.extend(repository.settings,
|
|
manager.settings[repository.repositoryId]);
|
|
}
|
|
repository.init();
|
|
},
|
|
|
|
/**
|
|
* Returns the repository identified by repositoryId.
|
|
*
|
|
* @param {String} id Id of repository to retrieve.
|
|
* @return {Repository|null} Repository or null if none with the given
|
|
* id is found.
|
|
*/
|
|
getRepository: function (id) {
|
|
var manager = this;
|
|
var i;
|
|
for (i = 0; i < manager.repositories.length; i++) {
|
|
if (manager.repositories[i].repositoryId === id) {
|
|
return manager.repositories[i];
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Searches all repositories for repositoryObjects matching query and
|
|
* repositoryObjectType.
|
|
*
|
|
* <pre><code>
|
|
* // Example:
|
|
* var params = {
|
|
* queryString: 'hello',
|
|
* objectTypeFilter: ['website'],
|
|
* filter: null,
|
|
* inFolderId: null,
|
|
* orderBy: null,
|
|
* maxItems: null,
|
|
* skipCount: null,
|
|
* renditionFilter: null,
|
|
* repositoryId: null
|
|
* };
|
|
* Aloha.RepositoryManager.query(params, function (items) {
|
|
* Console.log(items);
|
|
* });
|
|
* </code></pre>
|
|
*
|
|
* @param {object<string, mixed>} params
|
|
*
|
|
* queryString: String The query string for full text
|
|
* search.
|
|
* objectTypeFilter: Array (optional) Object types to be retrieved.
|
|
* filter: Array (optional) Attributes that will be
|
|
* included.
|
|
* inFolderId: boolean (optional) Whether or not a candidate
|
|
* object is a child-object of the
|
|
* folder object identified by the
|
|
* given inFolderId (objectId).
|
|
* inTreeId: boolean (optional) This indicates whether or
|
|
* not a candidate object is a
|
|
* descendant-object of the folder
|
|
* object identified by the given
|
|
* inTreeId (objectId).
|
|
* orderBy: Array (optional) example: [{
|
|
* lastModificationDate: 'DESC',
|
|
* name: 'ASC'
|
|
* }]
|
|
* maxItems: number (optional) Number of items to include in
|
|
* result set.
|
|
* skipCount: number (optional) This is tricky in a merged
|
|
* multi repository scenario.
|
|
* renditionFilter: Array (optional) Instead of termlist, an
|
|
* array of kind or mimetype is
|
|
* expected. If null or an empty
|
|
* set, then all renditions are
|
|
* returned. See
|
|
* http://docs.oasis-open.org/cmis/CMIS/v1.0/cd04/cmis-spec-v1.0.html#_Ref237323310
|
|
* for renditionFilter.
|
|
*
|
|
* @param {function(Document|Folder)} callback Function to be invoked
|
|
* after the repository
|
|
* manager has finished
|
|
* querying all
|
|
* repositories.
|
|
*/
|
|
query: function (params, callback) {
|
|
var manager = this;
|
|
|
|
var i;
|
|
|
|
// The merged results, collected from repository responses.
|
|
var results = [];
|
|
|
|
// The merged metainfo, collected from repository responses.
|
|
var allmetainfo = {
|
|
numItems: 0,
|
|
hasMoreItems: false
|
|
};
|
|
|
|
// A counting semaphore (working in reverse, ie: 0 means free).
|
|
var numOpenQueries;
|
|
|
|
// Unless the calling client specifies otherwise, the manager will
|
|
// wait a maximum of 5 seconds for all repositories to be queried
|
|
// and respond. 5 seconds is deemed to be the reasonable time to
|
|
// wait when querying the repository manager in the context of
|
|
// something like autocomplete.
|
|
var timeout = (params.timeout && parseInt(params.timeout, 10))
|
|
|| manager.settings.timeout;
|
|
|
|
// When this timer times-out, whatever has been collected in
|
|
// `results' will be returned to the calling client and all further
|
|
// processing aborted.
|
|
var timer = window.setTimeout(function () {
|
|
// Store in metainfo that a timeout occurred.
|
|
allmetainfo = allmetainfo || {};
|
|
allmetainfo.timeout = true;
|
|
|
|
if (numOpenQueries > 0) {
|
|
Console.warn(manager, numOpenQueries
|
|
+ ' repositories did not return before the '
|
|
+ 'configured timeout of ' + timeout + 'ms.');
|
|
numOpenQueries = 0;
|
|
}
|
|
clearTimeout(timer);
|
|
report(callback, bundle(results, allmetainfo));
|
|
}, timeout);
|
|
|
|
/**
|
|
* Invoked by each repository when it wants to present its results
|
|
* to the manager.
|
|
*
|
|
* Collects the results from each repository, and decrements the
|
|
* numOpenQueries semaphore to indicate that there is one less
|
|
* repository for which the manager is waiting for a reponse.
|
|
*
|
|
* If a repository invokes this callback after all openCallbacks
|
|
* have been closed (ie: numOpenQueries == 0), then the repository
|
|
* was too late ("missed the ship"), and will be ignored.
|
|
*
|
|
* If numOpenQueries decrements to 0 during this call, it means that
|
|
* the the manager is ready to report the results back to the client
|
|
* through the report() method.
|
|
*
|
|
* @param {Array.<Document|Folder>} items Results returned by the
|
|
* repository.
|
|
* @param {object<string, number>} metainfo Optional Metainfo
|
|
* returned by some
|
|
* repositories.
|
|
*/
|
|
var process = function (items, metainfo) {
|
|
var repository = this;
|
|
|
|
if (0 === numOpenQueries) {
|
|
return;
|
|
}
|
|
|
|
if (items && items.length) {
|
|
|
|
// Because some negligent repository implementations do not
|
|
// set repositoryId properly.
|
|
if (!items[0].repositoryId) {
|
|
var id = repository.repositoryId;
|
|
var i;
|
|
for (i = 0; i < items.length; i++) {
|
|
items[i].repositoryId = id;
|
|
}
|
|
}
|
|
|
|
$.merge(results, items);
|
|
}
|
|
|
|
if (metainfo && allmetainfo) {
|
|
allmetainfo.numItems =
|
|
($.isNumeric(metainfo.numItems) &&
|
|
$.isNumeric(allmetainfo.numItems))
|
|
? allmetainfo.numItems + metainfo.numItems
|
|
: undefined;
|
|
|
|
allmetainfo.hasMoreItems =
|
|
(typeof metainfo.hasMoreItems === 'boolean' &&
|
|
typeof allmetainfo.hasMoreItems === 'boolean')
|
|
? allmetainfo.hasMoreItems || metainfo.hasMoreItems
|
|
: undefined;
|
|
|
|
if (metainfo.timeout) {
|
|
allmetainfo.timeout = true;
|
|
}
|
|
} else {
|
|
|
|
// Because if even one repository does not return metainfo,
|
|
// so we have no aggregated metainfo at all.
|
|
allmetainfo = undefined;
|
|
}
|
|
|
|
Console.debug(manager, 'The repository '
|
|
+ repository.repositoryId + 'returned with '
|
|
+ items.length + ' results.');
|
|
|
|
// TODO: how to return the metainfo here?
|
|
if (0 === --numOpenQueries) {
|
|
clearTimeout(timer);
|
|
report(callback, bundle(results, allmetainfo));
|
|
}
|
|
};
|
|
|
|
var repositories = params.repositoryId
|
|
? [manager.getRepository(params.repositoryId)]
|
|
: manager.repositories;
|
|
|
|
var queue = filter(repositories, repositoryFilters.query);
|
|
|
|
// If none of the repositories implemented the query method, then
|
|
// don't wait for the timeout, simply report to the client.
|
|
if (0 === queue.length) {
|
|
clearTimeout(timer);
|
|
report(callback, bundle(results, allmetainfo));
|
|
return;
|
|
}
|
|
|
|
var makeProcess = function (repository) {
|
|
return function () {
|
|
process.apply(repository, arguments);
|
|
};
|
|
};
|
|
|
|
numOpenQueries = queue.length;
|
|
|
|
for (i = 0; i < queue.length; i++) {
|
|
queue[i].query(params, makeProcess(queue[i]));
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Retrieves children items.
|
|
*
|
|
* @param {object<string,mixed>} params Object with properties.
|
|
*
|
|
* objectTypeFilter: Array (optional) Object types to be retrieved.
|
|
* filter: Array (optional) Attributes to be retrieved.
|
|
* inFolderId: boolean (optional) This indicates whether or not
|
|
* a candidate object is a
|
|
* child-object of the folder
|
|
* object identified by the given
|
|
* inFolderId (objectId).
|
|
* orderBy: Array (optional) example: [{
|
|
* lastModificationDate: 'DESC',
|
|
* name: 'ASC'
|
|
* }]
|
|
* maxItems: number (optional) number Items to return as a result.
|
|
* skipCount: number (optional) This is tricky in a merged
|
|
* multi repository scenario.
|
|
* renditionFilter: Array (optional) Instead of termlist an Array
|
|
* of kind or mimetype is
|
|
* expected. If null or
|
|
* Array.length == 0 all
|
|
* renditions are returned. See
|
|
* http://docs.oasis-open.org/cmis/CMIS/v1.0/cd04/cmis-spec-v1.0.html#_Ref237323310
|
|
* for renditionFilter.
|
|
*
|
|
* @param {function(Document|Folder)} callback Function to be invoked
|
|
* after the repository
|
|
* manager has finished
|
|
* querying all
|
|
* repositories.
|
|
*/
|
|
getChildren: function (params, callback) {
|
|
var manager = this;
|
|
|
|
var i;
|
|
|
|
// The marged results, collected from repository responses.
|
|
var results = [];
|
|
|
|
// A counting semaphore (working in reverse, ie: 0 means free).
|
|
var numOpenQueries = 0;
|
|
|
|
var timeout = (params.timeout && parseInt(params.timeout, 10))
|
|
|| manager.settings.timeout;
|
|
|
|
var timer = window.setTimeout(function () {
|
|
if (numOpenQueries > 0) {
|
|
Console.warn(manager, numOpenQueries
|
|
+ ' repositories did not respond before the '
|
|
+ 'configured timeout of ' + timeout + 'ms.');
|
|
numOpenQueries = 0;
|
|
}
|
|
clearTimeout(timer);
|
|
report(callback, results);
|
|
}, timeout);
|
|
|
|
var process = function (items) {
|
|
if (0 === numOpenQueries) {
|
|
return;
|
|
}
|
|
if (items) {
|
|
$.merge(results, items);
|
|
}
|
|
if (0 === --numOpenQueries) {
|
|
clearTimeout(timer);
|
|
report(callback, results);
|
|
}
|
|
};
|
|
|
|
var repositories = params.repositoryId
|
|
? [manager.getRepository(params.repositoryId)]
|
|
: manager.repositories;
|
|
|
|
if (params.repositoryFilter && params.repositoryFilter.length) {
|
|
repositories = filter(repositories, function (repository) {
|
|
return -1 < $.inArray(repository.repositoryId,
|
|
params.repositoryFilter);
|
|
});
|
|
}
|
|
|
|
// If the inFolderId is the default id of 'aloha', then return all
|
|
// registered repositories as the result set.
|
|
if ('aloha' === params.inFolderId) {
|
|
var hasRepoFilter = params.repositoryFilter
|
|
&& 0 < params.repositoryFilter.length;
|
|
|
|
for (i = 0; i < repositories.length; i++) {
|
|
results.push(new Aloha.RepositoryFolder({
|
|
id: repositories[i].repositoryId,
|
|
name: repositories[i].repositoryName,
|
|
repositoryId: repositories[i].repositoryId,
|
|
type: 'repository',
|
|
hasMoreItems: true
|
|
}));
|
|
}
|
|
|
|
clearTimeout(timer);
|
|
report(callback, results);
|
|
return;
|
|
}
|
|
|
|
var queue = filter(repositories, repositoryFilters.getChildren);
|
|
|
|
if (0 === queue.length) {
|
|
clearTimeout(timer);
|
|
report(callback, results);
|
|
return;
|
|
}
|
|
|
|
numOpenQueries = queue.length;
|
|
|
|
for (i = 0; i < queue.length; i++) {
|
|
queue[i].getChildren(params, process);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @fixme: Not tested, but the code for this function does not seem to
|
|
* compute repository.makeClean will be undefined
|
|
*
|
|
* @todo: Rewrite this function header comment so that is clearer
|
|
*
|
|
* Pass an object, which represents an marked repository to corresponding
|
|
* repository, so that it can make the content clean (prepare for saving)
|
|
*
|
|
* @param {jQuery} obj - representing an editable
|
|
* @return void
|
|
*/
|
|
makeClean: function (obj) {
|
|
// iterate through all registered repositories
|
|
var that = this,
|
|
repository = {},
|
|
i = 0,
|
|
j = that.repositories.length;
|
|
|
|
// find all repository tags
|
|
obj.find('[data-gentics-aloha-repository=' + this.prefix + ']').each(function () {
|
|
while (i < j) {
|
|
repository.makeClean(obj);
|
|
i += 1;
|
|
}
|
|
Console.debug(that, 'Passing contents of HTML Element with id { ' + this.attr('id') + ' } for cleaning to repository { ' + repository.repositoryId + ' }');
|
|
repository.makeClean(this);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Marks an object as repository of this type and with this item.id.
|
|
* Objects can be any DOM objects as A, SPAN, ABBR, etc. or
|
|
* special objects such as aloha-aloha_block elements.
|
|
*
|
|
* Marks the target obj with two private attributes:
|
|
* (see http://dev.w3.org/html5/spec/elements.html#embedding-custom-non-visible-data)
|
|
* - data-gentics-aloha-repository: stores the repositoryId
|
|
* - data-gentics-aloha-object-id: stores the object.id
|
|
*
|
|
* @param {HTMLElement} obj DOM object to mark.
|
|
* @param {Aloha.Repository.Object} item Item which is applied to obj,
|
|
* if set to null, the
|
|
* "data-GENTICS-..." attributes
|
|
* are removed.
|
|
*/
|
|
markObject: function (obj, item) {
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
|
|
var manager = this;
|
|
|
|
if (item) {
|
|
var repository = manager.getRepository(item.repositoryId);
|
|
if (repository) {
|
|
$(obj).attr({
|
|
'data-gentics-aloha-repository': item.repositoryId,
|
|
'data-gentics-aloha-object-id': item.id
|
|
});
|
|
repository.markObject(obj, item);
|
|
} else {
|
|
Console.error(manager, 'Trying to apply a repository "'
|
|
+ item.name
|
|
+ '" to an object, but item has no repositoryId.');
|
|
}
|
|
} else {
|
|
$(obj).removeAttr('data-gentics-aloha-repository')
|
|
.removeAttr('data-gentics-aloha-object-id');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get the object for which the given DOM object is marked from the
|
|
* repository.
|
|
*
|
|
* Will initialize the item cache (per repository) if not already done.
|
|
*
|
|
* @param {HTMLElement} element DOM object which probably is marked.
|
|
* @param {function} callback
|
|
*/
|
|
getObject: function (element, callback) {
|
|
var manager = this;
|
|
var $element = $(element);
|
|
var itemId = $element.attr('data-gentics-aloha-object-id');
|
|
var repositoryId = $element.attr('data-gentics-aloha-repository');
|
|
var repository = manager.getRepository(repositoryId);
|
|
|
|
if (repository && itemId) {
|
|
if (!manager.itemCache) {
|
|
manager.itemCache = [];
|
|
}
|
|
|
|
var cache = manager.itemCache[repositoryId];
|
|
if (!cache) {
|
|
cache = manager.itemCache[repositoryId] = [];
|
|
}
|
|
|
|
if (cache[itemId]) {
|
|
callback([cache[itemId]]);
|
|
} else {
|
|
repository.getObjectById(itemId, function (items) {
|
|
cache[itemId] = items[0];
|
|
callback(items);
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Mark a folder as opened.
|
|
*
|
|
* Called by a repository client (eg: repository browser) when a folder
|
|
* is opened.
|
|
*
|
|
* @param {object|Folder} folder Object with property repositoryId.
|
|
*/
|
|
folderOpened: function (folder) {
|
|
var repository = this.getRepository(folder.repositoryId);
|
|
if (typeof repository.folderOpened === 'function') {
|
|
repository.folderOpened(folder);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Mark a folder as closed.
|
|
*
|
|
* Called by a repository client (eg: repository browser) when a folder
|
|
* is closed.
|
|
*
|
|
* @param {object|Folder} folder Object with property repositoryId.
|
|
*/
|
|
folderClosed: function (folder) {
|
|
var repository = this.getRepository(folder.repositoryId);
|
|
if (typeof repository.folderClosed === 'function') {
|
|
repository.folderClosed(folder);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Mark a folder as selected.
|
|
*
|
|
* Called by a repository client (eg: repository browser) when a folder
|
|
* is selected.
|
|
*
|
|
* @param {object|Folder} folder Object with property repositoryId.
|
|
*/
|
|
folderSelected: function (folder) {
|
|
var repository = this.getRepository(folder.repositoryId);
|
|
if (typeof repository.folderSelected === 'function') {
|
|
repository.folderSelected(folder);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Retrieve the selected folder.
|
|
*
|
|
* @return {Folder} Selected folder or null if it cannot be found.
|
|
*/
|
|
getSelectedFolder: function () {
|
|
var repositories = filter(this.repositories,
|
|
repositoryFilters.getSelectedFolder);
|
|
var i;
|
|
var selected;
|
|
for (i = 0; i < repositories.length; i++) {
|
|
selected = repositories[i].getSelectedFolder();
|
|
if (selected) {
|
|
return selected;
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Human readable representation of repository manager.
|
|
*
|
|
* @return {string}
|
|
*/
|
|
toString: function () {
|
|
return 'repositorymanager';
|
|
}
|
|
|
|
});
|
|
|
|
Aloha.RepositoryManager = new RepositoryManager();
|
|
|
|
return Aloha.RepositoryManager;
|
|
});
|