mirror of
https://github.com/haiwen/seahub.git
synced 2025-04-28 03:10:45 +00:00
[backbone] cleanup: removed related html/js files and python file/code (#4292)
This commit is contained in:
parent
42e64aca4e
commit
ed6336e7d5
@ -1,129 +0,0 @@
|
||||
{% load staticfiles i18n %}
|
||||
{% load compress %}
|
||||
{% load seahub_tags avatar_tags group_avatar_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ LANGUAGE_CODE }}">
|
||||
<head>
|
||||
<title>{{ site_title }}</title>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="keywords" content="{% trans "File Collaboration Team Organization" %}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link rel="shortcut icon" href="{{ MEDIA_URL }}{{ favicon_path }}" />
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/bootstrap.min.css" %}" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/jstree_default_theme/style.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/select2-3.5.2.css" %}" />
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/magnific-popup.css" %}" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seahub.css?t=1398068110" />
|
||||
{% endcompress %}
|
||||
|
||||
{% block extra_style %}{% endblock %}
|
||||
{% if branding_css != '' %}<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}{{ branding_css }}" />{% endif %}
|
||||
{% if enable_branding_css %}<link rel="stylesheet" type="text/css" href="{% url 'custom_css' %}" />{% endif %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrapper" role="application" class="{{ LANGUAGE_CODE }} h100 d-flex fd-col">
|
||||
<!--[if lt IE 10]>
|
||||
<p id="top-browser-tip" class="top-bar>{% trans "We no longer support this version of IE. Please upgrade it to version 10 or above." %} <span id="top-browser-tip-close" class="top-bar-click">{% trans "Close" %}</span></p>
|
||||
<![endif]-->
|
||||
{% block info_bar_message %}
|
||||
{% if request.user.is_authenticated and request.cur_note %}
|
||||
<div id="info-bar">
|
||||
<p id="info-bar-info">{{ request.cur_note.message|urlize }}</p>
|
||||
<span class="close sf2-icon-x1 op-icon" title="{% trans "Close" %}"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock info_bar_message %}
|
||||
|
||||
<div id="main" class="container-fluid w100 flex-auto ovhd d-flex fd-col"> {# 'ovhd' is for firefox #}
|
||||
<div class="initial-loading">
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
</div>
|
||||
|
||||
<div class="row main-content flex-auto ovhd d-flex hide"> {# 'ovhd' is for firefox #}
|
||||
<div class="side-panel col-md-3">
|
||||
<div class="side-panel-top panel-top">
|
||||
<a href="{{ SITE_ROOT }}" id="logo">
|
||||
<img src="{{ MEDIA_URL }}{{ logo_path }}" title="{{ site_title }}" alt="logo" width="{{logo_width}}" height="{{logo_height}}" />
|
||||
</a>
|
||||
<a href="#" title="{% trans "Close" %}" aria-label="{% trans "Close" %}" class="sf2-icon-x1 sf-popover-close side-panel-close op-icon hidden-md-up js-close"></a>
|
||||
</div>
|
||||
<div id="side-nav" class="home-side-nav" role="navigation"></div> {# #side-nav: to be compatible with old code #}
|
||||
</div>
|
||||
|
||||
<div class="col-md-9 main-panel flex-auto ovhd">
|
||||
<div class="main-panel-top panel-top">
|
||||
<span class="sf2-icon-menu side-nav-toggle hidden-md-up" title="{% trans "Side Nav Menu" %}" id="js-toggle-side-nav" aria-label="{% trans "Side Nav Menu" %}"></span>
|
||||
{# place for '<div class="cur-view-toolbar" id=""></div>' #}
|
||||
<div class="common-toolbar">
|
||||
{% if has_file_search %}
|
||||
{% include 'snippets/search_form.html' %}
|
||||
{% endif %}
|
||||
|
||||
<div id="notifications">
|
||||
<a href="#" class="no-deco" id="notice-icon" title="{% trans "Notifications" %}" aria-label="{% trans "Notifications" %}">
|
||||
<span class="sf2-icon-bell"></span>
|
||||
<span class="num hide">0</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if show_logout_icon %}
|
||||
<a id="logout-icon" href="{{ SITE_ROOT }}accounts/logout/" class="no-deco" title="{% trans "Log out" %}" aria-label="{% trans "Log out" %}"><span class="sf2-icon-logout"></span></a>
|
||||
{% endif %}
|
||||
|
||||
<div id="account">
|
||||
<a id="my-info" href="#" class="account-toggle no-deco hidden-sm-down" aria-label="{% trans "View profile and more" %}">
|
||||
{% avatar request.user 32 %} <span class="icon-caret-down vam"></span>
|
||||
</a>
|
||||
<span class="account-toggle sf2-icon-more mobile-icon hidden-md-up" aria-label="{% trans "View profile and more" %}"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# place for '<div class="main-panel-main" id=""></div>' #}
|
||||
</div>
|
||||
</div>
|
||||
</div> {# #main #}
|
||||
|
||||
<div id="confirm-popup" class="hide">
|
||||
<div id="confirm-con"></div>
|
||||
<button id="confirm-yes">{% trans "Yes"%}</button>
|
||||
<button class="simplemodal-close">{% trans "No"%}</button>
|
||||
</div>
|
||||
|
||||
<div id="guide-for-new" class="hide">
|
||||
<span class="icon-lightbulb fleft" aria-hidden="true"></span>
|
||||
<div class="txt">
|
||||
<h3 id="dialogTitle">{% blocktrans with site_name=site_name %}Welcome to {{site_name}}{% endblocktrans %}</h3>
|
||||
{% if user.permissions.can_add_repo %}
|
||||
<p>{% blocktrans with site_name=site_name %}{{site_name}} organizes files into libraries. Each library can be synced and shared separately. We have created a personal library for you. You can create more libraries later.{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
<p>{% blocktrans with site_name=site_name %}{{site_name}} organizes files into libraries. Each library can be synced and shared separately. Howerver, since you are a guest user now, you can not create libraries.{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
<button class="simplemodal-close" style="margin:8px 0 0 0;">{% trans "Close" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- wrapper -->
|
||||
|
||||
{% include 'js/common-templates.html' %}
|
||||
{% include 'js/templates.html' %}
|
||||
<script type="text/javascript">
|
||||
var app = {
|
||||
config: {
|
||||
mediaUrl: '{{ MEDIA_URL }}',
|
||||
siteRoot: '{{ SITE_ROOT }}',
|
||||
loginUrl: '{{ LOGIN_URL }}',
|
||||
csrfCookieName: '{{ CSRF_COOKIE_NAME }}',
|
||||
fileServerRoot: '{{ FILE_SERVER_ROOT }}'
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="{{ STATIC_URL }}scripts/i18n/{{ LANGUAGE_CODE }}/djangojs.js"></script>
|
||||
|
||||
{% block extra_script %}{% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
@ -1,309 +0,0 @@
|
||||
{% extends "base_for_backbone.html" %}
|
||||
{% load seahub_tags avatar_tags group_avatar_tags i18n %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block sub_title %}{% trans "Libraries" %} - {% endblock %}
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
html,body {
|
||||
height:100%;
|
||||
overflow:hidden;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/template" id="my-own-repos-tmpl">
|
||||
<div class="cur-view-main"> {# .cur-view-main is only for view with side panel #}
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "My Libraries" %}</h3>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<table class="hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "You have not created any libraries" %}</h2>
|
||||
<p>{% trans "You can create a library to organize your files. For example, you can create one for each of your projects. Each library can be synchronized and shared separately." %}</p>
|
||||
</div>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<p class="error error-tip hide"></p>
|
||||
</div>
|
||||
</div>
|
||||
{# <div class="cur-view-side"></div> #}
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="my-deleted-repos-tmpl">
|
||||
<div class="cur-view-path cur-view-path-path">
|
||||
<a href="#my-libs/" class="normal">{% trans "My Libraries" %}</a>
|
||||
<span class="path-split">/</span>
|
||||
<span>{% trans "Deleted Libraries" %}</span>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<p class="tip">{% blocktrans %}Tip: libraries deleted {{ trash_repos_expire_days }} days ago will be cleaned automatically.{% endblocktrans %}</p>
|
||||
<table class="my-deleted-repos-table hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "No deleted libraries." %}</h2>
|
||||
</div>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<p class="error error-tip hide"></p>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/template" id="repos-shared-to-me-tmpl">
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "Shared with me" %}</h3>
|
||||
</div>
|
||||
|
||||
<div class="cur-view-main-con">
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<table class="hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "No libraries have been shared with you" %}</h2>
|
||||
<p>{% blocktrans %}No libraries have been shared directly with you. You can find more shared libraries at "Shared with groups".{% endblocktrans %}</p>
|
||||
</div>
|
||||
<p class="error error-tip hide"></p>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="organization-repos-tmpl">
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "Shared with all" %}</h3>
|
||||
</div>
|
||||
|
||||
<div class="cur-view-main-con">
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<table class="repo-list hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "No public libraries" %}</h2>
|
||||
<p>{% blocktrans %}You can create a public library by clicking the "New Library" button, others can view and download this library.{% endblocktrans %}</p>
|
||||
</div>
|
||||
<p class="error error-tip hide"></p>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="groups-tmpl">
|
||||
<div class="cur-view-main">
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "My Groups" %}</h3>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<div id="group-list" class="hide"></div>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "You are not in any groups" %}</h2>
|
||||
{% if user.permissions.can_add_group %}
|
||||
<p>{% blocktrans %}Groups allow multiple people to collaborate on libraries. You can create a group by clicking the "New Group" button.{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
<p>{% trans "Groups allow multiple people to collaborate on libraries. Groups you join will be listed here." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<p class="error error-tip hide"></p>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="group-tmpl">
|
||||
<div class="cur-view-main">
|
||||
<div class="cur-view-path" id="group-path">
|
||||
<div class="group-path cur-view-path-path">
|
||||
</div>
|
||||
<div class="group-toolbar-2">
|
||||
</div>
|
||||
</div>
|
||||
<div class="cur-view-main-con" id="group-repos">
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<table class="hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="empty-tips common-group-empty-tips hide">
|
||||
<h2 class="alc">{% trans "No library is shared to this group" %}</h2>
|
||||
<p>{% blocktrans %}You can share libraries by clicking the "New Library" button above or the "Share" icon on your libraries list.{% endblocktrans %}</p>
|
||||
<p>{% trans "Libraries shared as writable can be downloaded and synced by other group members. Read only libraries can only be downloaded, updates by others will not be uploaded." %}</p>
|
||||
</div>
|
||||
<div class="empty-tips address-book-group-empty-tips-for-member hide">
|
||||
<h2 class="alc">{% trans "No libraries" %}</h2>
|
||||
</div>
|
||||
<div class="empty-tips address-book-group-empty-tips-for-admin hide">
|
||||
<h2 class="alc">{% trans "No libraries" %}</h2>
|
||||
<p>{% blocktrans %}You can create libraries by clicking the "New Library" button above.{% endblocktrans %}</p>
|
||||
</div>
|
||||
<p class="error error-tip hide"></p>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="starred-file-tmpl">
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "Favorites" %}</h3>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<table class="hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "You don't have any starred files yet" %}</h2>
|
||||
<p>{% blocktrans %}You can mark files as important by clicking the "Star" button on the file viewing page. Starred files will be listed here.{% endblocktrans %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="activities-tmpl">
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "Activities" %}</h3>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<div id="activities-body" class="hide"></div>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<button id="activities-more" class="full-width-btn hide">{% trans 'More' %}</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="devices-tmpl">
|
||||
<div class="cur-view-path">
|
||||
<h3>{% trans "Linked Devices" %}</h3>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<table class="hide">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="13%">{% trans "Platform" %}</th>
|
||||
<th width="30%">{% trans "Device Name" %}</th>
|
||||
<th width="30%">{% trans "IP" %}</th>
|
||||
<th width="17%">{% trans "Last Access" %}</th>
|
||||
<th width="10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "You do not have connected devices" %}</h2>
|
||||
<p>{% trans "Your clients (Desktop/Android/iOS) will be listed here." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="dir-view-tmpl">
|
||||
<div class="cur-view-main">
|
||||
<div class="cur-view-path" id="dir-view-path">
|
||||
<div class="dir-path cur-view-path-path"></div>
|
||||
<div class="dir-toolbar-2"></div>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<div class="js-dir-content hide">
|
||||
<table class="repo-file-list hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<ul class="grid-view hide">
|
||||
</ul>
|
||||
</div>
|
||||
<p class="error hide"></p>
|
||||
</div>
|
||||
</div>
|
||||
{# <div class="cur-view-side"></div> #}
|
||||
</script>
|
||||
|
||||
{% include "js/lib-op-popups.html" %}
|
||||
|
||||
<script type="text/javascript">
|
||||
app["pageOptions"] = {
|
||||
site_root: "{{ SITE_ROOT }}",
|
||||
csrfToken: "{{ csrf_token }}",
|
||||
groups: (function () {
|
||||
var groups = [];
|
||||
{% for group in joined_groups %}
|
||||
groups.push({'name': '{{group.group_name|escapejs}}', 'id': '{{group.id}}'});
|
||||
{% endfor %}
|
||||
return groups;
|
||||
})(),
|
||||
joined_groups_exclude_address_book: (function () {
|
||||
var groups = [];
|
||||
{% for group in joined_groups_exclude_address_book %}
|
||||
groups.push({'name': '{{group.group_name|escapejs}}', 'id': '{{group.id}}'});
|
||||
{% endfor %}
|
||||
return groups;
|
||||
})(),
|
||||
library_templates: (function () {
|
||||
var templates = [];
|
||||
{% for template in library_templates %}
|
||||
templates.push('{{ template|escapejs }}');
|
||||
{% endfor %}
|
||||
return templates;
|
||||
})(),
|
||||
storages: (function () {
|
||||
var storages = [];
|
||||
{% for storage in storages %}
|
||||
storages.push({'storage_name': '{{storage.storage_name|escapejs}}', 'storage_id': '{{storage.storage_id|escapejs}}'});
|
||||
{% endfor %}
|
||||
return storages;
|
||||
})(),
|
||||
username: "{{request.user.username|escapejs}}",
|
||||
name: "{{request.user.username|email2nickname|escapejs}}",
|
||||
contact_email: "{{ request.user.username|email2contact_email|escapejs }}",
|
||||
events_enabled: {% if events_enabled %} true {% else %} false {% endif %},
|
||||
can_add_repo: {% if user.permissions.can_add_repo %} true {% else %} false {% endif %},
|
||||
can_generate_share_link: {% if user.permissions.can_generate_share_link %} true {% else %} false {% endif %},
|
||||
can_generate_upload_link: {% if user.permissions.can_generate_upload_link %} true {% else %} false {% endif %},
|
||||
is_staff: {% if request.user.is_staff %} true {% else %} false {% endif %},
|
||||
repo_password_min_length: {{ repo_password_min_length }},
|
||||
share_link_password_min_length: {{ share_link_password_min_length }},
|
||||
share_link_expire_days_min: {{ share_link_expire_days_min }},
|
||||
share_link_expire_days_max: {{ share_link_expire_days_max }},
|
||||
share_link_expire_days_default: {{ share_link_expire_days_default }},
|
||||
guide_enabled: {% if guide_enabled %} true {% else %} false {% endif %},
|
||||
enable_wiki: {% if enable_wiki %} true {% else %} false {% endif %},
|
||||
enable_upload_folder: {% if enable_upload_folder %} true {% else %} false {% endif %},
|
||||
enable_resumable_fileupload: {% if enable_resumable_fileupload %} true {% else %} false {% endif %},
|
||||
resumable_upload_file_block_size: {{ resumable_upload_file_block_size }},
|
||||
max_number_of_files_for_fileupload: {{ max_number_of_files_for_fileupload }},
|
||||
enable_thumbnail: {% if enable_thumbnail %} true {% else %} false {% endif %},
|
||||
thumbnail_default_size: {{ thumbnail_default_size }},
|
||||
thumbnail_size_for_grid: {{ thumbnail_size_for_grid }},
|
||||
thumbnail_size_for_original: {{ thumbnail_size_for_original }},
|
||||
language_code: "{{ LANGUAGE_CODE }}",
|
||||
enable_encrypted_library: {% if enable_encrypted_library %} true {% else %} false {% endif %},
|
||||
enable_repo_history_setting: {% if enable_repo_history_setting %} true {% else %} false {% endif %},
|
||||
max_upload_file_size: {% if max_upload_file_size %} {{ max_upload_file_size }} {% else %} '' {% endif %},
|
||||
folder_perm_enabled: {% if folder_perm_enabled %} true {% else %} false {% endif %},
|
||||
is_pro: {% if is_pro %} true {% else %} false {% endif %},
|
||||
file_audit_enabled: {% if file_audit_enabled %} true {% else %} false {% endif %},
|
||||
enable_repo_snapshot_label: {% if enable_repo_snapshot_label %} true {% else %} false {% endif %},
|
||||
unread_notifications_request_interval: {{ unread_notifications_request_interval }},
|
||||
enable_share_to_all_groups: {% if enable_share_to_all_groups %} true {% else %} false {% endif %},
|
||||
cur_note: {% if request.cur_note %} {'id': '{{ request.cur_note.id }}'} {% else %} null {% endif %},
|
||||
enable_group_discussion: {% if enable_group_discussion %} true {% else %} false {% endif %},
|
||||
enable_file_comment: {% if enable_file_comment %} true {% else %} false {% endif %},
|
||||
enable_office_web_app: {% if enable_office_web_app %} true {% else %} false {% endif %},
|
||||
enable_onlyoffice: {% if enable_onlyoffice %} true {% else %} false {% endif %},
|
||||
enable_repo_wiki_mode: {% if enable_repo_wiki_mode %} true {% else %} false {% endif %}
|
||||
};
|
||||
app.ui = {
|
||||
currentDropdown: null,
|
||||
currentPopover: null,
|
||||
currentHighlightedItem: null,
|
||||
freezeItemHightlight: false
|
||||
};
|
||||
</script>
|
||||
{% if debug %}
|
||||
<script data-main="{% static "scripts/main.js" %}" src="{% static "scripts/lib/require.js" %}"></script>
|
||||
{% else %}
|
||||
<script data-main="{% static "scripts/dist/main.js" %}" src="{% static "scripts/lib/require.js" %}"></script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -1,129 +0,0 @@
|
||||
{% load staticfiles i18n %}
|
||||
{% load compress %}
|
||||
{% load seahub_tags avatar_tags group_avatar_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ LANGUAGE_CODE }}">
|
||||
<head>
|
||||
<title>{{ site_title }}</title>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="keywords" content="{% trans "File Collaboration Team Organization" %}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link rel="shortcut icon" href="{{ MEDIA_URL }}{{ favicon_path }}" />
|
||||
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/bootstrap.min.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/select2-3.5.2.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seahub.css?t=1398068110" />
|
||||
<link rel="stylesheet" type="text/css" href="{% static "css/magnific-popup.css" %}" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/sf_font3/iconfont.css" />
|
||||
{% endcompress %}
|
||||
|
||||
{% if branding_css != '' %}<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}{{ branding_css }}" />{% endif %}
|
||||
{% if enable_branding_css %}<link rel="stylesheet" type="text/css" href="{% url 'custom_css' %}" />{% endif %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrapper" role="application" class="{{ LANGUAGE_CODE }} d-flex fd-col h100">
|
||||
{% block info_bar_message %}
|
||||
{% if request.user.is_authenticated and request.cur_note %}
|
||||
<div id="info-bar">
|
||||
<p id="info-bar-info">{{ request.cur_note.message|urlize|url_target_blank }}</p>
|
||||
<span class="close sf2-icon-x1 op-icon" title="{% trans "Close" %}"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock info_bar_message %}
|
||||
|
||||
<div id="header" role="banner" class="d-flex">
|
||||
<a href="{{ SITE_ROOT }}" id="logo" class="hidden-sm-down">
|
||||
<img src="{{ MEDIA_URL }}{{ logo_path }}" title="{{ site_title }}" alt="logo" width="{{logo_width}}" height="{{logo_height}}" />
|
||||
</a>
|
||||
<span class="sf2-icon-menu side-nav-toggle hidden-md-up" title="{% trans "Side Nav Menu" %}" id="js-toggle-side-nav" aria-label="{% trans "Side Nav Menu" %}"></span>
|
||||
|
||||
<div id="account">
|
||||
<a id="my-info" href="#" class="account-toggle no-deco hidden-sm-down" aria-label="{% trans "View profile and more" %}">
|
||||
{% avatar request.user 32 %} <span class="icon-caret-down vam"></span>
|
||||
</a>
|
||||
<span class="account-toggle sf2-icon-more mobile-icon hidden-md-up" aria-label="{% trans "View profile and more" %}"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main" class="container-fluid w100 flex-auto ovhd d-flex">
|
||||
<span class="loading-icon loading-tip" id="initial-loading"></span>
|
||||
<div class="row flex-1 d-flex hide">
|
||||
<div class="side-nav side-tabnav col-md-3" id="side-nav" role="navigation"></div>
|
||||
<div id="right-panel" class="col-md-9 ov-auto flex-1">
|
||||
{% block right_panel %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="confirm-popup" class="hide">
|
||||
<div id="confirm-con"></div>
|
||||
<button id="confirm-yes">{% trans "Yes"%}</button>
|
||||
<button class="simplemodal-close">{% trans "No"%}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- wrapper -->
|
||||
|
||||
{% include 'js/common-templates.html' %}
|
||||
{% include 'js/sysadmin-templates.html' %}
|
||||
{% include 'js/admin-common-templates.html' %} {# for sys admin & org admin #}
|
||||
{% include 'js/lib-op-popups.html' %}
|
||||
|
||||
<script type="text/javascript">
|
||||
var app = {
|
||||
config: {
|
||||
mediaUrl: '{{ MEDIA_URL }}',
|
||||
siteRoot: '{{ SITE_ROOT }}',
|
||||
loginUrl: '{{ LOGIN_URL }}',
|
||||
csrfCookieName: '{{ CSRF_COOKIE_NAME }}'
|
||||
}
|
||||
};
|
||||
app["pageOptions"] = {
|
||||
csrfToken: "{{ csrf_token }}",
|
||||
email: "{{request.user.username}}",
|
||||
name: "{{request.user.username|email2nickname|escapejs}}",
|
||||
contact_email: "{{request.user.username|email2contact_email|escapejs}}",
|
||||
language_code: "{{ LANGUAGE_CODE }}",
|
||||
events_enabled: {% if events_enabled %} true {% else %} false {% endif %},
|
||||
repo_password_min_length: {{ repo_password_min_length }},
|
||||
share_link_password_min_length: {{ share_link_password_min_length }},
|
||||
enable_upload_folder: {% if enable_upload_folder %} true {% else %} false {% endif %},
|
||||
enable_resumable_fileupload: {% if enable_resumable_fileupload %} true {% else %} false {% endif %},
|
||||
max_number_of_files_for_fileupload: {{ max_number_of_files_for_fileupload }},
|
||||
thumbnail_default_size: {{ thumbnail_default_size }},
|
||||
thumbnail_size_for_grid: {{ thumbnail_size_for_grid }},
|
||||
enable_encrypted_library: {% if enable_encrypted_library %} true {% else %} false {% endif %},
|
||||
enable_repo_history_setting: {% if enable_repo_history_setting %} true {% else %} false {% endif %},
|
||||
max_upload_file_size: {% if max_upload_file_size %} {{ max_upload_file_size }} {% else %} '' {% endif %},
|
||||
folder_perm_enabled: {% if folder_perm_enabled %} true {% else %} false {% endif %},
|
||||
is_pro: {% if is_pro %} true {% else %} false {% endif %},
|
||||
enable_sys_admin_view_repo: {% if enable_sys_admin_view_repo %} true {% else %} false {% endif %},
|
||||
file_audit_enabled: {% if file_audit_enabled %} true {% else %} false {% endif %},
|
||||
cur_note: {% if request.cur_note %} {'id': '{{ request.cur_note.id }}'} {% else %} null {% endif %},
|
||||
is_default_admin: {% if is_default_admin %} true {% else %} false {% endif %},
|
||||
enable_file_scan: {% if enable_file_scan %} true {% else %} false {% endif %},
|
||||
enable_work_weixin: {% if enable_work_weixin %} true {% else %} false {% endif %},
|
||||
admin_permissions: {
|
||||
"can_view_system_info": {% if user.admin_permissions.can_view_system_info %} true {% else %} false {% endif %},
|
||||
"can_view_statistic": {% if user.admin_permissions.can_view_statistic %} true {% else %} false {% endif %},
|
||||
"can_config_system": {% if user.admin_permissions.can_config_system %} true {% else %} false {% endif %},
|
||||
"can_manage_library": {% if user.admin_permissions.can_manage_library %} true {% else %} false {% endif %},
|
||||
"can_manage_user": {% if user.admin_permissions.can_manage_user %} true {% else %} false {% endif %},
|
||||
"can_manage_group": {% if user.admin_permissions.can_manage_group %} true {% else %} false {% endif %},
|
||||
"can_view_user_log": {% if user.admin_permissions.can_view_user_log %} true {% else %} false {% endif %},
|
||||
"can_view_admin_log": {% if user.admin_permissions.can_view_admin_log %} true {% else %} false {% endif %}
|
||||
},
|
||||
enable_limit_ipaddress: {% if enable_limit_ipaddress %} true {% else %} false {% endif %}
|
||||
};
|
||||
</script>
|
||||
<script src="{{ STATIC_URL }}scripts/i18n/{{ LANGUAGE_CODE }}/djangojs.js"></script>
|
||||
{% if debug %}
|
||||
<script data-main="{% static "scripts/sysadmin-main.js" %}" src="{% static "scripts/lib/require.js" %}"></script>
|
||||
{% else %}
|
||||
<script data-main="{% static "scripts/dist/sysadmin-main.js" %}" src="{% static "scripts/lib/require.js" %}"></script>
|
||||
{% endif %}
|
||||
|
||||
</body>
|
||||
</html>
|
@ -172,7 +172,7 @@ urlpatterns = [
|
||||
url(r'^shib-login/', shib_login, name="shib_login"),
|
||||
url(r'^oauth/', include('seahub.oauth.urls')),
|
||||
|
||||
url(r'^$', libraries, name='libraries'),
|
||||
url(r'^$', react_fake_view, name='libraries'),
|
||||
#url(r'^home/$', direct_to_template, { 'template': 'home.html' } ),
|
||||
url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
|
||||
|
||||
@ -201,12 +201,6 @@ urlpatterns = [
|
||||
url(r'^lib/(?P<repo_id>[-0-9a-f]{36})/file(?P<path>.*)$', view_lib_file, name='view_lib_file'),
|
||||
url(r'^wiki/lib/(?P<repo_id>[-0-9a-f]{36})/(?P<path>.*)$', view_lib_as_wiki, name='view_lib_as_wiki'),
|
||||
url(r'^smart-link/(?P<dirent_uuid>[-0-9a-f]{36})/(?P<dirent_name>.*)$', view_lib_file_via_smart_link, name="view_lib_file_via_smart_link"),
|
||||
url(r'^#common/lib/(?P<repo_id>[-0-9a-f]{36})/(?P<path>.*)$', fake_view, name='view_common_lib_dir'),
|
||||
url(r'^#group/(?P<group_id>\d+)/$', fake_view, name='group_info'),
|
||||
url(r'^#group/(?P<group_id>\d+)/members/$', fake_view, name='group_members'),
|
||||
url(r'^#group/(?P<group_id>\d+)/discussions/$', fake_view, name='group_discuss'),
|
||||
url(r'^#groups/', fake_view, name='group_list'),
|
||||
url(r'^#group/(?P<group_id>\d+)/settings/$', fake_view, name='group_manage'),
|
||||
|
||||
### share/upload link ###
|
||||
url(r'^f/(?P<token>[a-f0-9]+)/$', view_shared_file, name='view_shared_file'),
|
||||
@ -633,7 +627,6 @@ urlpatterns = [
|
||||
url(r'^api/v2.1/admin/work-weixin/departments/import/$', AdminWorkWeixinDepartmentsImport.as_view(), name='api-v2.1-admin-work-weixin-department-import'),
|
||||
|
||||
### system admin ###
|
||||
url(r'^sysadmin/$', sysadmin, name='sysadmin'),
|
||||
url(r'^sys/settings/$', sys_settings, name='sys_settings'),
|
||||
url(r'^sys/statistic/file/$', sys_statistic_file, name='sys_statistic_file'),
|
||||
url(r'^sys/statistic/storage/$', sys_statistic_storage, name='sys_statistic_storage'),
|
||||
@ -641,13 +634,6 @@ urlpatterns = [
|
||||
url(r'^sys/statistic/traffic/$', sys_statistic_traffic, name='sys_statistic_traffic'),
|
||||
url(r'^sys/statistic/reports/$', sys_statistic_reports, name='sys_statistic_reports'),
|
||||
|
||||
url(r'^sysadmin/#all-libs/$', fake_view, name='sys_repo_admin'),
|
||||
url(r'^sysadmin/#libs/(?P<repo_id>[-0-9a-f]{36})/$', fake_view, name='sys_admin_repo'),
|
||||
url(r'^sysadmin/#system-lib/$', fake_view, name='sys_list_system'),
|
||||
url(r'^sysadmin/#trash-libs/$', fake_view, name='sys_repo_trash'),
|
||||
url(r'^sysadmin/#search-libs/$', fake_view, name='sys_repo_search'),
|
||||
url(r'^sysadmin/#search-trash-libs/$', fake_view, name='sys_trash_repo_search'),
|
||||
url(r'^sysadmin/#search-groups/$', fake_view, name='sys_group_search'),
|
||||
url(r'^sys/seafadmin/delete/(?P<repo_id>[-0-9a-f]{36})/$', sys_repo_delete, name='sys_repo_delete'),
|
||||
url(r'^sys/useradmin/$', sys_user_admin, name='sys_useradmin'),
|
||||
url(r'^sys/useradmin/export-excel/$', sys_useradmin_export_excel, name='sys_useradmin_export_excel'),
|
||||
|
@ -691,92 +691,6 @@ def get_owned_repo_list(request):
|
||||
else:
|
||||
return seafile_api.get_owned_repo_list(username)
|
||||
|
||||
@login_required
|
||||
def libraries(request):
|
||||
"""
|
||||
New URL to replace myhome
|
||||
"""
|
||||
username = request.user.username
|
||||
|
||||
# options
|
||||
if request.cloud_mode and request.user.org is None:
|
||||
allow_public_share = False
|
||||
else:
|
||||
allow_public_share = True
|
||||
sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
|
||||
max_upload_file_size = get_max_upload_file_size()
|
||||
guide_enabled = UserOptions.objects.is_user_guide_enabled(username)
|
||||
if guide_enabled:
|
||||
create_default_library(request)
|
||||
|
||||
folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
|
||||
|
||||
if request.cloud_mode and request.user.org is not None:
|
||||
org_id = request.user.org.org_id
|
||||
joined_groups = seaserv.get_org_groups_by_user(org_id, username)
|
||||
else:
|
||||
joined_groups = ccnet_api.get_groups(username, return_ancestors=True)
|
||||
|
||||
if joined_groups:
|
||||
try:
|
||||
joined_groups.sort(key=lambda x: x.group_name.lower())
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
joined_groups = []
|
||||
|
||||
joined_groups_exclude_address_book = [item for item in joined_groups if
|
||||
item.parent_group_id == 0]
|
||||
|
||||
try:
|
||||
expire_days = seafile_api.get_server_config_int('library_trash', 'expire_days')
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
expire_days = -1
|
||||
|
||||
# Whether use new index page
|
||||
use_new_page = True
|
||||
if request.GET.get('_old', None):
|
||||
use_new_page = False
|
||||
|
||||
if use_new_page:
|
||||
return react_fake_view(request)
|
||||
|
||||
return render(request, 'libraries.html', {
|
||||
"allow_public_share": allow_public_share,
|
||||
"guide_enabled": guide_enabled,
|
||||
"sub_lib_enabled": sub_lib_enabled,
|
||||
'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
|
||||
'enable_resumable_fileupload': settings.ENABLE_RESUMABLE_FILEUPLOAD,
|
||||
'resumable_upload_file_block_size': settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE,
|
||||
'max_number_of_files_for_fileupload': settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD,
|
||||
'enable_thumbnail': settings.ENABLE_THUMBNAIL,
|
||||
'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,
|
||||
'thumbnail_default_size': settings.THUMBNAIL_DEFAULT_SIZE,
|
||||
'thumbnail_size_for_grid': settings.THUMBNAIL_SIZE_FOR_GRID,
|
||||
'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
|
||||
'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
|
||||
'max_upload_file_size': max_upload_file_size,
|
||||
'folder_perm_enabled': folder_perm_enabled,
|
||||
'is_pro': True if is_pro_version() else False,
|
||||
'file_audit_enabled': FILE_AUDIT_ENABLED,
|
||||
'can_add_public_repo': request.user.permissions.can_add_public_repo(),
|
||||
'joined_groups': joined_groups,
|
||||
'joined_groups_exclude_address_book': joined_groups_exclude_address_book,
|
||||
'storages': get_library_storages(request),
|
||||
'unread_notifications_request_interval': UNREAD_NOTIFICATIONS_REQUEST_INTERVAL,
|
||||
'library_templates': list(LIBRARY_TEMPLATES.keys()) if \
|
||||
isinstance(LIBRARY_TEMPLATES, dict) else [],
|
||||
'enable_share_to_all_groups': config.ENABLE_SHARE_TO_ALL_GROUPS,
|
||||
'enable_group_discussion': settings.ENABLE_GROUP_DISCUSSION,
|
||||
'enable_file_comment': settings.ENABLE_FILE_COMMENT,
|
||||
'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
|
||||
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
|
||||
'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT,
|
||||
'enable_office_web_app': ENABLE_OFFICE_WEB_APP,
|
||||
'enable_onlyoffice': ENABLE_ONLYOFFICE,
|
||||
'trash_repos_expire_days': expire_days if expire_days > 0 else 30,
|
||||
})
|
||||
|
||||
@login_required
|
||||
def repo_set_access_property(request, repo_id):
|
||||
ap = request.GET.get('ap', '')
|
||||
@ -1177,15 +1091,6 @@ def underscore_template(request, template):
|
||||
|
||||
return render(request, template, {})
|
||||
|
||||
def fake_view(request, **kwargs):
|
||||
"""
|
||||
Used for 'view_common_lib_dir' and some other urls
|
||||
|
||||
As the urls start with '#',
|
||||
http request will not access this function
|
||||
"""
|
||||
return HttpResponse()
|
||||
|
||||
def client_token_login(request):
|
||||
"""Login from desktop client with a generated token.
|
||||
"""
|
||||
|
@ -104,40 +104,6 @@ from seahub.work_weixin.settings import ENABLE_WORK_WEIXIN
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@login_required
|
||||
@sys_staff_required
|
||||
def sysadmin(request):
|
||||
max_upload_file_size = get_max_upload_file_size()
|
||||
|
||||
folder_perm_enabled = True if is_pro_version() and settings.ENABLE_FOLDER_PERM else False
|
||||
|
||||
try:
|
||||
expire_days = seafile_api.get_server_config_int('library_trash', 'expire_days')
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
expire_days = -1
|
||||
|
||||
return render(request, 'sysadmin/sysadmin_backbone.html', {
|
||||
'enable_sys_admin_view_repo': ENABLE_SYS_ADMIN_VIEW_REPO,
|
||||
'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
|
||||
'enable_resumable_fileupload': settings.ENABLE_RESUMABLE_FILEUPLOAD,
|
||||
'max_number_of_files_for_fileupload': settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD,
|
||||
'enable_thumbnail': settings.ENABLE_THUMBNAIL,
|
||||
'thumbnail_default_size': settings.THUMBNAIL_DEFAULT_SIZE,
|
||||
'thumbnail_size_for_grid': settings.THUMBNAIL_SIZE_FOR_GRID,
|
||||
'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
|
||||
'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
|
||||
'max_upload_file_size': max_upload_file_size,
|
||||
'folder_perm_enabled': folder_perm_enabled,
|
||||
'is_pro': True if is_pro_version() else False,
|
||||
'file_audit_enabled': FILE_AUDIT_ENABLED,
|
||||
'enable_limit_ipaddress': ENABLE_LIMIT_IPADDRESS,
|
||||
'trash_repos_expire_days': expire_days if expire_days > 0 else 30,
|
||||
'enable_file_scan': ENABLE_FILE_SCAN,
|
||||
'enable_work_weixin': ENABLE_WORK_WEIXIN,
|
||||
'enable_share_link_report_abuse': ENABLE_SHARE_LINK_REPORT_ABUSE,
|
||||
})
|
||||
|
||||
@login_required
|
||||
@sys_staff_required
|
||||
def sysadmin_react_fake_view(request, **kwargs):
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
175
static/scripts/lib/jquery.fileupload-process.js
vendored
175
static/scripts/lib/jquery.fileupload-process.js
vendored
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* jQuery File Upload Processing Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2012, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'./jquery.fileupload'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery
|
||||
);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
var originalAdd = $.blueimp.fileupload.prototype.options.add;
|
||||
|
||||
// The File Upload Processing plugin extends the fileupload widget
|
||||
// with file processing functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// The list of processing actions:
|
||||
processQueue: [
|
||||
/*
|
||||
{
|
||||
action: 'log',
|
||||
type: 'debug'
|
||||
}
|
||||
*/
|
||||
],
|
||||
add: function (e, data) {
|
||||
var $this = $(this);
|
||||
data.process(function () {
|
||||
return $this.fileupload('process', data);
|
||||
});
|
||||
originalAdd.call(this, e, data);
|
||||
}
|
||||
},
|
||||
|
||||
processActions: {
|
||||
/*
|
||||
log: function (data, options) {
|
||||
console[options.type](
|
||||
'Processing "' + data.files[data.index].name + '"'
|
||||
);
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
_processFile: function (data, originalData) {
|
||||
var that = this,
|
||||
dfd = $.Deferred().resolveWith(that, [data]),
|
||||
chain = dfd.promise();
|
||||
this._trigger('process', null, data);
|
||||
$.each(data.processQueue, function (i, settings) {
|
||||
var func = function (data) {
|
||||
if (originalData.errorThrown) {
|
||||
return $.Deferred()
|
||||
.rejectWith(that, [originalData]).promise();
|
||||
}
|
||||
return that.processActions[settings.action].call(
|
||||
that,
|
||||
data,
|
||||
settings
|
||||
);
|
||||
};
|
||||
chain = chain.then(func, settings.always && func);
|
||||
});
|
||||
chain
|
||||
.done(function () {
|
||||
that._trigger('processdone', null, data);
|
||||
that._trigger('processalways', null, data);
|
||||
})
|
||||
.fail(function () {
|
||||
that._trigger('processfail', null, data);
|
||||
that._trigger('processalways', null, data);
|
||||
});
|
||||
return chain;
|
||||
},
|
||||
|
||||
// Replaces the settings of each processQueue item that
|
||||
// are strings starting with an "@", using the remaining
|
||||
// substring as key for the option map,
|
||||
// e.g. "@autoUpload" is replaced with options.autoUpload:
|
||||
_transformProcessQueue: function (options) {
|
||||
var processQueue = [];
|
||||
$.each(options.processQueue, function () {
|
||||
var settings = {},
|
||||
action = this.action,
|
||||
prefix = this.prefix === true ? action : this.prefix;
|
||||
$.each(this, function (key, value) {
|
||||
if ($.type(value) === 'string' &&
|
||||
value.charAt(0) === '@') {
|
||||
settings[key] = options[
|
||||
value.slice(1) || (prefix ? prefix +
|
||||
key.charAt(0).toUpperCase() + key.slice(1) : key)
|
||||
];
|
||||
} else {
|
||||
settings[key] = value;
|
||||
}
|
||||
|
||||
});
|
||||
processQueue.push(settings);
|
||||
});
|
||||
options.processQueue = processQueue;
|
||||
},
|
||||
|
||||
// Returns the number of files currently in the processsing queue:
|
||||
processing: function () {
|
||||
return this._processing;
|
||||
},
|
||||
|
||||
// Processes the files given as files property of the data parameter,
|
||||
// returns a Promise object that allows to bind callbacks:
|
||||
process: function (data) {
|
||||
var that = this,
|
||||
options = $.extend({}, this.options, data);
|
||||
if (options.processQueue && options.processQueue.length) {
|
||||
this._transformProcessQueue(options);
|
||||
if (this._processing === 0) {
|
||||
this._trigger('processstart');
|
||||
}
|
||||
$.each(data.files, function (index) {
|
||||
var opts = index ? $.extend({}, options) : options,
|
||||
func = function () {
|
||||
if (data.errorThrown) {
|
||||
return $.Deferred()
|
||||
.rejectWith(that, [data]).promise();
|
||||
}
|
||||
return that._processFile(opts, data);
|
||||
};
|
||||
opts.index = index;
|
||||
that._processing += 1;
|
||||
that._processingQueue = that._processingQueue.then(func, func)
|
||||
.always(function () {
|
||||
that._processing -= 1;
|
||||
if (that._processing === 0) {
|
||||
that._trigger('processstop');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return this._processingQueue;
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._processing = 0;
|
||||
this._processingQueue = $.Deferred().resolveWith(this)
|
||||
.promise();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
710
static/scripts/lib/jquery.fileupload-ui.js
vendored
710
static/scripts/lib/jquery.fileupload-ui.js
vendored
@ -1,710 +0,0 @@
|
||||
/*
|
||||
* jQuery File Upload User Interface Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'tmpl',
|
||||
//'./jquery.fileupload-image',
|
||||
//'./jquery.fileupload-audio',
|
||||
//'./jquery.fileupload-video',
|
||||
'./jquery.fileupload-validate'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('tmpl')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.tmpl
|
||||
);
|
||||
}
|
||||
}(function ($, tmpl) {
|
||||
'use strict';
|
||||
|
||||
$.blueimp.fileupload.prototype._specialOptions.push(
|
||||
'filesContainer',
|
||||
'uploadTemplateId',
|
||||
'downloadTemplateId'
|
||||
);
|
||||
|
||||
// The UI version extends the file upload widget
|
||||
// and adds complete user interface interaction:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// By default, files added to the widget are uploaded as soon
|
||||
// as the user clicks on the start buttons. To enable automatic
|
||||
// uploads, set the following option to true:
|
||||
autoUpload: false,
|
||||
// The ID of the upload template:
|
||||
uploadTemplateId: 'template-upload',
|
||||
// The ID of the download template:
|
||||
downloadTemplateId: 'template-download',
|
||||
// The container for the list of files. If undefined, it is set to
|
||||
// an element with class "files" inside of the widget element:
|
||||
filesContainer: undefined,
|
||||
// By default, files are appended to the files container.
|
||||
// Set the following option to true, to prepend files instead:
|
||||
prependFiles: false,
|
||||
// The expected data type of the upload response, sets the dataType
|
||||
// option of the $.ajax upload requests:
|
||||
dataType: 'json',
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
unknownError: 'Unknown error'
|
||||
},
|
||||
|
||||
// Function returning the current number of files,
|
||||
// used by the maxNumberOfFiles validation:
|
||||
getNumberOfFiles: function () {
|
||||
return this.filesContainer.children()
|
||||
.not('.processing').length;
|
||||
},
|
||||
|
||||
// Callback to retrieve the list of files from the server response:
|
||||
getFilesFromResponse: function (data) {
|
||||
if (data.result && $.isArray(data.result.files)) {
|
||||
return data.result.files;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
// The add callback is invoked as soon as files are added to the fileupload
|
||||
// widget (via file input selection, drag & drop or add API call).
|
||||
// See the basic file upload widget for more information:
|
||||
add: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
that = $this.data('blueimp-fileupload') ||
|
||||
$this.data('fileupload'),
|
||||
options = that.options;
|
||||
data.context = that._renderUpload(data.files)
|
||||
.data('data', data)
|
||||
.addClass('processing');
|
||||
options.filesContainer[
|
||||
options.prependFiles ? 'prepend' : 'append'
|
||||
](data.context);
|
||||
that._forceReflow(data.context);
|
||||
that._transition(data.context);
|
||||
data.process(function () {
|
||||
return $this.fileupload('process', data);
|
||||
}).always(function () {
|
||||
data.context.each(function (index) {
|
||||
$(this).find('.size').text(
|
||||
that._formatFileSize(data.files[index].size)
|
||||
);
|
||||
}).removeClass('processing');
|
||||
that._renderPreviews(data);
|
||||
}).done(function () {
|
||||
data.context.find('.start').prop('disabled', false);
|
||||
if ((that._trigger('added', e, data) !== false) &&
|
||||
(options.autoUpload || data.autoUpload) &&
|
||||
data.autoUpload !== false) {
|
||||
data.submit();
|
||||
}
|
||||
}).fail(function () {
|
||||
if (data.files.error) {
|
||||
data.context.each(function (index) {
|
||||
var error = data.files[index].error;
|
||||
if (error) {
|
||||
$(this).find('.error').text(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// Callback for the start of each file upload request:
|
||||
send: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload');
|
||||
if (data.context && data.dataType &&
|
||||
data.dataType.substr(0, 6) === 'iframe') {
|
||||
// Iframe Transport does not support progress events.
|
||||
// In lack of an indeterminate progress bar, we set
|
||||
// the progress to 100%, showing the full animated bar:
|
||||
data.context
|
||||
.find('.progress').addClass(
|
||||
!$.support.transition && 'progress-animated'
|
||||
)
|
||||
.attr('aria-valuenow', 100)
|
||||
.children().first().css(
|
||||
'width',
|
||||
'100%'
|
||||
);
|
||||
}
|
||||
return that._trigger('sent', e, data);
|
||||
},
|
||||
// Callback for successful uploads:
|
||||
done: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
getFilesFromResponse = data.getFilesFromResponse ||
|
||||
that.options.getFilesFromResponse,
|
||||
files = getFilesFromResponse(data),
|
||||
template,
|
||||
deferred;
|
||||
if (data.context) {
|
||||
data.context.each(function (index) {
|
||||
var file = files[index] ||
|
||||
{error: 'Empty file upload result'};
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file])
|
||||
.replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('completed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
template = that._renderDownload(files)[
|
||||
that.options.prependFiles ? 'prependTo' : 'appendTo'
|
||||
](that.options.filesContainer);
|
||||
that._forceReflow(template);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('completed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
// Callback for failed (abort or error) uploads:
|
||||
fail: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
template,
|
||||
deferred;
|
||||
if (data.context) {
|
||||
data.context.each(function (index) {
|
||||
if (data.errorThrown !== 'abort') {
|
||||
var file = data.files[index];
|
||||
file.error = file.error || data.errorThrown ||
|
||||
data.i18n('unknownError');
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file])
|
||||
.replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
$(this).remove();
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (data.errorThrown !== 'abort') {
|
||||
data.context = that._renderUpload(data.files)[
|
||||
that.options.prependFiles ? 'prependTo' : 'appendTo'
|
||||
](that.options.filesContainer)
|
||||
.data('data', data);
|
||||
that._forceReflow(data.context);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(data.context).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
that._addFinishedDeferreds().resolve();
|
||||
}
|
||||
},
|
||||
// Callback for upload progress events:
|
||||
progress: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var progress = Math.floor(data.loaded / data.total * 100);
|
||||
if (data.context) {
|
||||
data.context.each(function () {
|
||||
$(this).find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children().first().css(
|
||||
'width',
|
||||
progress + '%'
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
// Callback for global upload progress events:
|
||||
progressall: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
progress = Math.floor(data.loaded / data.total * 100),
|
||||
globalProgressNode = $this.find('.fileupload-progress'),
|
||||
extendedProgressNode = globalProgressNode
|
||||
.find('.progress-extended');
|
||||
if (extendedProgressNode.length) {
|
||||
extendedProgressNode.html(
|
||||
($this.data('blueimp-fileupload') || $this.data('fileupload'))
|
||||
._renderExtendedProgress(data)
|
||||
);
|
||||
}
|
||||
globalProgressNode
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children().first().css(
|
||||
'width',
|
||||
progress + '%'
|
||||
);
|
||||
},
|
||||
// Callback for uploads start, equivalent to the global ajaxStart event:
|
||||
start: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload');
|
||||
that._resetFinishedDeferreds();
|
||||
that._transition($(this).find('.fileupload-progress')).done(
|
||||
function () {
|
||||
that._trigger('started', e);
|
||||
}
|
||||
);
|
||||
},
|
||||
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
||||
stop: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
deferred = that._addFinishedDeferreds();
|
||||
$.when.apply($, that._getFinishedDeferreds())
|
||||
.done(function () {
|
||||
that._trigger('stopped', e);
|
||||
});
|
||||
that._transition($(this).find('.fileupload-progress')).done(
|
||||
function () {
|
||||
$(this).find('.progress')
|
||||
.attr('aria-valuenow', '0')
|
||||
.children().first().css('width', '0%');
|
||||
$(this).find('.progress-extended').html(' ');
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
},
|
||||
processstart: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
$(this).addClass('fileupload-processing');
|
||||
},
|
||||
processstop: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
$(this).removeClass('fileupload-processing');
|
||||
},
|
||||
// Callback for file deletion:
|
||||
destroy: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
removeNode = function () {
|
||||
that._transition(data.context).done(
|
||||
function () {
|
||||
$(this).remove();
|
||||
that._trigger('destroyed', e, data);
|
||||
}
|
||||
);
|
||||
};
|
||||
if (data.url) {
|
||||
data.dataType = data.dataType || that.options.dataType;
|
||||
$.ajax(data).done(removeNode).fail(function () {
|
||||
that._trigger('destroyfailed', e, data);
|
||||
});
|
||||
} else {
|
||||
removeNode();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_resetFinishedDeferreds: function () {
|
||||
this._finishedUploads = [];
|
||||
},
|
||||
|
||||
_addFinishedDeferreds: function (deferred) {
|
||||
if (!deferred) {
|
||||
deferred = $.Deferred();
|
||||
}
|
||||
this._finishedUploads.push(deferred);
|
||||
return deferred;
|
||||
},
|
||||
|
||||
_getFinishedDeferreds: function () {
|
||||
return this._finishedUploads;
|
||||
},
|
||||
|
||||
// Link handler, that allows to download files
|
||||
// by drag & drop of the links to the desktop:
|
||||
_enableDragToDesktop: function () {
|
||||
var link = $(this),
|
||||
url = link.prop('href'),
|
||||
name = link.prop('download'),
|
||||
type = 'application/octet-stream';
|
||||
link.bind('dragstart', function (e) {
|
||||
try {
|
||||
e.originalEvent.dataTransfer.setData(
|
||||
'DownloadURL',
|
||||
[type, name, url].join(':')
|
||||
);
|
||||
} catch (ignore) {}
|
||||
});
|
||||
},
|
||||
|
||||
_formatFileSize: function (bytes) {
|
||||
if (typeof bytes !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bytes >= 1000000000) {
|
||||
return (bytes / 1000000000).toFixed(2) + ' GB';
|
||||
}
|
||||
if (bytes >= 1000000) {
|
||||
return (bytes / 1000000).toFixed(2) + ' MB';
|
||||
}
|
||||
return (bytes / 1000).toFixed(2) + ' KB';
|
||||
},
|
||||
|
||||
_formatBitrate: function (bits) {
|
||||
if (typeof bits !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bits >= 1000000000) {
|
||||
return (bits / 1000000000).toFixed(2) + ' Gbit/s';
|
||||
}
|
||||
if (bits >= 1000000) {
|
||||
return (bits / 1000000).toFixed(2) + ' Mbit/s';
|
||||
}
|
||||
if (bits >= 1000) {
|
||||
return (bits / 1000).toFixed(2) + ' kbit/s';
|
||||
}
|
||||
return bits.toFixed(2) + ' bit/s';
|
||||
},
|
||||
|
||||
_formatTime: function (seconds) {
|
||||
var date = new Date(seconds * 1000),
|
||||
days = Math.floor(seconds / 86400);
|
||||
days = days ? days + 'd ' : '';
|
||||
return days +
|
||||
('0' + date.getUTCHours()).slice(-2) + ':' +
|
||||
('0' + date.getUTCMinutes()).slice(-2) + ':' +
|
||||
('0' + date.getUTCSeconds()).slice(-2);
|
||||
},
|
||||
|
||||
_formatPercentage: function (floatValue) {
|
||||
return (floatValue * 100).toFixed(2) + ' %';
|
||||
},
|
||||
|
||||
_renderExtendedProgress: function (data) {
|
||||
return this._formatBitrate(data.bitrate) + ' | ' +
|
||||
this._formatTime(
|
||||
(data.total - data.loaded) * 8 / data.bitrate
|
||||
) + ' | ' +
|
||||
this._formatPercentage(
|
||||
data.loaded / data.total
|
||||
) + ' | ' +
|
||||
this._formatFileSize(data.loaded) + ' / ' +
|
||||
this._formatFileSize(data.total);
|
||||
},
|
||||
|
||||
_renderTemplate: function (func, files) {
|
||||
if (!func) {
|
||||
return $();
|
||||
}
|
||||
var result = func({
|
||||
files: files,
|
||||
formatFileSize: this._formatFileSize,
|
||||
options: this.options
|
||||
});
|
||||
if (result instanceof $) {
|
||||
return result;
|
||||
}
|
||||
return $(this.options.templatesContainer).html(result).children();
|
||||
},
|
||||
|
||||
_renderPreviews: function (data) {
|
||||
data.context.find('.preview').each(function (index, elm) {
|
||||
$(elm).append(data.files[index].preview);
|
||||
});
|
||||
},
|
||||
|
||||
_renderUpload: function (files) {
|
||||
return this._renderTemplate(
|
||||
this.options.uploadTemplate,
|
||||
files
|
||||
);
|
||||
},
|
||||
|
||||
_renderDownload: function (files) {
|
||||
return this._renderTemplate(
|
||||
this.options.downloadTemplate,
|
||||
files
|
||||
).find('a[download]').each(this._enableDragToDesktop).end();
|
||||
},
|
||||
|
||||
_startHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget),
|
||||
template = button.closest('.template-upload'),
|
||||
data = template.data('data');
|
||||
button.prop('disabled', true);
|
||||
if (data && data.submit) {
|
||||
data.submit();
|
||||
}
|
||||
},
|
||||
|
||||
_cancelHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var template = $(e.currentTarget)
|
||||
.closest('.template-upload,.template-download'),
|
||||
data = template.data('data') || {};
|
||||
data.context = data.context || template;
|
||||
if (data.abort) {
|
||||
data.abort();
|
||||
} else {
|
||||
data.errorThrown = 'abort';
|
||||
this._trigger('fail', e, data);
|
||||
}
|
||||
},
|
||||
|
||||
_deleteHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget);
|
||||
this._trigger('destroy', e, $.extend({
|
||||
context: button.closest('.template-download'),
|
||||
type: 'DELETE'
|
||||
}, button.data()));
|
||||
},
|
||||
|
||||
_forceReflow: function (node) {
|
||||
return $.support.transition && node.length &&
|
||||
node[0].offsetWidth;
|
||||
},
|
||||
|
||||
_transition: function (node) {
|
||||
var dfd = $.Deferred();
|
||||
if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
|
||||
node.bind(
|
||||
$.support.transition.end,
|
||||
function (e) {
|
||||
// Make sure we don't respond to other transitions events
|
||||
// in the container element, e.g. from button elements:
|
||||
if (e.target === node[0]) {
|
||||
node.unbind($.support.transition.end);
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
}
|
||||
).toggleClass('in');
|
||||
} else {
|
||||
node.toggleClass('in');
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
return dfd;
|
||||
},
|
||||
|
||||
_initButtonBarEventHandlers: function () {
|
||||
var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
|
||||
filesList = this.options.filesContainer;
|
||||
this._on(fileUploadButtonBar.find('.start'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.start').click();
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.cancel'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.cancel').click();
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.delete'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.toggle:checked')
|
||||
.closest('.template-download')
|
||||
.find('.delete').click();
|
||||
fileUploadButtonBar.find('.toggle')
|
||||
.prop('checked', false);
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.toggle'), {
|
||||
change: function (e) {
|
||||
filesList.find('.toggle').prop(
|
||||
'checked',
|
||||
$(e.currentTarget).is(':checked')
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_destroyButtonBarEventHandlers: function () {
|
||||
this._off(
|
||||
this.element.find('.fileupload-buttonbar')
|
||||
.find('.start, .cancel, .delete'),
|
||||
'click'
|
||||
);
|
||||
this._off(
|
||||
this.element.find('.fileupload-buttonbar .toggle'),
|
||||
'change.'
|
||||
);
|
||||
},
|
||||
|
||||
_initEventHandlers: function () {
|
||||
this._super();
|
||||
this._on(this.options.filesContainer, {
|
||||
'click .start': this._startHandler,
|
||||
'click .cancel': this._cancelHandler,
|
||||
'click .delete': this._deleteHandler
|
||||
});
|
||||
this._initButtonBarEventHandlers();
|
||||
},
|
||||
|
||||
_destroyEventHandlers: function () {
|
||||
this._destroyButtonBarEventHandlers();
|
||||
this._off(this.options.filesContainer, 'click');
|
||||
this._super();
|
||||
},
|
||||
|
||||
_enableFileInputButton: function () {
|
||||
this.element.find('.fileinput-button input')
|
||||
.prop('disabled', false)
|
||||
.parent().removeClass('disabled');
|
||||
},
|
||||
|
||||
_disableFileInputButton: function () {
|
||||
this.element.find('.fileinput-button input')
|
||||
.prop('disabled', true)
|
||||
.parent().addClass('disabled');
|
||||
},
|
||||
|
||||
_initTemplates: function () {
|
||||
var options = this.options;
|
||||
options.templatesContainer = this.document[0].createElement(
|
||||
options.filesContainer.prop('nodeName')
|
||||
);
|
||||
if (tmpl) {
|
||||
if (options.uploadTemplateId) {
|
||||
options.uploadTemplate = tmpl(options.uploadTemplateId);
|
||||
}
|
||||
if (options.downloadTemplateId) {
|
||||
options.downloadTemplate = tmpl(options.downloadTemplateId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_initFilesContainer: function () {
|
||||
var options = this.options;
|
||||
if (options.filesContainer === undefined) {
|
||||
options.filesContainer = this.element.find('.files');
|
||||
} else if (!(options.filesContainer instanceof $)) {
|
||||
options.filesContainer = $(options.filesContainer);
|
||||
}
|
||||
},
|
||||
|
||||
_initSpecialOptions: function () {
|
||||
this._super();
|
||||
this._initFilesContainer();
|
||||
this._initTemplates();
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._resetFinishedDeferreds();
|
||||
if (!$.support.fileInput) {
|
||||
this._disableFileInputButton();
|
||||
}
|
||||
},
|
||||
|
||||
enable: function () {
|
||||
var wasDisabled = false;
|
||||
if (this.options.disabled) {
|
||||
wasDisabled = true;
|
||||
}
|
||||
this._super();
|
||||
if (wasDisabled) {
|
||||
this.element.find('input, button').prop('disabled', false);
|
||||
this._enableFileInputButton();
|
||||
}
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
if (!this.options.disabled) {
|
||||
this.element.find('input, button').prop('disabled', true);
|
||||
this._disableFileInputButton();
|
||||
}
|
||||
this._super();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
122
static/scripts/lib/jquery.fileupload-validate.js
vendored
122
static/scripts/lib/jquery.fileupload-validate.js
vendored
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* jQuery File Upload Validation Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery
|
||||
);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Append to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.push(
|
||||
{
|
||||
action: 'validate',
|
||||
// Always trigger this action,
|
||||
// even if the previous action was rejected:
|
||||
always: true,
|
||||
// Options taken from the global options map:
|
||||
acceptFileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
minFileSize: '@',
|
||||
maxNumberOfFiles: '@',
|
||||
disabled: '@disableValidation'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Validation plugin extends the fileupload widget
|
||||
// with file validation functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
/*
|
||||
// The regular expression for allowed file types, matches
|
||||
// against either file type or file name:
|
||||
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
|
||||
// The maximum allowed file size in bytes:
|
||||
maxFileSize: 10000000, // 10 MB
|
||||
// The minimum allowed file size in bytes:
|
||||
minFileSize: undefined, // No minimal file size
|
||||
// The limit of files to be uploaded:
|
||||
maxNumberOfFiles: 10,
|
||||
*/
|
||||
|
||||
// Function returning the current number of files,
|
||||
// has to be overriden for maxNumberOfFiles validation:
|
||||
getNumberOfFiles: $.noop,
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
maxNumberOfFiles: 'Maximum number of files exceeded',
|
||||
acceptFileTypes: 'File type not allowed',
|
||||
maxFileSize: 'File is too large',
|
||||
minFileSize: 'File is too small'
|
||||
}
|
||||
},
|
||||
|
||||
processActions: {
|
||||
|
||||
validate: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var dfd = $.Deferred(),
|
||||
settings = this.options,
|
||||
file = data.files[data.index],
|
||||
fileSize;
|
||||
if (options.minFileSize || options.maxFileSize) {
|
||||
fileSize = file.size;
|
||||
}
|
||||
if ($.type(options.maxNumberOfFiles) === 'number' &&
|
||||
(settings.getNumberOfFiles() || 0) + data.files.length >
|
||||
options.maxNumberOfFiles) {
|
||||
file.error = settings.i18n('maxNumberOfFiles');
|
||||
} else if (options.acceptFileTypes &&
|
||||
!(options.acceptFileTypes.test(file.type) ||
|
||||
options.acceptFileTypes.test(file.name))) {
|
||||
file.error = settings.i18n('acceptFileTypes');
|
||||
} else if (fileSize > options.maxFileSize) {
|
||||
file.error = settings.i18n('maxFileSize');
|
||||
} else if ($.type(fileSize) === 'number' &&
|
||||
fileSize < options.minFileSize) {
|
||||
file.error = settings.i18n('minFileSize');
|
||||
} else {
|
||||
delete file.error;
|
||||
}
|
||||
if (file.error || data.files.error) {
|
||||
data.files.error = true;
|
||||
dfd.rejectWith(this, [data]);
|
||||
} else {
|
||||
dfd.resolveWith(this, [data]);
|
||||
}
|
||||
return dfd.promise();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
1477
static/scripts/lib/jquery.fileupload.js
vendored
1477
static/scripts/lib/jquery.fileupload.js
vendored
File diff suppressed because it is too large
Load Diff
@ -1,217 +0,0 @@
|
||||
/*
|
||||
* jQuery Iframe Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window, document */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Helper variable to create unique names for the transport iframes:
|
||||
var counter = 0;
|
||||
|
||||
// The iframe transport accepts four additional options:
|
||||
// options.fileInput: a jQuery collection of file input fields
|
||||
// options.paramName: the parameter name for the file form data,
|
||||
// overrides the name property of the file input field(s),
|
||||
// can be a string or an array of strings.
|
||||
// options.formData: an array of objects with name and value properties,
|
||||
// equivalent to the return data of .serializeArray(), e.g.:
|
||||
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
|
||||
// options.initialIframeSrc: the URL of the initial iframe src,
|
||||
// by default set to "javascript:false;"
|
||||
$.ajaxTransport('iframe', function (options) {
|
||||
if (options.async) {
|
||||
// javascript:false as initial iframe src
|
||||
// prevents warning popups on HTTPS in IE6:
|
||||
/*jshint scripturl: true */
|
||||
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
|
||||
/*jshint scripturl: false */
|
||||
form,
|
||||
iframe,
|
||||
addParamChar;
|
||||
return {
|
||||
send: function (_, completeCallback) {
|
||||
form = $('<form style="display:none;"></form>');
|
||||
form.attr('accept-charset', options.formAcceptCharset);
|
||||
addParamChar = /\?/.test(options.url) ? '&' : '?';
|
||||
// XDomainRequest only supports GET and POST:
|
||||
if (options.type === 'DELETE') {
|
||||
options.url = options.url + addParamChar + '_method=DELETE';
|
||||
options.type = 'POST';
|
||||
} else if (options.type === 'PUT') {
|
||||
options.url = options.url + addParamChar + '_method=PUT';
|
||||
options.type = 'POST';
|
||||
} else if (options.type === 'PATCH') {
|
||||
options.url = options.url + addParamChar + '_method=PATCH';
|
||||
options.type = 'POST';
|
||||
}
|
||||
// IE versions below IE8 cannot set the name property of
|
||||
// elements that have already been added to the DOM,
|
||||
// so we set the name along with the iframe HTML markup:
|
||||
counter += 1;
|
||||
iframe = $(
|
||||
'<iframe src="' + initialIframeSrc +
|
||||
'" name="iframe-transport-' + counter + '"></iframe>'
|
||||
).bind('load', function () {
|
||||
var fileInputClones,
|
||||
paramNames = $.isArray(options.paramName) ?
|
||||
options.paramName : [options.paramName];
|
||||
iframe
|
||||
.unbind('load')
|
||||
.bind('load', function () {
|
||||
var response;
|
||||
// Wrap in a try/catch block to catch exceptions thrown
|
||||
// when trying to access cross-domain iframe contents:
|
||||
try {
|
||||
response = iframe.contents();
|
||||
// Google Chrome and Firefox do not throw an
|
||||
// exception when calling iframe.contents() on
|
||||
// cross-domain requests, so we unify the response:
|
||||
if (!response.length || !response[0].firstChild) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch (e) {
|
||||
response = undefined;
|
||||
}
|
||||
// The complete callback returns the
|
||||
// iframe content document as response object:
|
||||
completeCallback(
|
||||
200,
|
||||
'success',
|
||||
{'iframe': response}
|
||||
);
|
||||
// Fix for IE endless progress bar activity bug
|
||||
// (happens on form submits to iframe targets):
|
||||
$('<iframe src="' + initialIframeSrc + '"></iframe>')
|
||||
.appendTo(form);
|
||||
window.setTimeout(function () {
|
||||
// Removing the form in a setTimeout call
|
||||
// allows Chrome's developer tools to display
|
||||
// the response result
|
||||
form.remove();
|
||||
}, 0);
|
||||
});
|
||||
form
|
||||
.prop('target', iframe.prop('name'))
|
||||
.prop('action', options.url)
|
||||
.prop('method', options.type);
|
||||
if (options.formData) {
|
||||
$.each(options.formData, function (index, field) {
|
||||
$('<input type="hidden"/>')
|
||||
.prop('name', field.name)
|
||||
.val(field.value)
|
||||
.appendTo(form);
|
||||
});
|
||||
}
|
||||
if (options.fileInput && options.fileInput.length &&
|
||||
options.type === 'POST') {
|
||||
fileInputClones = options.fileInput.clone();
|
||||
// Insert a clone for each file input field:
|
||||
options.fileInput.after(function (index) {
|
||||
return fileInputClones[index];
|
||||
});
|
||||
if (options.paramName) {
|
||||
options.fileInput.each(function (index) {
|
||||
$(this).prop(
|
||||
'name',
|
||||
paramNames[index] || options.paramName
|
||||
);
|
||||
});
|
||||
}
|
||||
// Appending the file input fields to the hidden form
|
||||
// removes them from their original location:
|
||||
form
|
||||
.append(options.fileInput)
|
||||
.prop('enctype', 'multipart/form-data')
|
||||
// enctype must be set as encoding for IE:
|
||||
.prop('encoding', 'multipart/form-data');
|
||||
// Remove the HTML5 form attribute from the input(s):
|
||||
options.fileInput.removeAttr('form');
|
||||
}
|
||||
form.submit();
|
||||
// Insert the file input fields at their original location
|
||||
// by replacing the clones with the originals:
|
||||
if (fileInputClones && fileInputClones.length) {
|
||||
options.fileInput.each(function (index, input) {
|
||||
var clone = $(fileInputClones[index]);
|
||||
// Restore the original name and form properties:
|
||||
$(input)
|
||||
.prop('name', clone.prop('name'))
|
||||
.attr('form', clone.attr('form'));
|
||||
clone.replaceWith(input);
|
||||
});
|
||||
}
|
||||
});
|
||||
form.append(iframe).appendTo(document.body);
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
// javascript:false as iframe src aborts the request
|
||||
// and prevents warning popups on HTTPS in IE6.
|
||||
// concat is used to avoid the "Script URL" JSLint error:
|
||||
iframe
|
||||
.unbind('load')
|
||||
.prop('src', initialIframeSrc);
|
||||
}
|
||||
if (form) {
|
||||
form.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// The iframe transport returns the iframe content document as response.
|
||||
// The following adds converters from iframe to text, json, html, xml
|
||||
// and script.
|
||||
// Please note that the Content-Type for JSON responses has to be text/plain
|
||||
// or text/html, if the browser doesn't include application/json in the
|
||||
// Accept header, else IE will show a download dialog.
|
||||
// The Content-Type for XML responses on the other hand has to be always
|
||||
// application/xml or text/xml, so IE properly parses the XML response.
|
||||
// See also
|
||||
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'iframe text': function (iframe) {
|
||||
return iframe && $(iframe[0].body).text();
|
||||
},
|
||||
'iframe json': function (iframe) {
|
||||
return iframe && $.parseJSON($(iframe[0].body).text());
|
||||
},
|
||||
'iframe html': function (iframe) {
|
||||
return iframe && $(iframe[0].body).html();
|
||||
},
|
||||
'iframe xml': function (iframe) {
|
||||
var xmlDoc = iframe && iframe[0];
|
||||
return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
|
||||
$.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
|
||||
$(xmlDoc.body).html());
|
||||
},
|
||||
'iframe script': function (iframe) {
|
||||
return iframe && $.globalEval($(iframe[0].body).text());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}));
|
File diff suppressed because one or more lines are too long
@ -1,165 +0,0 @@
|
||||
/*!
|
||||
* JavaScript Cookie v2.2.0
|
||||
* https://github.com/js-cookie/js-cookie
|
||||
*
|
||||
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
|
||||
* Released under the MIT license
|
||||
*/
|
||||
;(function (factory) {
|
||||
var registeredInModuleLoader = false;
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
registeredInModuleLoader = true;
|
||||
}
|
||||
if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
registeredInModuleLoader = true;
|
||||
}
|
||||
if (!registeredInModuleLoader) {
|
||||
var OldCookies = window.Cookies;
|
||||
var api = window.Cookies = factory();
|
||||
api.noConflict = function () {
|
||||
window.Cookies = OldCookies;
|
||||
return api;
|
||||
};
|
||||
}
|
||||
}(function () {
|
||||
function extend () {
|
||||
var i = 0;
|
||||
var result = {};
|
||||
for (; i < arguments.length; i++) {
|
||||
var attributes = arguments[ i ];
|
||||
for (var key in attributes) {
|
||||
result[key] = attributes[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function init (converter) {
|
||||
function api (key, value, attributes) {
|
||||
var result;
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Write
|
||||
|
||||
if (arguments.length > 1) {
|
||||
attributes = extend({
|
||||
path: '/'
|
||||
}, api.defaults, attributes);
|
||||
|
||||
if (typeof attributes.expires === 'number') {
|
||||
var expires = new Date();
|
||||
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
|
||||
attributes.expires = expires;
|
||||
}
|
||||
|
||||
// We're using "expires" because "max-age" is not supported by IE
|
||||
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
|
||||
|
||||
try {
|
||||
result = JSON.stringify(value);
|
||||
if (/^[\{\[]/.test(result)) {
|
||||
value = result;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (!converter.write) {
|
||||
value = encodeURIComponent(String(value))
|
||||
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
|
||||
} else {
|
||||
value = converter.write(value, key);
|
||||
}
|
||||
|
||||
key = encodeURIComponent(String(key));
|
||||
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
|
||||
key = key.replace(/[\(\)]/g, escape);
|
||||
|
||||
var stringifiedAttributes = '';
|
||||
|
||||
for (var attributeName in attributes) {
|
||||
if (!attributes[attributeName]) {
|
||||
continue;
|
||||
}
|
||||
stringifiedAttributes += '; ' + attributeName;
|
||||
if (attributes[attributeName] === true) {
|
||||
continue;
|
||||
}
|
||||
stringifiedAttributes += '=' + attributes[attributeName];
|
||||
}
|
||||
return (document.cookie = key + '=' + value + stringifiedAttributes);
|
||||
}
|
||||
|
||||
// Read
|
||||
|
||||
if (!key) {
|
||||
result = {};
|
||||
}
|
||||
|
||||
// To prevent the for loop in the first place assign an empty array
|
||||
// in case there are no cookies at all. Also prevents odd result when
|
||||
// calling "get()"
|
||||
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||
var rdecode = /(%[0-9A-Z]{2})+/g;
|
||||
var i = 0;
|
||||
|
||||
for (; i < cookies.length; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
var cookie = parts.slice(1).join('=');
|
||||
|
||||
if (!this.json && cookie.charAt(0) === '"') {
|
||||
cookie = cookie.slice(1, -1);
|
||||
}
|
||||
|
||||
try {
|
||||
var name = parts[0].replace(rdecode, decodeURIComponent);
|
||||
cookie = converter.read ?
|
||||
converter.read(cookie, name) : converter(cookie, name) ||
|
||||
cookie.replace(rdecode, decodeURIComponent);
|
||||
|
||||
if (this.json) {
|
||||
try {
|
||||
cookie = JSON.parse(cookie);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (key === name) {
|
||||
result = cookie;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
result[name] = cookie;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
api.set = api;
|
||||
api.get = function (key) {
|
||||
return api.call(api, key);
|
||||
};
|
||||
api.getJSON = function () {
|
||||
return api.apply({
|
||||
json: true
|
||||
}, [].slice.call(arguments));
|
||||
};
|
||||
api.defaults = {};
|
||||
|
||||
api.remove = function (key, attributes) {
|
||||
api(key, '', extend(attributes, {
|
||||
expires: -1
|
||||
}));
|
||||
};
|
||||
|
||||
api.withConverter = init;
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
return init(function () {});
|
||||
}));
|
File diff suppressed because it is too large
Load Diff
@ -1,391 +0,0 @@
|
||||
/**
|
||||
* @license RequireJS text 2.0.13+ Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/requirejs/text for details
|
||||
*/
|
||||
/*jslint regexp: true */
|
||||
/*global require, XMLHttpRequest, ActiveXObject,
|
||||
define, window, process, Packages,
|
||||
java, location, Components, FileUtils */
|
||||
|
||||
define(['module'], function (module) {
|
||||
'use strict';
|
||||
|
||||
var text, fs, Cc, Ci, xpcIsWindows,
|
||||
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
|
||||
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
|
||||
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
|
||||
hasLocation = typeof location !== 'undefined' && location.href,
|
||||
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
|
||||
defaultHostName = hasLocation && location.hostname,
|
||||
defaultPort = hasLocation && (location.port || undefined),
|
||||
buildMap = {},
|
||||
masterConfig = (module.config && module.config()) || {};
|
||||
|
||||
text = {
|
||||
version: '2.0.13+',
|
||||
|
||||
strip: function (content) {
|
||||
//Strips <?xml ...?> declarations so that external SVG and XML
|
||||
//documents can be added to a document without worry. Also, if the string
|
||||
//is an HTML document, only the part inside the body tag is returned.
|
||||
if (content) {
|
||||
content = content.replace(xmlRegExp, "");
|
||||
var matches = content.match(bodyRegExp);
|
||||
if (matches) {
|
||||
content = matches[1];
|
||||
}
|
||||
} else {
|
||||
content = "";
|
||||
}
|
||||
return content;
|
||||
},
|
||||
|
||||
jsEscape: function (content) {
|
||||
return content.replace(/(['\\])/g, '\\$1')
|
||||
.replace(/[\f]/g, "\\f")
|
||||
.replace(/[\b]/g, "\\b")
|
||||
.replace(/[\n]/g, "\\n")
|
||||
.replace(/[\t]/g, "\\t")
|
||||
.replace(/[\r]/g, "\\r")
|
||||
.replace(/[\u2028]/g, "\\u2028")
|
||||
.replace(/[\u2029]/g, "\\u2029");
|
||||
},
|
||||
|
||||
createXhr: masterConfig.createXhr || function () {
|
||||
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
|
||||
var xhr, i, progId;
|
||||
if (typeof XMLHttpRequest !== "undefined") {
|
||||
return new XMLHttpRequest();
|
||||
} else if (typeof ActiveXObject !== "undefined") {
|
||||
for (i = 0; i < 3; i += 1) {
|
||||
progId = progIds[i];
|
||||
try {
|
||||
xhr = new ActiveXObject(progId);
|
||||
} catch (e) {}
|
||||
|
||||
if (xhr) {
|
||||
progIds = [progId]; // so faster next time
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xhr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a resource name into its component parts. Resource names
|
||||
* look like: module/name.ext!strip, where the !strip part is
|
||||
* optional.
|
||||
* @param {String} name the resource name
|
||||
* @returns {Object} with properties "moduleName", "ext" and "strip"
|
||||
* where strip is a boolean.
|
||||
*/
|
||||
parseName: function (name) {
|
||||
var modName, ext, temp,
|
||||
strip = false,
|
||||
index = name.lastIndexOf("."),
|
||||
isRelative = name.indexOf('./') === 0 ||
|
||||
name.indexOf('../') === 0;
|
||||
|
||||
if (index !== -1 && (!isRelative || index > 1)) {
|
||||
modName = name.substring(0, index);
|
||||
ext = name.substring(index + 1);
|
||||
} else {
|
||||
modName = name;
|
||||
}
|
||||
|
||||
temp = ext || modName;
|
||||
index = temp.indexOf("!");
|
||||
if (index !== -1) {
|
||||
//Pull off the strip arg.
|
||||
strip = temp.substring(index + 1) === "strip";
|
||||
temp = temp.substring(0, index);
|
||||
if (ext) {
|
||||
ext = temp;
|
||||
} else {
|
||||
modName = temp;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
moduleName: modName,
|
||||
ext: ext,
|
||||
strip: strip
|
||||
};
|
||||
},
|
||||
|
||||
xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
|
||||
|
||||
/**
|
||||
* Is an URL on another domain. Only works for browser use, returns
|
||||
* false in non-browser environments. Only used to know if an
|
||||
* optimized .js version of a text resource should be loaded
|
||||
* instead.
|
||||
* @param {String} url
|
||||
* @returns Boolean
|
||||
*/
|
||||
useXhr: function (url, protocol, hostname, port) {
|
||||
var uProtocol, uHostName, uPort,
|
||||
match = text.xdRegExp.exec(url);
|
||||
if (!match) {
|
||||
return true;
|
||||
}
|
||||
uProtocol = match[2];
|
||||
uHostName = match[3];
|
||||
|
||||
uHostName = uHostName.split(':');
|
||||
uPort = uHostName[1];
|
||||
uHostName = uHostName[0];
|
||||
|
||||
return (!uProtocol || uProtocol === protocol) &&
|
||||
(!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
|
||||
((!uPort && !uHostName) || uPort === port);
|
||||
},
|
||||
|
||||
finishLoad: function (name, strip, content, onLoad) {
|
||||
content = strip ? text.strip(content) : content;
|
||||
if (masterConfig.isBuild) {
|
||||
buildMap[name] = content;
|
||||
}
|
||||
onLoad(content);
|
||||
},
|
||||
|
||||
load: function (name, req, onLoad, config) {
|
||||
//Name has format: some.module.filext!strip
|
||||
//The strip part is optional.
|
||||
//if strip is present, then that means only get the string contents
|
||||
//inside a body tag in an HTML string. For XML/SVG content it means
|
||||
//removing the <?xml ...?> declarations so the content can be inserted
|
||||
//into the current doc without problems.
|
||||
|
||||
// Do not bother with the work if a build and text will
|
||||
// not be inlined.
|
||||
if (config && config.isBuild && !config.inlineText) {
|
||||
onLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
masterConfig.isBuild = config && config.isBuild;
|
||||
|
||||
var parsed = text.parseName(name),
|
||||
nonStripName = parsed.moduleName +
|
||||
(parsed.ext ? '.' + parsed.ext : ''),
|
||||
url = req.toUrl(nonStripName),
|
||||
useXhr = (masterConfig.useXhr) ||
|
||||
text.useXhr;
|
||||
|
||||
// Do not load if it is an empty: url
|
||||
if (url.indexOf('empty:') === 0) {
|
||||
onLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
//Load the text. Use XHR if possible and in a browser.
|
||||
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
|
||||
text.get(url, function (content) {
|
||||
text.finishLoad(name, parsed.strip, content, onLoad);
|
||||
}, function (err) {
|
||||
if (onLoad.error) {
|
||||
onLoad.error(err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//Need to fetch the resource across domains. Assume
|
||||
//the resource has been optimized into a JS module. Fetch
|
||||
//by the module name + extension, but do not include the
|
||||
//!strip part to avoid file system issues.
|
||||
req([nonStripName], function (content) {
|
||||
text.finishLoad(parsed.moduleName + '.' + parsed.ext,
|
||||
parsed.strip, content, onLoad);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
write: function (pluginName, moduleName, write, config) {
|
||||
if (buildMap.hasOwnProperty(moduleName)) {
|
||||
var content = text.jsEscape(buildMap[moduleName]);
|
||||
write.asModule(pluginName + "!" + moduleName,
|
||||
"define(function () { return '" +
|
||||
content +
|
||||
"';});\n");
|
||||
}
|
||||
},
|
||||
|
||||
writeFile: function (pluginName, moduleName, req, write, config) {
|
||||
var parsed = text.parseName(moduleName),
|
||||
extPart = parsed.ext ? '.' + parsed.ext : '',
|
||||
nonStripName = parsed.moduleName + extPart,
|
||||
//Use a '.js' file name so that it indicates it is a
|
||||
//script that can be loaded across domains.
|
||||
fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
|
||||
|
||||
//Leverage own load() method to load plugin value, but only
|
||||
//write out values that do not have the strip argument,
|
||||
//to avoid any potential issues with ! in file names.
|
||||
text.load(nonStripName, req, function (value) {
|
||||
//Use own write() method to construct full module value.
|
||||
//But need to create shell that translates writeFile's
|
||||
//write() to the right interface.
|
||||
var textWrite = function (contents) {
|
||||
return write(fileName, contents);
|
||||
};
|
||||
textWrite.asModule = function (moduleName, contents) {
|
||||
return write.asModule(moduleName, fileName, contents);
|
||||
};
|
||||
|
||||
text.write(pluginName, nonStripName, textWrite, config);
|
||||
}, config);
|
||||
}
|
||||
};
|
||||
|
||||
if (masterConfig.env === 'node' || (!masterConfig.env &&
|
||||
typeof process !== "undefined" &&
|
||||
process.versions &&
|
||||
!!process.versions.node &&
|
||||
!process.versions['node-webkit'] &&
|
||||
!process.versions['atom-shell'])) {
|
||||
//Using special require.nodeRequire, something added by r.js.
|
||||
fs = require.nodeRequire('fs');
|
||||
|
||||
text.get = function (url, callback, errback) {
|
||||
try {
|
||||
var file = fs.readFileSync(url, 'utf8');
|
||||
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
|
||||
if (file[0] === '\uFEFF') {
|
||||
file = file.substring(1);
|
||||
}
|
||||
callback(file);
|
||||
} catch (e) {
|
||||
if (errback) {
|
||||
errback(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
|
||||
text.createXhr())) {
|
||||
text.get = function (url, callback, errback, headers) {
|
||||
var xhr = text.createXhr(), header;
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
//Allow plugins direct access to xhr headers
|
||||
if (headers) {
|
||||
for (header in headers) {
|
||||
if (headers.hasOwnProperty(header)) {
|
||||
xhr.setRequestHeader(header.toLowerCase(), headers[header]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Allow overrides specified in config
|
||||
if (masterConfig.onXhr) {
|
||||
masterConfig.onXhr(xhr, url);
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function (evt) {
|
||||
var status, err;
|
||||
//Do not explicitly handle errors, those should be
|
||||
//visible via console output in the browser.
|
||||
if (xhr.readyState === 4) {
|
||||
status = xhr.status || 0;
|
||||
if (status > 399 && status < 600) {
|
||||
//An http 4xx or 5xx error. Signal an error.
|
||||
err = new Error(url + ' HTTP status: ' + status);
|
||||
err.xhr = xhr;
|
||||
if (errback) {
|
||||
errback(err);
|
||||
}
|
||||
} else {
|
||||
callback(xhr.responseText);
|
||||
}
|
||||
|
||||
if (masterConfig.onXhrComplete) {
|
||||
masterConfig.onXhrComplete(xhr, url);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
};
|
||||
} else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
|
||||
typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
|
||||
//Why Java, why is this so awkward?
|
||||
text.get = function (url, callback) {
|
||||
var stringBuffer, line,
|
||||
encoding = "utf-8",
|
||||
file = new java.io.File(url),
|
||||
lineSeparator = java.lang.System.getProperty("line.separator"),
|
||||
input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
|
||||
content = '';
|
||||
try {
|
||||
stringBuffer = new java.lang.StringBuffer();
|
||||
line = input.readLine();
|
||||
|
||||
// Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
|
||||
// http://www.unicode.org/faq/utf_bom.html
|
||||
|
||||
// Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
|
||||
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
|
||||
if (line && line.length() && line.charAt(0) === 0xfeff) {
|
||||
// Eat the BOM, since we've already found the encoding on this file,
|
||||
// and we plan to concatenating this buffer with others; the BOM should
|
||||
// only appear at the top of a file.
|
||||
line = line.substring(1);
|
||||
}
|
||||
|
||||
if (line !== null) {
|
||||
stringBuffer.append(line);
|
||||
}
|
||||
|
||||
while ((line = input.readLine()) !== null) {
|
||||
stringBuffer.append(lineSeparator);
|
||||
stringBuffer.append(line);
|
||||
}
|
||||
//Make sure we return a JavaScript string and not a Java string.
|
||||
content = String(stringBuffer.toString()); //String
|
||||
} finally {
|
||||
input.close();
|
||||
}
|
||||
callback(content);
|
||||
};
|
||||
} else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
|
||||
typeof Components !== 'undefined' && Components.classes &&
|
||||
Components.interfaces)) {
|
||||
//Avert your gaze!
|
||||
Cc = Components.classes;
|
||||
Ci = Components.interfaces;
|
||||
Components.utils['import']('resource://gre/modules/FileUtils.jsm');
|
||||
xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
|
||||
|
||||
text.get = function (url, callback) {
|
||||
var inStream, convertStream, fileObj,
|
||||
readData = {};
|
||||
|
||||
if (xpcIsWindows) {
|
||||
url = url.replace(/\//g, '\\');
|
||||
}
|
||||
|
||||
fileObj = new FileUtils.File(url);
|
||||
|
||||
//XPCOM, you so crazy
|
||||
try {
|
||||
inStream = Cc['@mozilla.org/network/file-input-stream;1']
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
inStream.init(fileObj, 1, 0, false);
|
||||
|
||||
convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
|
||||
.createInstance(Ci.nsIConverterInputStream);
|
||||
convertStream.init(inStream, "utf-8", inStream.available(),
|
||||
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
|
||||
|
||||
convertStream.readString(inStream.available(), readData);
|
||||
convertStream.close();
|
||||
inStream.close();
|
||||
callback(readData.value);
|
||||
} catch (e) {
|
||||
throw new Error((fileObj && fileObj.path || '') + ': ' + e);
|
||||
}
|
||||
};
|
||||
}
|
||||
return text;
|
||||
});
|
2
static/scripts/lib/tmpl.min.js
vendored
2
static/scripts/lib/tmpl.min.js
vendored
@ -1,2 +0,0 @@
|
||||
// tmpl.min.js
|
||||
(function(a){"use strict";var b=function(a,c){var d=/[^\w\-\.:]/.test(a)?new Function(b.arg+",tmpl","var _e=tmpl.encode"+b.helper+",_s='"+a.replace(b.regexp,b.func)+"';return _s;"):b.cache[a]=b.cache[a]||b(b.load(a));return c?d(c,b):function(a){return d(a,b)}};b.cache={},b.load=function(a){return document.getElementById(a).innerHTML},b.regexp=/([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,b.func=function(a,b,c,d,e,f){if(b)return{"\n":"\\n","\r":"\\r","\t":"\\t"," ":" "}[a]||"\\"+a;if(c)return c==="="?"'+_e("+d+")+'":"'+("+d+"||'')+'";if(e)return"';";if(f)return"_s+='"},b.encReg=/[<>&"'\x00]/g,b.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},b.encode=function(a){return String(a||"").replace(b.encReg,function(a){return b.encMap[a]||""})},b.arg="o",b.helper=",print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=tmpl(s,d);}",typeof define=="function"&&define.amd?define(function(){return b}):a.tmpl=b})(this);
|
@ -1,79 +0,0 @@
|
||||
import json
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
import pytest
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
from seahub.options.models import UserOptions
|
||||
from seahub.test_utils import BaseTestCase
|
||||
from mock import patch, MagicMock
|
||||
|
||||
|
||||
class LibrariesTest(BaseTestCase):
|
||||
def setUp(self):
|
||||
self.url = reverse('libraries') + '?_old=1'
|
||||
from constance import config
|
||||
self.config = config
|
||||
|
||||
def test_user_guide(self):
|
||||
self.login_as(self.user)
|
||||
username = self.user.username
|
||||
assert UserOptions.objects.get_default_repo(username) is None
|
||||
assert UserOptions.objects.is_user_guide_enabled(username) is True
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'libraries.html')
|
||||
assert resp.context['guide_enabled'] is True
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
assert resp.context['guide_enabled'] is False
|
||||
|
||||
assert UserOptions.objects.get_default_repo(username) is not None
|
||||
assert UserOptions.objects.is_user_guide_enabled(username) is False
|
||||
|
||||
def test_pub_repo_creation_config(self):
|
||||
self.clear_cache()
|
||||
|
||||
# user
|
||||
self.login_as(self.user)
|
||||
|
||||
# can_add_public_repo
|
||||
with patch('seahub.base.accounts.UserPermissions.can_add_public_repo', MagicMock(return_value=True)):
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_public_repo'] is True
|
||||
|
||||
# can_not_add_public_repo
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_public_repo'] is False
|
||||
|
||||
# logout
|
||||
self.logout()
|
||||
|
||||
# admin
|
||||
self.login_as(self.admin)
|
||||
|
||||
self.config.ENABLE_USER_CREATE_ORG_REPO = 1
|
||||
assert bool(self.config.ENABLE_USER_CREATE_ORG_REPO) is True
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_public_repo'] is True
|
||||
|
||||
self.config.ENABLE_USER_CREATE_ORG_REPO = 0
|
||||
assert bool(self.config.ENABLE_USER_CREATE_ORG_REPO) is False
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_public_repo'] is True
|
||||
|
||||
def test_get_user_joined_groups(self):
|
||||
self.login_as(self.user)
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'libraries.html')
|
||||
assert len(resp.context['joined_groups']) > 0
|
Loading…
Reference in New Issue
Block a user