diff --git a/docs-android/app/app.iml b/docs-android/app/app.iml
index 0df93fa8..22f4bad8 100644
--- a/docs-android/app/app.iml
+++ b/docs-android/app/app.iml
@@ -89,11 +89,11 @@
-
+
@@ -108,18 +108,16 @@
-
+
-
-
-
+
-
+
\ No newline at end of file
diff --git a/docs-android/app/build.gradle b/docs-android/app/build.gradle
index 3c6ad05c..ce706bde 100644
--- a/docs-android/app/build.gradle
+++ b/docs-android/app/build.gradle
@@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.0.0-alpha7'
+ classpath 'com.android.tools.build:gradle:2.0.0-beta3'
}
}
apply plugin: 'com.android.application'
@@ -52,12 +52,11 @@ dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
- compile 'com.loopj.android:android-async-http:1.4.9'
compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5'
- compile 'de.greenrobot:eventbus:2.4.1'
+ compile 'org.greenrobot:eventbus:3.0.0'
compile 'com.shamanland:fab:0.0.6'
compile 'com.squareup.picasso:picasso:2.5.2'
- compile 'com.squareup.okhttp3:okhttp:3.0.1'
- compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.1"
+ compile 'com.squareup.okhttp3:okhttp:3.1.1'
+ compile "com.squareup.okhttp3:okhttp-urlconnection:3.1.1"
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2'
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java
index 6214b2fe..c15d04fc 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java
@@ -1,7 +1,6 @@
package com.sismics.docs.activity;
import android.app.ProgressDialog;
-import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
@@ -25,6 +24,7 @@ import com.sismics.docs.ui.view.DatePickerView;
import com.sismics.docs.ui.view.TagsCompleteTextView;
import com.sismics.docs.util.PreferenceUtil;
+import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -35,8 +35,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import de.greenrobot.event.EventBus;
-
/**
* Document edition activity.
*
@@ -123,7 +121,7 @@ public class DocumentEditActivity extends AppCompatActivity {
} else {
setTitle(R.string.edit_document);
titleEditText.setText(document.optString("title"));
- descriptionEditText.setText(document.optString("description"));
+ descriptionEditText.setText(document.isNull("description") ? "" : document.optString("description"));
datePickerView.setDate(new Date(document.optLong("create_date")));
languageSpinner.setSelection(languageAdapter.getItemPosition(document.optString("language")));
JSONArray documentTags = document.optJSONArray("tags");
@@ -164,13 +162,7 @@ public class DocumentEditActivity extends AppCompatActivity {
// Cancellable progress dialog
final ProgressDialog progressDialog = ProgressDialog.show(this,
getString(R.string.please_wait),
- getString(R.string.document_editing_message), true, true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- DocumentResource.cancel(DocumentEditActivity.this);
- }
- });
+ getString(R.string.document_editing_message), true, true);
// Server callback
HttpCallback callback = new HttpCallback() {
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java
index 8c90f2c5..c5e8d12a 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java
@@ -1,16 +1,13 @@
package com.sismics.docs.activity;
import android.app.AlertDialog;
-import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.ClipData;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
import android.support.v4.app.DialogFragment;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewPager;
@@ -47,15 +44,18 @@ import com.sismics.docs.event.FileDeleteEvent;
import com.sismics.docs.fragment.DocExportPdfFragment;
import com.sismics.docs.fragment.DocShareFragment;
import com.sismics.docs.listener.HttpCallback;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
import com.sismics.docs.model.application.ApplicationContext;
import com.sismics.docs.resource.CommentResource;
import com.sismics.docs.resource.DocumentResource;
import com.sismics.docs.resource.FileResource;
import com.sismics.docs.service.FileUploadService;
+import com.sismics.docs.util.NetworkUtil;
import com.sismics.docs.util.PreferenceUtil;
import com.sismics.docs.util.TagUtil;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -64,9 +64,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import cz.msebera.android.httpclient.Header;
-import de.greenrobot.event.EventBus;
-
/**
* Document activity.
*
@@ -183,7 +180,7 @@ public class DocumentViewActivity extends AppCompatActivity {
createdDateTextView.setText(date);
TextView descriptionTextView = (TextView) findViewById(R.id.descriptionTextView);
- if (description == null || description.isEmpty() || description.equals(JSONObject.NULL.toString())) {
+ if (description.isEmpty() || document.isNull("description")) {
descriptionTextView.setVisibility(View.GONE);
} else {
descriptionTextView.setVisibility(View.VISIBLE);
@@ -251,7 +248,8 @@ public class DocumentViewActivity extends AppCompatActivity {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- DialogFragment dialog = DocExportPdfFragment.newInstance(DocumentViewActivity.this.document.optString("id"));
+ DialogFragment dialog = DocExportPdfFragment.newInstance(
+ DocumentViewActivity.this.document.optString("id"), DocumentViewActivity.this.document.optString("title"));
dialog.show(getSupportFragmentManager(), "DocExportPdfFragment");
}
});
@@ -282,14 +280,14 @@ public class DocumentViewActivity extends AppCompatActivity {
CommentResource.add(DocumentViewActivity.this,
DocumentViewActivity.this.document.optString("id"),
commentEditText.getText().toString(),
- new JsonHttpResponseHandler() {
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ new HttpCallback() {
+ public void onSuccess(JSONObject response) {
EventBus.getDefault().post(new CommentAddEvent(response));
commentEditText.setText("");
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(DocumentViewActivity.this, R.string.comment_add_failure, Toast.LENGTH_LONG).show();
}
});
@@ -366,11 +364,11 @@ public class DocumentViewActivity extends AppCompatActivity {
int position = fileViewPager.getCurrentItem();
if (mimeType == null || !mimeType.contains("/")) return;
String ext = mimeType.split("/")[1];
- String fileName = getTitle() + "-" + position + "." + ext;
+ String fileName = document.optString("title") + "-" + position + "." + ext;
// Download the file
String fileUrl = PreferenceUtil.getServerUrl(this) + "/api/file/" + file.optString("id") + "/data";
- downloadFile(fileUrl, fileName, getTitle().toString(), getString(R.string.downloading_file, position + 1));
+ NetworkUtil.downloadFile(this, fileUrl, fileName, document.optString("title"), getString(R.string.download_file_title));
}
private void deleteCurrentFile() {
@@ -393,24 +391,18 @@ public class DocumentViewActivity extends AppCompatActivity {
// Show a progress dialog while deleting
final ProgressDialog progressDialog = ProgressDialog.show(DocumentViewActivity.this,
getString(R.string.please_wait),
- getString(R.string.file_deleting_message), true, true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- FileResource.cancel(DocumentViewActivity.this);
- }
- });
+ getString(R.string.file_deleting_message), true, true);
// Actual delete server call
final String fileId = file.optString("id");
- FileResource.delete(DocumentViewActivity.this, fileId, new JsonHttpResponseHandler() {
+ FileResource.delete(DocumentViewActivity.this, fileId, new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
EventBus.getDefault().post(new FileDeleteEvent(fileId));
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(DocumentViewActivity.this, R.string.file_delete_failure, Toast.LENGTH_LONG).show();
}
@@ -435,28 +427,8 @@ public class DocumentViewActivity extends AppCompatActivity {
private void downloadZip() {
if (document == null) return;
String url = PreferenceUtil.getServerUrl(this) + "/api/file/zip?id=" + document.optString("id");
- String fileName = getTitle() + ".zip";
- downloadFile(url, fileName, getTitle().toString(), getString(R.string.downloading_document));
- }
-
- /**
- * Download a file using Android download manager.
- *
- * @param url URL to download
- * @param fileName Destination file name
- * @param title Notification title
- * @param description Notification description
- */
- private void downloadFile(String url, String fileName, String title, String description) {
- String authToken = PreferenceUtil.getAuthToken(this);
- DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
- DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
- request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
- request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
- request.addRequestHeader("Cookie", "auth_token=" + authToken);
- request.setTitle(title);
- request.setDescription(description);
- downloadManager.enqueue(request);
+ String fileName = document.optString("title") + ".zip";
+ NetworkUtil.downloadFile(this, url, fileName, document.optString("title"), getString(R.string.download_document_title));
}
/**
@@ -478,13 +450,7 @@ public class DocumentViewActivity extends AppCompatActivity {
// Show a progress dialog while deleting
final ProgressDialog progressDialog = ProgressDialog.show(DocumentViewActivity.this,
getString(R.string.please_wait),
- getString(R.string.document_deleting_message), true, true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- DocumentResource.cancel(DocumentViewActivity.this);
- }
- });
+ getString(R.string.document_deleting_message), true, true);
// Actual delete server call
final String documentId = document.optString("id");
@@ -520,6 +486,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event Document fullscreen event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DocumentFullscreenEvent event) {
findViewById(R.id.detailLayout).setVisibility(event.isFullscreen() ? View.GONE : View.VISIBLE);
}
@@ -529,6 +496,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event Document edit event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DocumentEditEvent event) {
if (document == null) return;
if (event.getDocument().optString("id").equals(document.optString("id"))) {
@@ -542,6 +510,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event Document delete event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DocumentDeleteEvent event) {
if (document == null) return;
if (event.getDocumentId().equals(document.optString("id"))) {
@@ -555,6 +524,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event File delete event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(FileDeleteEvent event) {
if (filePagerAdapter == null) return;
filePagerAdapter.remove(event.getFileId());
@@ -567,6 +537,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event File add event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(FileAddEvent event) {
if (document == null) return;
if (document.optString("id").equals(event.getDocumentId())) {
@@ -579,6 +550,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event Comment add event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(CommentAddEvent event) {
if (commentListAdapter == null) return;
TextView emptyView = (TextView) findViewById(R.id.commentEmptyView);
@@ -593,6 +565,7 @@ public class DocumentViewActivity extends AppCompatActivity {
*
* @param event Comment add event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(CommentDeleteEvent event) {
if (commentListAdapter == null) return;
TextView emptyView = (TextView) findViewById(R.id.commentEmptyView);
@@ -696,14 +669,14 @@ public class DocumentViewActivity extends AppCompatActivity {
final String commentId = comment.optString("id");
Toast.makeText(DocumentViewActivity.this, R.string.deleting_comment, Toast.LENGTH_LONG).show();
- CommentResource.remove(DocumentViewActivity.this, commentId, new JsonHttpResponseHandler() {
+ CommentResource.remove(DocumentViewActivity.this, commentId, new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
EventBus.getDefault().post(new CommentDeleteEvent(commentId));
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(DocumentViewActivity.this, R.string.error_deleting_comment, Toast.LENGTH_LONG).show();
}
});
@@ -728,9 +701,9 @@ public class DocumentViewActivity extends AppCompatActivity {
listView.setVisibility(View.GONE);
registerForContextMenu(listView);
- CommentResource.list(this, document.optString("id"), new JsonHttpResponseHandler() {
+ CommentResource.list(this, document.optString("id"), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
JSONArray comments = response.optJSONArray("comments");
commentListAdapter = new CommentListAdapter(DocumentViewActivity.this, comments);
listView.setAdapter(commentListAdapter);
@@ -743,7 +716,7 @@ public class DocumentViewActivity extends AppCompatActivity {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
emptyView.setText(R.string.error_loading_comments);
progressBar.setVisibility(View.GONE);
listView.setVisibility(View.GONE);
@@ -766,9 +739,9 @@ public class DocumentViewActivity extends AppCompatActivity {
progressBar.setVisibility(View.VISIBLE);
filesEmptyView.setVisibility(View.GONE);
- FileResource.list(this, document.optString("id"), new JsonHttpResponseHandler() {
+ FileResource.list(this, document.optString("id"), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
JSONArray files = response.optJSONArray("files");
filePagerAdapter = new FilePagerAdapter(DocumentViewActivity.this, files);
fileViewPager.setAdapter(filePagerAdapter);
@@ -778,7 +751,7 @@ public class DocumentViewActivity extends AppCompatActivity {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
filesEmptyView.setText(R.string.error_loading_files);
progressBar.setVisibility(View.GONE);
filesEmptyView.setVisibility(View.VISIBLE);
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java
index 9495e863..096588bd 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java
@@ -14,7 +14,7 @@ import android.widget.TextView;
import com.sismics.docs.R;
import com.sismics.docs.listener.CallbackListener;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.model.application.ApplicationContext;
import com.sismics.docs.resource.UserResource;
import com.sismics.docs.ui.form.Validator;
@@ -24,8 +24,6 @@ import com.sismics.docs.util.PreferenceUtil;
import org.json.JSONObject;
-import cz.msebera.android.httpclient.Header;
-
/**
* Login activity.
*
@@ -90,9 +88,9 @@ public class LoginActivity extends AppCompatActivity {
PreferenceUtil.setServerUrl(LoginActivity.this, txtServer.getText().toString());
try {
- UserResource.login(getApplicationContext(), txtUsername.getText().toString(), txtPassword.getText().toString(), new JsonHttpResponseHandler() {
+ UserResource.login(getApplicationContext(), txtUsername.getText().toString(), txtPassword.getText().toString(), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject json) {
+ public void onSuccess(JSONObject json) {
// Empty previous user caches
PreferenceUtil.resetUserCache(getApplicationContext());
@@ -108,11 +106,11 @@ public class LoginActivity extends AppCompatActivity {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
loginForm.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
- if (responseBytes != null && new String(responseBytes).contains("\"ForbiddenError\"")) {
+ if (json != null && json.optString("type").equals("ForbiddenError")) {
DialogUtil.showOkDialog(LoginActivity.this, R.string.login_fail_title, R.string.login_fail);
} else {
DialogUtil.showOkDialog(LoginActivity.this, R.string.network_error_title, R.string.network_error);
@@ -150,9 +148,9 @@ public class LoginActivity extends AppCompatActivity {
finish();
} else {
// Trying to get user data
- UserResource.info(getApplicationContext(), new JsonHttpResponseHandler() {
+ UserResource.info(getApplicationContext(), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, final JSONObject json) {
+ public void onSuccess(final JSONObject json) {
if (json.optBoolean("anonymous", true)) {
loginForm.setVisibility(View.VISIBLE);
return;
@@ -168,7 +166,7 @@ public class LoginActivity extends AppCompatActivity {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
DialogUtil.showOkDialog(LoginActivity.this, R.string.network_error_title, R.string.network_error);
loginForm.setVisibility(View.VISIBLE);
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
index 80748991..6732e7f3 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
@@ -23,18 +23,18 @@ import com.sismics.docs.adapter.TagListAdapter;
import com.sismics.docs.event.AdvancedSearchEvent;
import com.sismics.docs.event.SearchEvent;
import com.sismics.docs.fragment.SearchFragment;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.model.application.ApplicationContext;
import com.sismics.docs.provider.RecentSuggestionsProvider;
import com.sismics.docs.resource.TagResource;
import com.sismics.docs.resource.UserResource;
import com.sismics.docs.util.PreferenceUtil;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONObject;
-import cz.msebera.android.httpclient.Header;
-import de.greenrobot.event.EventBus;
-
/**
* Main activity.
*
@@ -90,9 +90,9 @@ public class MainActivity extends AppCompatActivity {
if (cacheTags != null) {
tagListView.setAdapter(new TagListAdapter(cacheTags.optJSONArray("stats")));
}
- TagResource.stats(this, new JsonHttpResponseHandler() {
+ TagResource.stats(this, new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
PreferenceUtil.setCachedJson(MainActivity.this, PreferenceUtil.PREF_CACHED_TAGS_JSON, response);
tagListView.setAdapter(new TagListAdapter(response.optJSONArray("stats")));
tagProgressView.setVisibility(View.GONE);
@@ -100,7 +100,7 @@ public class MainActivity extends AppCompatActivity {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
tagEmptyView.setText(R.string.error_loading_tags);
tagProgressView.setVisibility(View.GONE);
tagListView.setEmptyView(tagEmptyView);
@@ -146,7 +146,7 @@ public class MainActivity extends AppCompatActivity {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.logout:
- UserResource.logout(getApplicationContext(), new JsonHttpResponseHandler() {
+ UserResource.logout(getApplicationContext(), new HttpCallback() {
@Override
public void onFinish() {
// Force logout in all cases, so the user is not stuck in case of network error
@@ -266,6 +266,7 @@ public class MainActivity extends AppCompatActivity {
*
* @param event Advanced search event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(AdvancedSearchEvent event) {
searchQuery(event.getQuery());
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java
index 8b04cede..c2926652 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java
@@ -36,11 +36,6 @@ public class FilePagerAdapter extends PagerAdapter {
*/
private Context context;
- /**
- * Auth token used to download files.
- */
- private String authToken;
-
/**
* File pager adapter.
*
@@ -53,7 +48,6 @@ public class FilePagerAdapter extends PagerAdapter {
files.add(filesArray.optJSONObject(i));
}
this.context = context;
- this.authToken = PreferenceUtil.getAuthToken(context);
}
@Override
diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java
index 6469866f..e92a8862 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/ShareListAdapter.java
@@ -12,14 +12,13 @@ import com.sismics.docs.R;
import com.sismics.docs.event.ShareDeleteEvent;
import com.sismics.docs.event.ShareSendEvent;
+import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
-import de.greenrobot.event.EventBus;
-
/**
* Share list adapter.
*
diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java
index b10be67e..f921a804 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/TagListAdapter.java
@@ -20,6 +20,7 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
/**
* Tag list adapter.
@@ -99,7 +100,7 @@ public class TagListAdapter extends BaseAdapter {
TextView tagTextView = (TextView) view.findViewById(R.id.tagTextView);
tagTextView.setText(tagItem.name);
TextView tagCountTextView = (TextView) view.findViewById(R.id.tagCountTextView);
- tagCountTextView.setText(String.format("%d", tagItem.count));
+ tagCountTextView.setText(String.format(Locale.ENGLISH, "%d", tagItem.count));
// Label color filtering
ImageView labelImageView = (ImageView) view.findViewById(R.id.labelImageView);
diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java
index 0aab910e..3af5480c 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocExportPdfFragment.java
@@ -8,8 +8,15 @@ import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.CheckBox;
+import android.widget.SeekBar;
+import android.widget.TextView;
import com.sismics.docs.R;
+import com.sismics.docs.util.NetworkUtil;
+import com.sismics.docs.util.PreferenceUtil;
+
+import java.util.Locale;
/**
* Export PDF dialog fragment.
@@ -21,11 +28,13 @@ public class DocExportPdfFragment extends DialogFragment {
* Export PDF dialog fragment.
*
* @param id Document ID
+ * @param title Document title
*/
- public static DocExportPdfFragment newInstance(String id) {
+ public static DocExportPdfFragment newInstance(String id, String title) {
DocExportPdfFragment fragment = new DocExportPdfFragment();
Bundle args = new Bundle();
args.putString("id", id);
+ args.putString("title", title);
fragment.setArguments(args);
return fragment;
}
@@ -38,11 +47,41 @@ public class DocExportPdfFragment extends DialogFragment {
// Setup the view
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.document_export_pdf_dialog, null);
+ final SeekBar marginSeekBar = (SeekBar) view.findViewById(R.id.marginSeekBar);
+ final CheckBox exportMetadataCheckbox = (CheckBox) view.findViewById(R.id.exportMetadataCheckbox);
+ final CheckBox exportCommentsCheckbox = (CheckBox) view.findViewById(R.id.exportCommentsCheckbox);
+ final CheckBox fitToPageCheckbox = (CheckBox) view.findViewById(R.id.fitToPageCheckbox);
+ final TextView marginValueText = (TextView) view.findViewById(R.id.marginValueText);
+
+ // Margin label follow seekbar value
+ marginSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ marginValueText.setText(String.format(Locale.ENGLISH, "%d", progress));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
// Build the dialog
builder.setView(view)
.setPositiveButton(R.string.download, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
+ // Download the PDF
+ String pdfUrl = PreferenceUtil.getServerUrl(getActivity()) + "/api/document/" + getArguments().getString("id") + "/pdf?" +
+ "metadata=" + exportMetadataCheckbox.isChecked() + "&comments=" + exportCommentsCheckbox.isChecked() + "&fitimagetopage=" + fitToPageCheckbox.isChecked() +
+ "&margin=" + marginSeekBar.getProgress();
+ String title = getArguments().getString("title");
+ NetworkUtil.downloadFile(getActivity(), pdfUrl, title + ".pdf", title, getString(R.string.download_pdf_title));
+
getDialog().cancel();
}
})
diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java
index db810b88..dad50038 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocListFragment.java
@@ -27,10 +27,11 @@ import com.sismics.docs.resource.DocumentResource;
import com.sismics.docs.ui.view.DividerItemDecoration;
import com.sismics.docs.ui.view.EmptyRecyclerView;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONObject;
-import de.greenrobot.event.EventBus;
-
/**
* @author bgamard.
*/
@@ -99,7 +100,7 @@ public class DocListFragment extends Fragment {
}));
// Infinite scrolling
- recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
+ recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
@@ -149,6 +150,7 @@ public class DocListFragment extends Fragment {
*
* @param event Search event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(SearchEvent event) {
query = event.getQuery();
loadDocuments(getView(), true);
@@ -159,6 +161,7 @@ public class DocListFragment extends Fragment {
*
* @param event Document edit event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DocumentEditEvent event) {
adapter.updateDocument(event.getDocument());
}
@@ -168,6 +171,7 @@ public class DocListFragment extends Fragment {
*
* @param event Document delete event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DocumentDeleteEvent event) {
adapter.deleteDocument(event.getDocumentId());
}
@@ -177,6 +181,7 @@ public class DocListFragment extends Fragment {
*
* @param event Document add event
*/
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DocumentAddEvent event) {
// Refresh the list, maybe the new document fit in it
loadDocuments(getView(), true);
diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java
index aa85a063..a97f6a67 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java
@@ -22,17 +22,16 @@ import com.sismics.docs.adapter.ShareListAdapter;
import com.sismics.docs.event.ShareDeleteEvent;
import com.sismics.docs.event.ShareSendEvent;
import com.sismics.docs.listener.HttpCallback;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
import com.sismics.docs.resource.DocumentResource;
import com.sismics.docs.resource.ShareResource;
import com.sismics.docs.util.PreferenceUtil;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONArray;
import org.json.JSONObject;
-import cz.msebera.android.httpclient.Header;
-import de.greenrobot.event.EventBus;
-
/**
* Document sharing dialog fragment.
*
@@ -76,15 +75,15 @@ public class DocShareFragment extends DialogFragment {
shareAddButton.setEnabled(false);
ShareResource.add(getActivity(), getArguments().getString("id"), shareNameEditText.getText().toString(),
- new JsonHttpResponseHandler() {
+ new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
shareNameEditText.setText("");
loadShares(getDialog().getWindow().getDecorView());
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(getActivity(), R.string.error_adding_share, Toast.LENGTH_SHORT).show();
}
@@ -141,20 +140,32 @@ public class DocShareFragment extends DialogFragment {
});
}
+ /**
+ * A share delete event has been fired.
+ *
+ * @param event Share delete event
+ */
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(ShareDeleteEvent event) {
- ShareResource.delete(getActivity(), event.getId(), new JsonHttpResponseHandler() {
+ ShareResource.delete(getActivity(), event.getId(), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
loadShares(getDialog().getWindow().getDecorView());
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(getActivity(), R.string.error_deleting_share, Toast.LENGTH_SHORT).show();
}
});
}
+ /**
+ * A share send event has been fired.
+ *
+ * @param event Share send event
+ */
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(ShareSendEvent event) {
if (document == null) return;
diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java
index 93ead327..d5eeedc5 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/SearchFragment.java
@@ -22,14 +22,13 @@ import com.sismics.docs.ui.view.TagsCompleteTextView;
import com.sismics.docs.util.PreferenceUtil;
import com.sismics.docs.util.SearchQueryBuilder;
+import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
-import de.greenrobot.event.EventBus;
-
/**
* Advanced search fragment.
*
diff --git a/docs-android/app/src/main/java/com/sismics/docs/listener/JsonHttpResponseHandler.java b/docs-android/app/src/main/java/com/sismics/docs/listener/JsonHttpResponseHandler.java
deleted file mode 100644
index ee9bb33c..00000000
--- a/docs-android/app/src/main/java/com/sismics/docs/listener/JsonHttpResponseHandler.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- Android Asynchronous Http Client
- Copyright (c) 2011 James Smith
- http://loopj.com
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package com.sismics.docs.listener;
-
-import android.util.Log;
-
-import com.loopj.android.http.TextHttpResponseHandler;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-
-import cz.msebera.android.httpclient.Header;
-import cz.msebera.android.httpclient.HttpStatus;
-
-/**
- * Used to intercept and handle the responses from requests made using {@link com.loopj.android.http.AsyncHttpClient}, with
- * automatic parsing into a {@link JSONObject} or {@link JSONArray}.
This class is
- * designed to be passed to get, post, put and delete requests with the {@link #onSuccess(int,
- * cz.msebera.android.httpclient.Header[], org.json.JSONArray)} or {@link #onSuccess(int,
- * cz.msebera.android.httpclient.Header[], org.json.JSONObject)} methods anonymously overridden.
- * Additionally, you can override the other event methods from the parent class.
- */
-public class JsonHttpResponseHandler extends TextHttpResponseHandler {
-
- private static final String LOG_TAG = "JsonHttpResponseHandler";
-
- /**
- * Creates new JsonHttpResponseHandler, with JSON String encoding UTF-8
- */
- public JsonHttpResponseHandler() {
- super(DEFAULT_CHARSET);
- }
-
- /**
- * Creates new JsonHttpRespnseHandler with given JSON String encoding
- *
- * @param encoding String encoding to be used when parsing JSON
- */
- public JsonHttpResponseHandler(String encoding) {
- super(encoding);
- }
-
- /**
- * Returns when request succeeds
- *
- * @param statusCode http response status line
- * @param headers response headers if any
- * @param response parsed response if any
- */
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Log.w(LOG_TAG, "onSuccess(int, Header[], JSONObject) was not overriden, but callback was received");
- }
-
- /**
- * Returns when request succeeds
- *
- * @param statusCode http response status line
- * @param headers response headers if any
- * @param response parsed response if any
- */
- public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
- Log.w(LOG_TAG, "onSuccess(int, Header[], JSONArray) was not overriden, but callback was received");
- }
-
- /**
- * Returns when request failed
- *
- * @param statusCode http response status line
- * @param headers response headers if any
- * @param throwable throwable describing the way request failed
- * @param errorResponse parsed response if any
- */
- public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
- Log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONObject) was not overriden, but callback was received", throwable);
- }
-
- /**
- * Returns when request failed
- *
- * @param statusCode http response status line
- * @param headers response headers if any
- * @param throwable throwable describing the way request failed
- * @param errorResponse parsed response if any
- */
- public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {
- Log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONArray) was not overriden, but callback was received", throwable);
- }
-
- @Override
- public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
- Log.w(LOG_TAG, "onFailure(int, Header[], String, Throwable) was not overriden, but callback was received", throwable);
- }
-
- @Override
- public void onSuccess(int statusCode, Header[] headers, String responseString) {
- Log.w(LOG_TAG, "onSuccess(int, Header[], String) was not overriden, but callback was received");
- }
-
- @Override
- public final void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBytes) {
- if (statusCode != HttpStatus.SC_NO_CONTENT) {
- Runnable parser = new Runnable() {
- @Override
- public void run() {
- try {
- final Object jsonResponse = parseResponse(responseBytes);
- postRunnable(new Runnable() {
- @Override
- public void run() {
- if (jsonResponse instanceof JSONObject) {
- onSuccess(statusCode, headers, (JSONObject) jsonResponse);
- } else if (jsonResponse instanceof JSONArray) {
- onSuccess(statusCode, headers, (JSONArray) jsonResponse);
- } else if (jsonResponse instanceof String) {
- onFailure(statusCode, headers, (String) jsonResponse, new JSONException("Response cannot be parsed as JSON data"));
- } else {
- onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null);
- }
-
- }
- });
- } catch (final JSONException ex) {
- postRunnable(new Runnable() {
- @Override
- public void run() {
- onFailure(statusCode, headers, ex, (JSONObject) null);
- }
- });
- }
- }
- };
- if (!getUseSynchronousMode()) {
- new Thread(parser).start();
- } else {
- // In synchronous mode everything should be run on one thread
- parser.run();
- }
- } else {
- onSuccess(statusCode, headers, new JSONObject());
- }
- }
-
- @Override
- public final void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) {
- if (responseBytes != null) {
- Runnable parser = new Runnable() {
- @Override
- public void run() {
- try {
- final Object jsonResponse = parseResponse(responseBytes);
- postRunnable(new Runnable() {
- @Override
- public void run() {
- if (jsonResponse instanceof JSONObject) {
- onFailure(statusCode, headers, throwable, (JSONObject) jsonResponse);
- } else if (jsonResponse instanceof JSONArray) {
- onFailure(statusCode, headers, throwable, (JSONArray) jsonResponse);
- } else if (jsonResponse instanceof String) {
- onFailure(statusCode, headers, (String) jsonResponse, throwable);
- } else {
- onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null);
- }
- }
- });
-
- } catch (final JSONException ex) {
- postRunnable(new Runnable() {
- @Override
- public void run() {
- onFailure(statusCode, headers, ex, (JSONObject) null);
- }
- });
-
- }
- }
- };
- if (!getUseSynchronousMode()) {
- new Thread(parser).start();
- } else {
- // In synchronous mode everything should be run on one thread
- parser.run();
- }
- } else {
- Log.v(LOG_TAG, "response body is null, calling onFailure(Throwable, JSONObject)");
- onFailure(statusCode, headers, throwable, (JSONObject) null);
- }
-
- // In all cases, call the default failure listener
- onAllFailure(statusCode, headers, responseBytes, throwable);
- }
-
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
- // All failures go there
- }
-
- /**
- * Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long,
- * Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()}
- *
- * @param responseBody response bytes to be assembled in String and parsed as JSON
- * @return Object parsedResponse
- * @throws org.json.JSONException exception if thrown while parsing JSON
- */
- protected Object parseResponse(byte[] responseBody) throws JSONException {
- if (null == responseBody)
- return null;
- Object result = null;
- //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If JSON is not valid this will return null
- String jsonString = getResponseString(responseBody, getCharset());
- if (jsonString != null) {
- jsonString = jsonString.trim();
- if (jsonString.startsWith(UTF8_BOM)) {
- jsonString = jsonString.substring(1);
- }
- if (jsonString.startsWith("{") || jsonString.startsWith("[")) {
- result = new JSONTokener(jsonString).nextValue();
- }
- }
- if (result == null) {
- result = jsonString;
- }
- return result;
- }
-}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java b/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java
index 4287396b..92a7c80e 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/listener/RecyclerItemClickListener.java
@@ -29,7 +29,7 @@ public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListen
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
- mListener.onItemClick(childView, view.getChildPosition(childView));
+ mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java b/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java
index 3fe032a8..b911ddc3 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/model/application/ApplicationContext.java
@@ -4,14 +4,12 @@ import android.app.Activity;
import android.content.Context;
import com.sismics.docs.listener.CallbackListener;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.resource.UserResource;
import com.sismics.docs.util.PreferenceUtil;
import org.json.JSONObject;
-import cz.msebera.android.httpclient.Header;
-
/**
* Global context of the application.
*
@@ -81,9 +79,9 @@ public class ApplicationContext {
* @param callbackListener CallbackListener
*/
public void fetchUserInfo(final Activity activity, final CallbackListener callbackListener) {
- UserResource.info(activity.getApplicationContext(), new JsonHttpResponseHandler() {
+ UserResource.info(activity.getApplicationContext(), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, final JSONObject json) {
+ public void onSuccess(JSONObject json) {
// Save data in application context
if (!json.optBoolean("anonymous", true)) {
setUserInfo(activity.getApplicationContext(), json);
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java
index c0f421cb..e78bd2a2 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java
@@ -1,124 +1,15 @@
package com.sismics.docs.resource;
import android.content.Context;
-import android.os.Build;
-import com.loopj.android.http.AsyncHttpClient;
-import com.loopj.android.http.PersistentCookieStore;
-import com.sismics.docs.util.ApplicationUtil;
import com.sismics.docs.util.PreferenceUtil;
-import java.io.IOException;
-import java.net.Socket;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Locale;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory;
-
/**
* Base class for API access.
*
* @author bgamard
*/
public class BaseResource {
- /**
- * User-Agent to use.
- */
- protected static String USER_AGENT = null;
-
- /**
- * Accept-Language header.
- */
- protected static String ACCEPT_LANGUAGE = null;
-
- /**
- * Async HTTP client.
- */
- protected static AsyncHttpClient client = new AsyncHttpClient();
-
- static {
- // 20sec default timeout
- client.setTimeout(60000);
- try {
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(null, null);
-
- // Async HTTP Client uses another HTTP libary
- MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
- sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- client.setSSLSocketFactory(sf);
- } catch (Exception e) {
- // NOP
- }
- }
-
- /**
- * Resource initialization.
- *
- * @param context Context
- */
- protected static void init(Context context) {
- client.setCookieStore(new PersistentCookieStore(context));
-
- if (USER_AGENT == null) {
- USER_AGENT = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
- client.setUserAgent(USER_AGENT);
- }
-
- if (ACCEPT_LANGUAGE == null) {
- Locale locale = Locale.getDefault();
- ACCEPT_LANGUAGE = locale.getLanguage() + "_" + locale.getCountry();
- client.addHeader("Accept-Language", ACCEPT_LANGUAGE);
- }
- }
-
- /**
- * Socket factory to allow self-signed certificates for Async HTTP Client.
- *
- * @author bgamard
- */
- public static class MySSLSocketFactory extends cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory {
- SSLContext sslContext = SSLContext.getInstance(SSLSocketFactory.TLS);
-
- public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
- super(truststore);
-
- TrustManager tm = new X509TrustManager() {
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
-
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
-
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- };
-
- sslContext.init(null, new TrustManager[]{tm}, null);
- }
-
- @Override
- public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
- return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
- }
-
- @Override
- public Socket createSocket() throws IOException {
- return sslContext.getSocketFactory().createSocket();
- }
- }
-
/**
* Returns cleaned API URL.
*
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java
index 6e545956..d93ee657 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/CommentResource.java
@@ -2,8 +2,12 @@ package com.sismics.docs.resource;
import android.content.Context;
-import com.loopj.android.http.RequestParams;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
+import com.sismics.docs.util.OkHttpUtil;
+
+import okhttp3.FormBody;
+import okhttp3.HttpUrl;
+import okhttp3.Request;
/**
@@ -17,12 +21,16 @@ public class CommentResource extends BaseResource {
*
* @param context Context
* @param documentId Document ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void list(Context context, String documentId, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.get(getApiUrl(context) + "/comment/" + documentId, responseHandler);
+ public static void list(Context context, String documentId, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/comment/" + documentId))
+ .get()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -31,15 +39,19 @@ public class CommentResource extends BaseResource {
* @param context Context
* @param documentId Document ID
* @param content Comment content
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void add(Context context, String documentId, String content, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- RequestParams params = new RequestParams();
- params.put("id", documentId);
- params.put("content", content);
- client.put(getApiUrl(context) + "/comment", params, responseHandler);
+ public static void add(Context context, String documentId, String content, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/comment"))
+ .put(new FormBody.Builder()
+ .add("id", documentId)
+ .add("content", content)
+ .build())
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -47,20 +59,15 @@ public class CommentResource extends BaseResource {
*
* @param context Context
* @param commentId Comment ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void remove(Context context, String commentId, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.delete(getApiUrl(context) + "/comment/" + commentId, responseHandler);
- }
-
- /**
- * Cancel pending requests.
- *
- * @param context Context
- */
- public static void cancel(Context context) {
- client.cancelRequests(context, true);
+ public static void remove(Context context, String commentId, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/comment/" + commentId))
+ .delete()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java
index 474590bf..b3bc5a71 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java
@@ -94,9 +94,8 @@ public class DocumentResource extends BaseResource {
.add("description", description)
.add("language", language)
.add("create_date", Long.toString(createDate));
- String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]);
- for (int i = 0; i < tagIdArray.length; i++) {
- formBuilder.add("tags", tagIdArray[i]);
+ for( String tagId : tagIdList) {
+ formBuilder.add("tags", tagId);
}
Request request = new Request.Builder()
@@ -127,9 +126,8 @@ public class DocumentResource extends BaseResource {
.add("description", description)
.add("language", language)
.add("create_date", Long.toString(createDate));
- String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]);
- for (int i = 0; i < tagIdArray.length; i++) {
- formBuilder.add("tags", tagIdArray[i]);
+ for( String tagId : tagIdList) {
+ formBuilder.add("tags", tagId);
}
Request request = new Request.Builder()
@@ -140,13 +138,4 @@ public class DocumentResource extends BaseResource {
.newCall(request)
.enqueue(HttpCallback.buildOkHttpCallback(callback));
}
-
- /**
- * Cancel pending requests.
- *
- * @param context Context
- */
- public static void cancel(Context context) {
- client.cancelRequests(context, true);
- }
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java
index 2e594817..87922f8d 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/FileResource.java
@@ -2,13 +2,24 @@ package com.sismics.docs.resource;
import android.content.Context;
-import com.loopj.android.http.PersistentCookieStore;
-import com.loopj.android.http.RequestParams;
-import com.loopj.android.http.SyncHttpClient;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
+import com.sismics.docs.util.OkHttpUtil;
+import org.json.JSONObject;
+
+import java.io.IOException;
import java.io.InputStream;
-import java.security.KeyStore;
+
+import okhttp3.HttpUrl;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.internal.Util;
+import okio.BufferedSink;
+import okio.Okio;
+import okio.Source;
/**
@@ -22,12 +33,19 @@ public class FileResource extends BaseResource {
*
* @param context Context
* @param documentId Document ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void list(Context context, String documentId, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.get(getApiUrl(context) + "/file/list?id=" + documentId, responseHandler);
+ public static void list(Context context, String documentId, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/file/list")
+ .newBuilder()
+ .addQueryParameter("id", documentId)
+ .build())
+ .get()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -35,12 +53,16 @@ public class FileResource extends BaseResource {
*
* @param context Context
* @param id ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void delete(Context context, String id, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.delete(getApiUrl(context) + "/file/" + id, responseHandler);
+ public static void delete(Context context, String id, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/file/" + id))
+ .delete()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -49,34 +71,53 @@ public class FileResource extends BaseResource {
* @param context Context
* @param documentId Document ID
* @param is Input stream
- * @param responseHandler Callback
+ * @param callback Callback
* @throws Exception
*/
- public static void addSync(Context context, String documentId, InputStream is, JsonHttpResponseHandler responseHandler) throws Exception {
- init(context);
+ public static void addSync(Context context, String documentId, final InputStream is, HttpCallback callback) throws Exception {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/file"))
+ .put(new MultipartBody.Builder()
+ .setType(MultipartBody.FORM)
+ .addFormDataPart("id", documentId)
+ .addFormDataPart("file", "file", new RequestBody() {
+ @Override
+ public MediaType contentType() {
+ return MediaType.parse("application/octet-stream");
+ }
- SyncHttpClient client = new SyncHttpClient();
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(null, null);
- MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
- sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- client.setSSLSocketFactory(sf);
- client.setCookieStore(new PersistentCookieStore(context));
- client.setUserAgent(USER_AGENT);
- client.addHeader("Accept-Language", ACCEPT_LANGUAGE);
+ @Override
+ public void writeTo(BufferedSink sink) throws IOException {
+ Source source = Okio.source(is);
+ try {
+ sink.writeAll(source);
+ } finally {
+ Util.closeQuietly(source);
+ }
+ }
+ })
+ .build())
+ .build();
+ Response response = OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .execute();
- RequestParams params = new RequestParams();
- params.put("id", documentId);
- params.put("file", is, "file", "application/octet-stream", true);
- client.put(getApiUrl(context) + "/file", params, responseHandler);
- }
+ // Call the right callback
+ final String body = response.body().string();
+ if (response.isSuccessful()) {
+ try {
+ callback.onSuccess(new JSONObject(body));
+ } catch (Exception e) {
+ callback.onFailure(null, e);
+ }
+ } else {
+ try {
+ callback.onFailure(new JSONObject(body), null);
+ } catch (Exception e) {
+ callback.onFailure(null, e);
+ }
+ }
- /**
- * Cancel pending requests.
- *
- * @param context Context
- */
- public static void cancel(Context context) {
- client.cancelRequests(context, true);
+ callback.onFinish();
}
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java
index 833d993e..fbbfba81 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/ShareResource.java
@@ -2,8 +2,12 @@ package com.sismics.docs.resource;
import android.content.Context;
-import com.loopj.android.http.RequestParams;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
+import com.sismics.docs.util.OkHttpUtil;
+
+import okhttp3.FormBody;
+import okhttp3.HttpUrl;
+import okhttp3.Request;
/**
@@ -18,15 +22,19 @@ public class ShareResource extends BaseResource {
* @param context Context
* @param documentId Document ID
* @param name Name
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void add(Context context, String documentId, String name, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- RequestParams params = new RequestParams();
- params.put("id", documentId);
- params.put("name", name);
- client.put(getApiUrl(context) + "/share", params, responseHandler);
+ public static void add(Context context, String documentId, String name, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/share"))
+ .put(new FormBody.Builder()
+ .add("id", documentId)
+ .add("name", name)
+ .build())
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -34,11 +42,15 @@ public class ShareResource extends BaseResource {
*
* @param context Context
* @param id ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void delete(Context context, String id, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.delete(getApiUrl(context) + "/share/" + id, responseHandler);
+ public static void delete(Context context, String id, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/share/" + id))
+ .delete()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java
index db03bb16..34539d14 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/TagResource.java
@@ -2,7 +2,11 @@ package com.sismics.docs.resource;
import android.content.Context;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
+import com.sismics.docs.util.OkHttpUtil;
+
+import okhttp3.HttpUrl;
+import okhttp3.Request;
/**
@@ -15,11 +19,15 @@ public class TagResource extends BaseResource {
* GET /tag/stats.
*
* @param context Context
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void stats(Context context, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.get(getApiUrl(context) + "/tag/stats", responseHandler);
+ public static void stats(Context context, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/tag/stats"))
+ .get()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java
index 36cb11db..3d35564a 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/UserResource.java
@@ -2,8 +2,12 @@ package com.sismics.docs.resource;
import android.content.Context;
-import com.loopj.android.http.RequestParams;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
+import com.sismics.docs.util.OkHttpUtil;
+
+import okhttp3.FormBody;
+import okhttp3.HttpUrl;
+import okhttp3.Request;
/**
* Access to /user API.
@@ -18,41 +22,51 @@ public class UserResource extends BaseResource {
* @param context Context
* @param username Username
* @param password Password
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void login(Context context, String username, String password, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- RequestParams params = new RequestParams();
- params.put("username", username);
- params.put("password", password);
- params.put("remember", "true");
- client.post(getApiUrl(context) + "/user/login", params, responseHandler);
+ public static void login(Context context, String username, String password, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/user/login"))
+ .post(new FormBody.Builder()
+ .add("username", username)
+ .add("password", password)
+ .add("remember", "true")
+ .build())
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
* GET /user.
*
* @param context Context
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void info(Context context, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- RequestParams params = new RequestParams();
- client.get(getApiUrl(context) + "/user", params, responseHandler);
+ public static void info(Context context, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/user"))
+ .get()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
* POST /user/logout.
*
* @param context Context
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void logout(Context context, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- RequestParams params = new RequestParams();
- client.post(getApiUrl(context) + "/user/logout", params, responseHandler);
+ public static void logout(Context context, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/user/logout"))
+ .post(new FormBody.Builder().build())
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java b/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java
index 79903b77..07fcb6cd 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/service/FileUploadService.java
@@ -12,16 +12,16 @@ import android.util.Log;
import com.sismics.docs.R;
import com.sismics.docs.event.FileAddEvent;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.resource.FileResource;
+import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
-import cz.msebera.android.httpclient.Header;
-import de.greenrobot.event.EventBus;
+import okhttp3.internal.Util;
/**
* Service to upload a file to a document in the background.
@@ -81,17 +81,22 @@ public class FileUploadService extends IntentService {
*/
private void handleFileUpload(final String documentId, final Uri uri) throws Exception {
final InputStream is = getContentResolver().openInputStream(uri);
- FileResource.addSync(this, documentId, is, new JsonHttpResponseHandler() {
+ FileResource.addSync(this, documentId, is, new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
EventBus.getDefault().post(new FileAddEvent(documentId, response.optString("id")));
FileUploadService.this.onComplete();
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
FileUploadService.this.onError();
}
+
+ @Override
+ public void onFinish() {
+ Util.closeQuietly(is);
+ }
});
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java
index fba41d56..3c703035 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/ApplicationUtil.java
@@ -10,7 +10,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
* @author bgamard
*/
public class ApplicationUtil {
-
/**
* Returns version name.
*
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java
index 271977c6..9967a25b 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/DialogUtil.java
@@ -12,7 +12,6 @@ import com.sismics.docs.R;
* @author bgamard
*/
public class DialogUtil {
-
/**
* Create a dialog with an OK button.
*
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java
new file mode 100644
index 00000000..a81b4862
--- /dev/null
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java
@@ -0,0 +1,33 @@
+package com.sismics.docs.util;
+
+import android.app.DownloadManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Environment;
+
+/**
+ * Utility class for network actions.
+ *
+ * @author bgamard.
+ */
+public class NetworkUtil {
+ /**
+ * Download a file using Android download manager.
+ *
+ * @param url URL to download
+ * @param fileName Destination file name
+ * @param title Notification title
+ * @param description Notification description
+ */
+ public static void downloadFile(Context context, String url, String fileName, String title, String description) {
+ String authToken = PreferenceUtil.getAuthToken(context);
+ DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
+ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
+ request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+ request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
+ request.addRequestHeader("Cookie", "auth_token=" + authToken);
+ request.setTitle(title);
+ request.setDescription(description);
+ downloadManager.enqueue(request);
+ }
+}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java
index e6756cdf..8ab91793 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java
@@ -11,8 +11,6 @@ import com.squareup.picasso.Picasso;
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
-import java.net.HttpCookie;
-import java.net.URI;
import java.security.cert.CertificateException;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
@@ -105,10 +103,10 @@ public class OkHttpUtil {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException { // Override cache configuration
final Request original = chain.request();
- final Request.Builder requestBuilder = original.newBuilder()
+ return chain.proceed(original.newBuilder()
.header("Cache-Control", "max-age=" + (3600 * 24 * 365))
- .method(original.method(), original.body());
- return chain.proceed(requestBuilder.build());
+ .method(original.method(), original.body())
+ .build());
}
})
.cache(getCache(context))
@@ -169,8 +167,6 @@ public class OkHttpUtil {
// Cookie handling
PersistentCookieStore cookieStore = new PersistentCookieStore(context);
CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ALL);
- cookieStore.add(URI.create(PreferenceUtil.getServerUrl(context)),
- new HttpCookie("auth_token", PreferenceUtil.getAuthToken(context))); // TODO Remove me when async http is ditched
// Runtime configuration
return okHttpClient.newBuilder()
@@ -178,11 +174,11 @@ public class OkHttpUtil {
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
- Request originalRequest = chain.request();
- return chain.proceed(originalRequest.newBuilder()
+ Request original = chain.request();
+ return chain.proceed(original.newBuilder()
.header("User-Agent", userAgent)
.header("Accept-Language", acceptLanguage)
- // TODO necessary?? .method(originalRequest.method(), originalRequest.body())
+ .method(original.method(), original.body())
.build());
}
})
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java
index 581bc139..da8537ea 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/PreferenceUtil.java
@@ -5,14 +5,13 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.preference.PreferenceManager;
-import com.loopj.android.http.PersistentCookieStore;
+import com.sismics.docs.resource.cookie.PersistentCookieStore;
import org.json.JSONObject;
+import java.net.HttpCookie;
import java.util.List;
-import cz.msebera.android.httpclient.cookie.Cookie;
-
/**
* Utility class on preferences.
*
@@ -27,6 +26,7 @@ public class PreferenceUtil {
/**
* Returns a preference of boolean type.
+ *
* @param context Context
* @param key Shared preference key
* @return Shared preference value
@@ -38,6 +38,7 @@ public class PreferenceUtil {
/**
* Returns a preference of string type.
+ *
* @param context Context
* @param key Shared preference key
* @return Shared preference value
@@ -49,6 +50,7 @@ public class PreferenceUtil {
/**
* Returns a preference of integer type.
+ *
* @param context Context
* @param key Shared preference key
* @return Shared preference value
@@ -70,6 +72,7 @@ public class PreferenceUtil {
/**
* Update JSON cache.
+ *
* @param context Context
* @param key Shared preference key
* @param json JSON data
@@ -81,6 +84,7 @@ public class PreferenceUtil {
/**
* Returns a JSON cache.
+ *
* @param context Context
* @param key Shared preference key
* @return JSON data
@@ -97,6 +101,7 @@ public class PreferenceUtil {
/**
* Update server URL.
+ *
* @param context Context
*/
public static void setServerUrl(Context context, String serverUrl) {
@@ -106,6 +111,7 @@ public class PreferenceUtil {
/**
* Empty user caches.
+ *
* @param context Context
*/
public static void resetUserCache(Context context) {
@@ -119,12 +125,13 @@ public class PreferenceUtil {
/**
* Returns auth token cookie from shared preferences.
+ *
* @return Auth token
*/
public static String getAuthToken(Context context) {
PersistentCookieStore cookieStore = new PersistentCookieStore(context);
- List cookieList = cookieStore.getCookies();
- for (Cookie cookie : cookieList) {
+ List cookieList = cookieStore.getCookies();
+ for (HttpCookie cookie : cookieList) {
if (cookie.getName().equals("auth_token")) {
return cookie.getValue();
}
@@ -135,6 +142,7 @@ public class PreferenceUtil {
/**
* Returns cleaned server URL.
+ *
* @param context Context
* @return Server URL
*/
diff --git a/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml b/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml
index 2ab84d61..16db3354 100644
--- a/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml
+++ b/docs-android/app/src/main/res/layout/document_export_pdf_dialog.xml
@@ -8,23 +8,59 @@
+ android:layout_margin="6dp"
+ android:text="@string/export_metadata"
+ android:id="@+id/exportMetadataCheckbox" />
+ android:layout_margin="6dp"
+ android:text="@string/export_comments"
+ android:id="@+id/exportCommentsCheckbox" />
+ android:layout_margin="6dp"
+ android:checked="true"
+ android:text="@string/fit_image_to_page"
+ android:id="@+id/fitToPageCheckbox" />
-
+ android:layout_margin="16dp"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs-android/app/src/main/res/values/strings.xml b/docs-android/app/src/main/res/values/strings.xml
index a6e76661..c65eeaec 100644
--- a/docs-android/app/src/main/res/values/strings.xml
+++ b/docs-android/app/src/main/res/values/strings.xml
@@ -28,9 +28,7 @@
A crash occurred, a report has been sent to resolve this problem
Created date
Download current file
- Downloading file number %1s
Download
- Downloading document
Search documents
All documents
Shared documents
@@ -119,6 +117,13 @@
Error deleting comment
Export PDF
Download
-
+ Margin
+ Fit image to page
+ Export comments
+ Export metadata
+ mm
+ Sismics Docs file export
+ Sismics Docs document export
+ Sismics Docs PDF export
diff --git a/docs-core/pom.xml b/docs-core/pom.xml
index d5f915ab..6db59fe5 100644
--- a/docs-core/pom.xml
+++ b/docs-core/pom.xml
@@ -28,7 +28,7 @@
org.hibernate
- hibernate-validator
+ hibernate-c3p0
diff --git a/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java b/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java
index 47f687c7..6ac6e64d 100644
--- a/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java
+++ b/docs-core/src/main/java/com/sismics/util/jpa/DbOpenHelper.java
@@ -1,21 +1,11 @@
package com.sismics.util.jpa;
-import com.google.common.base.Strings;
-import com.google.common.io.CharStreams;
-import com.sismics.docs.core.util.ConfigUtil;
-import com.sismics.util.ResourceUtil;
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.hibernate.engine.jdbc.internal.FormatStyle;
-import org.hibernate.engine.jdbc.internal.Formatter;
-import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
-import org.hibernate.service.ServiceRegistry;
-import org.hibernate.tool.hbm2ddl.ConnectionHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.*;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Writer;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -26,6 +16,22 @@ import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
+import org.hibernate.engine.jdbc.internal.FormatStyle;
+import org.hibernate.engine.jdbc.internal.Formatter;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
+import org.hibernate.service.ServiceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+import com.google.common.io.CharStreams;
+import com.sismics.docs.core.util.ConfigUtil;
+import com.sismics.util.ResourceUtil;
+
/**
* A helper to update the database incrementally.
*
@@ -37,10 +43,10 @@ public abstract class DbOpenHelper {
*/
private static final Logger log = LoggerFactory.getLogger(DbOpenHelper.class);
- private final ConnectionHelper connectionHelper;
-
private final SqlStatementLogger sqlStatementLogger;
+ private final JdbcConnectionAccess jdbcConnectionAccess;
+
private final List exceptions = new ArrayList();
private Formatter formatter;
@@ -51,9 +57,8 @@ public abstract class DbOpenHelper {
public DbOpenHelper(ServiceRegistry serviceRegistry) throws HibernateException {
final JdbcServices jdbcServices = serviceRegistry.getService(JdbcServices.class);
- connectionHelper = new SuppliedConnectionProviderConnectionHelper(jdbcServices.getConnectionProvider());
-
sqlStatementLogger = jdbcServices.getSqlStatementLogger();
+ jdbcConnectionAccess = jdbcServices.getBootstrapJdbcConnectionAccess();
formatter = (sqlStatementLogger.isFormat() ? FormatStyle.DDL : FormatStyle.NONE).getFormatter();
}
@@ -67,8 +72,7 @@ public abstract class DbOpenHelper {
try {
try {
- connectionHelper.prepare(true);
- connection = connectionHelper.getConnection();
+ connection = jdbcConnectionAccess.obtainConnection();
} catch (SQLException sqle) {
exceptions.add(sqle);
log.error("Unable to get database metadata", sqle);
@@ -120,7 +124,7 @@ public abstract class DbOpenHelper {
stmt.close();
stmt = null;
}
- connectionHelper.release();
+ jdbcConnectionAccess.releaseConnection(connection);
} catch (Exception e) {
exceptions.add(e);
log.error("Unable to close connection", e);
diff --git a/docs-core/src/main/java/com/sismics/util/jpa/EMF.java b/docs-core/src/main/java/com/sismics/util/jpa/EMF.java
index 01287b9e..c0073ce3 100644
--- a/docs-core/src/main/java/com/sismics/util/jpa/EMF.java
+++ b/docs-core/src/main/java/com/sismics/util/jpa/EMF.java
@@ -11,10 +11,10 @@ import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry;
-import org.hibernate.service.ServiceRegistryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,7 +36,7 @@ public final class EMF {
Environment.verifyProperties(properties);
ConfigurationHelper.resolvePlaceHolders(properties);
- ServiceRegistry reg = new ServiceRegistryBuilder().applySettings(properties).buildServiceRegistry();
+ ServiceRegistry reg = new StandardServiceRegistryBuilder().applySettings(properties).build();
DbOpenHelper openHelper = new DbOpenHelper(reg) {
@@ -85,12 +85,16 @@ public final class EMF {
String dbFile = dbDirectory.resolve("docs").toAbsolutePath().toString();
props.put("hibernate.connection.url", "jdbc:h2:file:" + dbFile + ";CACHE_SIZE=65536");
props.put("hibernate.connection.username", "sa");
- props.put("hibernate.hbm2ddl.auto", "none");
+ props.put("hibernate.hbm2ddl.auto", "");
props.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
props.put("hibernate.show_sql", "false");
props.put("hibernate.format_sql", "false");
props.put("hibernate.max_fetch_depth", "5");
props.put("hibernate.cache.use_second_level_cache", "false");
+ props.put("hibernate.c3p0.min_size", "1");
+ props.put("hibernate.c3p0.max_size", "10");
+ props.put("hibernate.c3p0.timeout", "0");
+ props.put("hibernate.c3p0.max_statements", "0");
return props;
}
diff --git a/docs-core/src/main/java/com/sismics/util/jpa/ManagedProvidedConnectionHelper.java b/docs-core/src/main/java/com/sismics/util/jpa/ManagedProvidedConnectionHelper.java
deleted file mode 100644
index 452b692e..00000000
--- a/docs-core/src/main/java/com/sismics/util/jpa/ManagedProvidedConnectionHelper.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-
-package com.sismics.util.jpa;
-
-import org.hibernate.cfg.Environment;
-import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
-import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.service.ServiceRegistryBuilder;
-import org.hibernate.service.internal.StandardServiceRegistryImpl;
-import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
-import org.hibernate.tool.hbm2ddl.ConnectionHelper;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Properties;
-
-/**
- * A {@link ConnectionHelper} implementation based on an internally
- * built and managed {@link ConnectionProvider}.
- *
- * @author Steve Ebersole
- */
-class ManagedProviderConnectionHelper implements ConnectionHelper {
- private Properties cfgProperties;
- private StandardServiceRegistryImpl serviceRegistry;
- private Connection connection;
-
- public ManagedProviderConnectionHelper(Properties cfgProperties) {
- this.cfgProperties = cfgProperties;
- }
-
- @Override
- public void prepare(boolean needsAutoCommit) throws SQLException {
- serviceRegistry = createServiceRegistry(cfgProperties);
- connection = serviceRegistry.getService(ConnectionProvider.class).getConnection();
- if (needsAutoCommit && !connection.getAutoCommit()) {
- connection.commit();
- connection.setAutoCommit(true);
- }
- }
-
- private static StandardServiceRegistryImpl createServiceRegistry(Properties properties) {
- Environment.verifyProperties(properties);
- ConfigurationHelper.resolvePlaceHolders(properties);
- return (StandardServiceRegistryImpl) new ServiceRegistryBuilder().applySettings(properties).buildServiceRegistry();
- }
-
- @Override
- public Connection getConnection() throws SQLException {
- return connection;
- }
-
- @Override
- public void release() throws SQLException {
- try {
- releaseConnection();
- } finally {
- releaseServiceRegistry();
- }
- }
-
- private void releaseConnection() throws SQLException {
- if (connection != null) {
- try {
- new SqlExceptionHelper().logAndClearWarnings(connection);
- } finally {
- try {
- serviceRegistry.getService(ConnectionProvider.class).closeConnection(connection);
- } finally {
- connection = null;
- }
- }
- }
- }
-
- private void releaseServiceRegistry() {
- if (serviceRegistry != null) {
- try {
- serviceRegistry.destroy();
- } finally {
- serviceRegistry = null;
- }
- }
- }
-}
diff --git a/docs-core/src/main/java/com/sismics/util/jpa/SessionUtil.java b/docs-core/src/main/java/com/sismics/util/jpa/SessionUtil.java
deleted file mode 100644
index 02e54ba7..00000000
--- a/docs-core/src/main/java/com/sismics/util/jpa/SessionUtil.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.sismics.util.jpa;
-
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-import org.hibernate.ejb.HibernateEntityManagerFactory;
-
-/**
- * Hibernate session utilities.
- *
- * @author jtremeaux
- */
-public final class SessionUtil {
- /**
- * Private constructor.
- */
- private SessionUtil() {
- }
-
- /**
- * Returns an instance of the current session.
- *
- * @return Instance of the current session
- */
- public static Session getCurrentSession() {
- SessionFactory sessionFactory = ((HibernateEntityManagerFactory) EMF.get()).getSessionFactory();
- return sessionFactory.getCurrentSession();
- }
-}
\ No newline at end of file
diff --git a/docs-core/src/main/java/com/sismics/util/jpa/SuppliedConnectionProviderConnectionHelper.java b/docs-core/src/main/java/com/sismics/util/jpa/SuppliedConnectionProviderConnectionHelper.java
deleted file mode 100644
index 0da68386..00000000
--- a/docs-core/src/main/java/com/sismics/util/jpa/SuppliedConnectionProviderConnectionHelper.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-
-package com.sismics.util.jpa;
-
-import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
-import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
-import org.hibernate.tool.hbm2ddl.ConnectionHelper;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * A {@link ConnectionHelper} implementation based on a provided
- * {@link ConnectionProvider}. Essentially, ensures that the connection
- * gets cleaned up, but that the provider itself remains usable since it
- * was externally provided to us.
- *
- * @author Steve Ebersole
- */
-class SuppliedConnectionProviderConnectionHelper implements ConnectionHelper {
- private ConnectionProvider provider;
- private Connection connection;
- private boolean toggleAutoCommit;
-
- public SuppliedConnectionProviderConnectionHelper(ConnectionProvider provider) {
- this.provider = provider;
- }
-
- @Override
- public void prepare(boolean needsAutoCommit) throws SQLException {
- connection = provider.getConnection();
- toggleAutoCommit = needsAutoCommit && !connection.getAutoCommit();
- if ( toggleAutoCommit ) {
- try {
- connection.commit();
- }
- catch( Throwable ignore ) {
- // might happen with a managed connection
- }
- connection.setAutoCommit( true );
- }
- }
-
- @Override
- public Connection getConnection() throws SQLException {
- return connection;
- }
-
- @Override
- public void release() throws SQLException {
- // we only release the connection
- if ( connection != null ) {
- new SqlExceptionHelper().logAndClearWarnings( connection );
- if ( toggleAutoCommit ) {
- connection.setAutoCommit( false );
- }
- provider.closeConnection( connection );
- connection = null;
- }
- }
-}
diff --git a/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java b/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java
index 0dc8d675..8abad9c7 100644
--- a/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java
+++ b/docs-core/src/test/java/com/sismics/docs/core/dao/jpa/TestJpa.java
@@ -3,7 +3,7 @@ package com.sismics.docs.core.dao.jpa;
import com.sismics.docs.BaseTransactionalTest;
import com.sismics.docs.core.model.jpa.User;
import com.sismics.docs.core.util.TransactionUtil;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.junit.Test;
/**
diff --git a/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java b/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java
index 39477e5f..68dbbe8b 100644
--- a/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java
+++ b/docs-core/src/test/java/com/sismics/docs/core/util/TestEncryptUtil.java
@@ -5,8 +5,7 @@ import java.io.InputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
-import junit.framework.Assert;
-
+import org.junit.Assert;
import org.junit.Test;
import com.google.common.base.Strings;
diff --git a/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java b/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java
index 7ec18c99..7e04aaf2 100644
--- a/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java
+++ b/docs-core/src/test/java/com/sismics/docs/core/util/TestFileUtil.java
@@ -11,7 +11,7 @@ import com.google.common.io.Resources;
import com.sismics.docs.core.model.jpa.File;
import com.sismics.util.mime.MimeType;
-import junit.framework.Assert;
+import org.junit.Assert;
/**
* Test of the file entity utilities.
diff --git a/docs-core/src/test/java/com/sismics/util/TestDateUtil.java b/docs-core/src/test/java/com/sismics/util/TestDateUtil.java
index 797904b6..4c587881 100644
--- a/docs-core/src/test/java/com/sismics/util/TestDateUtil.java
+++ b/docs-core/src/test/java/com/sismics/util/TestDateUtil.java
@@ -1,6 +1,6 @@
package com.sismics.util;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.junit.Test;
/**
diff --git a/docs-core/src/test/java/com/sismics/util/TestImageUtil.java b/docs-core/src/test/java/com/sismics/util/TestImageUtil.java
index d6c62703..6d980aaa 100644
--- a/docs-core/src/test/java/com/sismics/util/TestImageUtil.java
+++ b/docs-core/src/test/java/com/sismics/util/TestImageUtil.java
@@ -1,6 +1,6 @@
package com.sismics.util;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.junit.Test;
/**
diff --git a/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java b/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java
index c780dcf6..10518fc4 100644
--- a/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java
+++ b/docs-core/src/test/java/com/sismics/util/TestResourceUtil.java
@@ -1,6 +1,6 @@
package com.sismics.util;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.junit.Test;
import java.util.List;
diff --git a/docs-core/src/test/resources/hibernate.properties b/docs-core/src/test/resources/hibernate.properties
index edd32f92..2c068af9 100644
--- a/docs-core/src/test/resources/hibernate.properties
+++ b/docs-core/src/test/resources/hibernate.properties
@@ -2,9 +2,13 @@ hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:mem:docs
hibernate.connection.username=sa
hibernate.connection.password=
-hibernate.hbm2ddl.auto=none
+hibernate.hbm2ddl.auto=
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.show_sql=true
hibernate.format_sql=false
hibernate.max_fetch_depth=5
hibernate.cache.use_second_level_cache=false
+hibernate.c3p0.min_size=1
+hibernate.c3p0.max_size=10
+hibernate.c3p0.timeout=0
+hibernate.c3p0.max_statements=0
\ No newline at end of file
diff --git a/docs-parent/pom.xml b/docs-parent/pom.xml
index 7dbec5a4..30badbc7 100644
--- a/docs-parent/pom.xml
+++ b/docs-parent/pom.xml
@@ -20,20 +20,20 @@
2.6
2.4
1.4
- 18.0
+ 19.0
1.2.16
1.6.4
1.6.6
- 4.7
- 1.4.190
+ 4.12
+ 1.4.191
2.22.1
0.3m
4.2.0
4.2
- 2.0.0-RC2
- 1.53
+ 2.0.0-RC3
+ 1.54
2.9.1
- 4.1.0.Final
+ 5.0.7.Final
3.1.0
1.0.5
4.2.1
@@ -48,11 +48,10 @@
1.8
2.10
- 2.4
- 2.5.2
+ 2.6
2.7
2.6
- 2.18.1
+ 2.19.1
9.2.13.v20150730
@@ -306,7 +305,7 @@
org.hibernate
- hibernate-validator
+ hibernate-c3p0
${org.hibernate.hibernate.version}
diff --git a/docs-stress/src/main/java/com/sismics/docs/stress/Main.java b/docs-stress/src/main/java/com/sismics/docs/stress/Main.java
index 788af740..6ee460ef 100644
--- a/docs-stress/src/main/java/com/sismics/docs/stress/Main.java
+++ b/docs-stress/src/main/java/com/sismics/docs/stress/Main.java
@@ -17,7 +17,7 @@ import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
diff --git a/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java b/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java
index 4d5a289a..d9eb4cc5 100644
--- a/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java
+++ b/docs-web-common/src/test/java/com/sismics/docs/rest/util/TestValidationUtil.java
@@ -2,7 +2,7 @@ package com.sismics.docs.rest.util;
import com.sismics.rest.exception.ClientException;
import com.sismics.rest.util.ValidationUtil;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.junit.Test;
/**
diff --git a/docs-web/pom.xml b/docs-web/pom.xml
index 744c698e..048cc060 100644
--- a/docs-web/pom.xml
+++ b/docs-web/pom.xml
@@ -88,7 +88,7 @@
com.twelvemonkeys.servlet
servlet
-
+
com.sismics.docs
diff --git a/docs-web/src/dev/resources/hibernate.properties b/docs-web/src/dev/resources/hibernate.properties
index 0f7dfbdd..7e4efc32 100644
--- a/docs-web/src/dev/resources/hibernate.properties
+++ b/docs-web/src/dev/resources/hibernate.properties
@@ -2,9 +2,13 @@ hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:mem:docs
hibernate.connection.username=sa
hibernate.connection.password=
-hibernate.hbm2ddl.auto=none
+hibernate.hbm2ddl.auto=
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.show_sql=false
hibernate.format_sql=false
hibernate.max_fetch_depth=5
hibernate.cache.use_second_level_cache=false
+hibernate.c3p0.min_size=1
+hibernate.c3p0.max_size=10
+hibernate.c3p0.timeout=0
+hibernate.c3p0.max_statements=0
\ No newline at end of file
diff --git a/docs-web/src/main/webapp/src/style/bootstrap.css b/docs-web/src/main/webapp/src/style/bootstrap.css
index 6d772357..3d6b3daa 100644
--- a/docs-web/src/main/webapp/src/style/bootstrap.css
+++ b/docs-web/src/main/webapp/src/style/bootstrap.css
@@ -1,13 +1,3 @@
-/*!
- * Bootstrap v3.3.5 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-/*!
- * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=cd406b52370309d5bcbd)
- * Config saved to config.json and https://gist.github.com/cd406b52370309d5bcbd
- */
/*!
* Bootstrap v3.3.6 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
@@ -16,8 +6,8 @@
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
- -ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
}
body {
margin: 0;
@@ -70,28 +60,28 @@ dfn {
font-style: italic;
}
h1 {
+ margin: .67em 0;
font-size: 2em;
- margin: 0.67em 0;
}
mark {
- background: #ff0;
color: #000;
+ background: #ff0;
}
small {
font-size: 80%;
}
sub,
sup {
+ position: relative;
font-size: 75%;
line-height: 0;
- position: relative;
vertical-align: baseline;
}
sup {
- top: -0.5em;
+ top: -.5em;
}
sub {
- bottom: -0.25em;
+ bottom: -.25em;
}
img {
border: 0;
@@ -103,10 +93,10 @@ figure {
margin: 1em 40px;
}
hr {
+ height: 0;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
- height: 0;
}
pre {
overflow: auto;
@@ -123,9 +113,9 @@ input,
optgroup,
select,
textarea {
- color: inherit;
- font: inherit;
margin: 0;
+ font: inherit;
+ color: inherit;
}
button {
overflow: visible;
@@ -147,8 +137,8 @@ html input[disabled] {
}
button::-moz-focus-inner,
input::-moz-focus-inner {
- border: 0;
padding: 0;
+ border: 0;
}
input {
line-height: normal;
@@ -165,23 +155,23 @@ input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
input[type="search"] {
- -webkit-appearance: textfield;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
+ -webkit-appearance: textfield;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
fieldset {
- border: 1px solid #c0c0c0;
+ padding: .35em .625em .75em;
margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
+ border: 1px solid #c0c0c0;
}
legend {
- border: 0;
padding: 0;
+ border: 0;
}
textarea {
overflow: auto;
@@ -190,8 +180,8 @@ optgroup {
font-weight: bold;
}
table {
- border-collapse: collapse;
border-spacing: 0;
+ border-collapse: collapse;
}
td,
th {
@@ -202,11 +192,11 @@ th {
*,
*:before,
*:after {
- background: transparent !important;
color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
- text-shadow: none !important;
}
a,
a:visited {
@@ -225,6 +215,7 @@ th {
pre,
blockquote {
border: 1px solid #999;
+
page-break-inside: avoid;
}
thead {
@@ -271,6 +262,7 @@ th {
}
@font-face {
font-family: 'Glyphicons Halflings';
+
src: url('../fonts/glyphicons-halflings-regular.eot');
src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
@@ -282,6 +274,7 @@ th {
font-style: normal;
font-weight: normal;
line-height: 1;
+
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@@ -1074,25 +1067,26 @@ th {
}
* {
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
*:before,
*:after {
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
html {
font-size: 10px;
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.42857143;
- color: #333333;
- background-color: #ffffff;
+ color: #333;
+ background-color: #fff;
}
input,
button,
@@ -1135,17 +1129,17 @@ img {
border-radius: 6px;
}
.img-thumbnail {
- padding: 4px;
- line-height: 1.42857143;
- background-color: #ffffff;
- border: 1px solid #dddddd;
- border-radius: 4px;
- -webkit-transition: all 0.2s ease-in-out;
- -o-transition: all 0.2s ease-in-out;
- transition: all 0.2s ease-in-out;
display: inline-block;
max-width: 100%;
height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
}
.img-circle {
border-radius: 50%;
@@ -1154,14 +1148,14 @@ hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
- border-top: 1px solid #eeeeee;
+ border-top: 1px solid #eee;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
- margin: -1px;
padding: 0;
+ margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
@@ -1221,7 +1215,7 @@ h6 .small,
.h6 .small {
font-weight: normal;
line-height: 1;
- color: #777777;
+ color: #777;
}
h1,
.h1,
@@ -1313,8 +1307,8 @@ small,
}
mark,
.mark {
- background-color: #fcf8e3;
padding: .2em;
+ background-color: #fcf8e3;
}
.text-left {
text-align: left;
@@ -1341,7 +1335,7 @@ mark,
text-transform: capitalize;
}
.text-muted {
- color: #777777;
+ color: #777;
}
.text-primary {
color: #337ab7;
@@ -1417,7 +1411,7 @@ a.bg-danger:focus {
.page-header {
padding-bottom: 9px;
margin: 40px 0 20px;
- border-bottom: 1px solid #eeeeee;
+ border-bottom: 1px solid #eee;
}
ul,
ol {
@@ -1436,13 +1430,13 @@ ol ol {
}
.list-inline {
padding-left: 0;
- list-style: none;
margin-left: -5px;
+ list-style: none;
}
.list-inline > li {
display: inline-block;
- padding-left: 5px;
padding-right: 5px;
+ padding-left: 5px;
}
dl {
margin-top: 0;
@@ -1462,9 +1456,9 @@ dd {
.dl-horizontal dt {
float: left;
width: 160px;
+ overflow: hidden;
clear: left;
text-align: right;
- overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@@ -1475,7 +1469,7 @@ dd {
abbr[title],
abbr[data-original-title] {
cursor: help;
- border-bottom: 1px dotted #777777;
+ border-bottom: 1px dotted #777;
}
.initialism {
font-size: 90%;
@@ -1485,7 +1479,7 @@ blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
- border-left: 5px solid #eeeeee;
+ border-left: 5px solid #eee;
}
blockquote p:last-child,
blockquote ul:last-child,
@@ -1498,7 +1492,7 @@ blockquote .small {
display: block;
font-size: 80%;
line-height: 1.42857143;
- color: #777777;
+ color: #777;
}
blockquote footer:before,
blockquote small:before,
@@ -1509,9 +1503,9 @@ blockquote .small:before {
blockquote.pull-right {
padding-right: 15px;
padding-left: 0;
- border-right: 5px solid #eeeeee;
- border-left: 0;
text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
}
.blockquote-reverse footer:before,
blockquote.pull-right footer:before,
@@ -1550,11 +1544,11 @@ code {
kbd {
padding: 2px 4px;
font-size: 90%;
- color: #ffffff;
- background-color: #333333;
+ color: #fff;
+ background-color: #333;
border-radius: 3px;
- -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
}
kbd kbd {
padding: 0;
@@ -1569,11 +1563,11 @@ pre {
margin: 0 0 10px;
font-size: 13px;
line-height: 1.42857143;
+ color: #333;
word-break: break-all;
word-wrap: break-word;
- color: #333333;
background-color: #f5f5f5;
- border: 1px solid #cccccc;
+ border: 1px solid #ccc;
border-radius: 4px;
}
pre code {
@@ -1589,10 +1583,10 @@ pre code {
overflow-y: scroll;
}
.container {
+ padding-right: 15px;
+ padding-left: 15px;
margin-right: auto;
margin-left: auto;
- padding-left: 15px;
- padding-right: 15px;
}
@media (min-width: 768px) {
.container {
@@ -1610,20 +1604,20 @@ pre code {
}
}
.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
margin-right: auto;
margin-left: auto;
- padding-left: 15px;
- padding-right: 15px;
}
.row {
- margin-left: -15px;
margin-right: -15px;
+ margin-left: -15px;
}
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
position: relative;
min-height: 1px;
- padding-left: 15px;
padding-right: 15px;
+ padding-left: 15px;
}
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
float: left;
@@ -1779,7 +1773,7 @@ pre code {
margin-left: 8.33333333%;
}
.col-xs-offset-0 {
- margin-left: 0%;
+ margin-left: 0;
}
@media (min-width: 768px) {
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
@@ -1936,7 +1930,7 @@ pre code {
margin-left: 8.33333333%;
}
.col-sm-offset-0 {
- margin-left: 0%;
+ margin-left: 0;
}
}
@media (min-width: 992px) {
@@ -2094,7 +2088,7 @@ pre code {
margin-left: 8.33333333%;
}
.col-md-offset-0 {
- margin-left: 0%;
+ margin-left: 0;
}
}
@media (min-width: 1200px) {
@@ -2252,7 +2246,7 @@ pre code {
margin-left: 8.33333333%;
}
.col-lg-offset-0 {
- margin-left: 0%;
+ margin-left: 0;
}
}
table {
@@ -2261,7 +2255,7 @@ table {
caption {
padding-top: 8px;
padding-bottom: 8px;
- color: #777777;
+ color: #777;
text-align: left;
}
th {
@@ -2281,11 +2275,11 @@ th {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
- border-top: 1px solid #dddddd;
+ border-top: 1px solid #ddd;
}
.table > thead > tr > th {
vertical-align: bottom;
- border-bottom: 2px solid #dddddd;
+ border-bottom: 2px solid #ddd;
}
.table > caption + thead > tr:first-child > th,
.table > colgroup + thead > tr:first-child > th,
@@ -2296,10 +2290,10 @@ th {
border-top: 0;
}
.table > tbody + tbody {
- border-top: 2px solid #dddddd;
+ border-top: 2px solid #ddd;
}
.table .table {
- background-color: #ffffff;
+ background-color: #fff;
}
.table-condensed > thead > tr > th,
.table-condensed > tbody > tr > th,
@@ -2310,7 +2304,7 @@ th {
padding: 5px;
}
.table-bordered {
- border: 1px solid #dddddd;
+ border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
@@ -2318,7 +2312,7 @@ th {
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td {
- border: 1px solid #dddddd;
+ border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
@@ -2332,14 +2326,14 @@ th {
}
table col[class*="col-"] {
position: static;
- float: none;
display: table-column;
+ float: none;
}
table td[class*="col-"],
table th[class*="col-"] {
position: static;
- float: none;
display: table-cell;
+ float: none;
}
.table > thead > tr > td.active,
.table > tbody > tr > td.active,
@@ -2447,8 +2441,8 @@ table th[class*="col-"] {
background-color: #ebcccc;
}
.table-responsive {
+ min-height: .01%;
overflow-x: auto;
- min-height: 0.01%;
}
@media screen and (max-width: 767px) {
.table-responsive {
@@ -2456,7 +2450,7 @@ table th[class*="col-"] {
margin-bottom: 15px;
overflow-y: hidden;
-ms-overflow-style: -ms-autohiding-scrollbar;
- border: 1px solid #dddddd;
+ border: 1px solid #ddd;
}
.table-responsive > .table {
margin-bottom: 0;
@@ -2496,10 +2490,10 @@ table th[class*="col-"] {
}
}
fieldset {
+ min-width: 0;
padding: 0;
margin: 0;
border: 0;
- min-width: 0;
}
legend {
display: block;
@@ -2508,7 +2502,7 @@ legend {
margin-bottom: 20px;
font-size: 21px;
line-height: inherit;
- color: #333333;
+ color: #333;
border: 0;
border-bottom: 1px solid #e5e5e5;
}
@@ -2520,8 +2514,8 @@ label {
}
input[type="search"] {
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
input[type="radio"],
input[type="checkbox"] {
@@ -2552,7 +2546,7 @@ output {
padding-top: 7px;
font-size: 14px;
line-height: 1.42857143;
- color: #555555;
+ color: #555;
}
.form-control {
display: block;
@@ -2561,41 +2555,41 @@ output {
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
- color: #555555;
- background-color: #ffffff;
+ color: #555;
+ background-color: #fff;
background-image: none;
- border: 1px solid #cccccc;
+ border: 1px solid #ccc;
border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
- -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
- transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
- -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
- box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
}
.form-control::-moz-placeholder {
- color: #999999;
+ color: #999;
opacity: 1;
}
.form-control:-ms-input-placeholder {
- color: #999999;
+ color: #999;
}
.form-control::-webkit-input-placeholder {
- color: #999999;
+ color: #999;
}
.form-control::-ms-expand {
- border: 0;
background-color: transparent;
+ border: 0;
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
- background-color: #eeeeee;
+ background-color: #eee;
opacity: 1;
}
.form-control[disabled],
@@ -2659,8 +2653,8 @@ input[type="search"] {
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
position: absolute;
- margin-left: -20px;
margin-top: 4px \9;
+ margin-left: -20px;
}
.radio + .radio,
.checkbox + .checkbox {
@@ -2672,8 +2666,8 @@ input[type="search"] {
display: inline-block;
padding-left: 20px;
margin-bottom: 0;
- vertical-align: middle;
font-weight: normal;
+ vertical-align: middle;
cursor: pointer;
}
.radio-inline + .radio-inline,
@@ -2702,15 +2696,15 @@ fieldset[disabled] .checkbox label {
cursor: not-allowed;
}
.form-control-static {
+ min-height: 34px;
padding-top: 7px;
padding-bottom: 7px;
margin-bottom: 0;
- min-height: 34px;
}
.form-control-static.input-lg,
.form-control-static.input-sm {
- padding-left: 0;
padding-right: 0;
+ padding-left: 0;
}
.input-sm {
height: 30px;
@@ -2832,18 +2826,18 @@ select[multiple].input-lg {
}
.has-success .form-control {
border-color: #3c763d;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.has-success .form-control:focus {
border-color: #2b542c;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
}
.has-success .input-group-addon {
color: #3c763d;
- border-color: #3c763d;
background-color: #dff0d8;
+ border-color: #3c763d;
}
.has-success .form-control-feedback {
color: #3c763d;
@@ -2862,18 +2856,18 @@ select[multiple].input-lg {
}
.has-warning .form-control {
border-color: #8a6d3b;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.has-warning .form-control:focus {
border-color: #66512c;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
}
.has-warning .input-group-addon {
color: #8a6d3b;
- border-color: #8a6d3b;
background-color: #fcf8e3;
+ border-color: #8a6d3b;
}
.has-warning .form-control-feedback {
color: #8a6d3b;
@@ -2892,18 +2886,18 @@ select[multiple].input-lg {
}
.has-error .form-control {
border-color: #a94442;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.has-error .form-control:focus {
border-color: #843534;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
}
.has-error .input-group-addon {
color: #a94442;
- border-color: #a94442;
background-color: #f2dede;
+ border-color: #a94442;
}
.has-error .form-control-feedback {
color: #a94442;
@@ -2974,23 +2968,23 @@ select[multiple].input-lg {
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
+ padding-top: 7px;
margin-top: 0;
margin-bottom: 0;
- padding-top: 7px;
}
.form-horizontal .radio,
.form-horizontal .checkbox {
min-height: 27px;
}
.form-horizontal .form-group {
- margin-left: -15px;
margin-right: -15px;
+ margin-left: -15px;
}
@media (min-width: 768px) {
.form-horizontal .control-label {
- text-align: right;
- margin-bottom: 0;
padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
}
}
.form-horizontal .has-feedback .form-control-feedback {
@@ -3010,24 +3004,24 @@ select[multiple].input-lg {
}
.btn {
display: inline-block;
+ padding: 6px 12px;
margin-bottom: 0;
+ font-size: 14px;
font-weight: normal;
+ line-height: 1.42857143;
text-align: center;
+ white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
background-image: none;
border: 1px solid transparent;
- white-space: nowrap;
- padding: 6px 12px;
- font-size: 14px;
- line-height: 1.42857143;
border-radius: 4px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
}
.btn:focus,
.btn:active:focus,
@@ -3042,49 +3036,49 @@ select[multiple].input-lg {
.btn:hover,
.btn:focus,
.btn.focus {
- color: #333333;
+ color: #333;
text-decoration: none;
}
.btn:active,
.btn.active {
- outline: 0;
background-image: none;
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
cursor: not-allowed;
- opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
- box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
}
a.btn.disabled,
fieldset[disabled] a.btn {
pointer-events: none;
}
.btn-default {
- color: #333333;
- background-color: #ffffff;
- border-color: #cccccc;
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
}
.btn-default:focus,
.btn-default.focus {
- color: #333333;
+ color: #333;
background-color: #e6e6e6;
border-color: #8c8c8c;
}
.btn-default:hover {
- color: #333333;
+ color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
- color: #333333;
+ color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
@@ -3097,7 +3091,7 @@ fieldset[disabled] a.btn {
.btn-default:active.focus,
.btn-default.active.focus,
.open > .dropdown-toggle.btn-default.focus {
- color: #333333;
+ color: #333;
background-color: #d4d4d4;
border-color: #8c8c8c;
}
@@ -3115,33 +3109,33 @@ fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus {
- background-color: #ffffff;
- border-color: #cccccc;
+ background-color: #fff;
+ border-color: #ccc;
}
.btn-default .badge {
- color: #ffffff;
- background-color: #333333;
+ color: #fff;
+ background-color: #333;
}
.btn-primary {
- color: #ffffff;
+ color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary:focus,
.btn-primary.focus {
- color: #ffffff;
+ color: #fff;
background-color: #286090;
border-color: #122b40;
}
.btn-primary:hover {
- color: #ffffff;
+ color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
- color: #ffffff;
+ color: #fff;
background-color: #286090;
border-color: #204d74;
}
@@ -3154,7 +3148,7 @@ fieldset[disabled] .btn-default.focus {
.btn-primary:active.focus,
.btn-primary.active.focus,
.open > .dropdown-toggle.btn-primary.focus {
- color: #ffffff;
+ color: #fff;
background-color: #204d74;
border-color: #122b40;
}
@@ -3177,28 +3171,28 @@ fieldset[disabled] .btn-primary.focus {
}
.btn-primary .badge {
color: #337ab7;
- background-color: #ffffff;
+ background-color: #fff;
}
.btn-success {
- color: #ffffff;
+ color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-success:focus,
.btn-success.focus {
- color: #ffffff;
+ color: #fff;
background-color: #449d44;
border-color: #255625;
}
.btn-success:hover {
- color: #ffffff;
+ color: #fff;
background-color: #449d44;
border-color: #398439;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
- color: #ffffff;
+ color: #fff;
background-color: #449d44;
border-color: #398439;
}
@@ -3211,7 +3205,7 @@ fieldset[disabled] .btn-primary.focus {
.btn-success:active.focus,
.btn-success.active.focus,
.open > .dropdown-toggle.btn-success.focus {
- color: #ffffff;
+ color: #fff;
background-color: #398439;
border-color: #255625;
}
@@ -3234,28 +3228,28 @@ fieldset[disabled] .btn-success.focus {
}
.btn-success .badge {
color: #5cb85c;
- background-color: #ffffff;
+ background-color: #fff;
}
.btn-info {
- color: #ffffff;
+ color: #fff;
background-color: #5bc0de;
border-color: #46b8da;
}
.btn-info:focus,
.btn-info.focus {
- color: #ffffff;
+ color: #fff;
background-color: #31b0d5;
border-color: #1b6d85;
}
.btn-info:hover {
- color: #ffffff;
+ color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
- color: #ffffff;
+ color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
@@ -3268,7 +3262,7 @@ fieldset[disabled] .btn-success.focus {
.btn-info:active.focus,
.btn-info.active.focus,
.open > .dropdown-toggle.btn-info.focus {
- color: #ffffff;
+ color: #fff;
background-color: #269abc;
border-color: #1b6d85;
}
@@ -3291,28 +3285,28 @@ fieldset[disabled] .btn-info.focus {
}
.btn-info .badge {
color: #5bc0de;
- background-color: #ffffff;
+ background-color: #fff;
}
.btn-warning {
- color: #ffffff;
+ color: #fff;
background-color: #f0ad4e;
border-color: #eea236;
}
.btn-warning:focus,
.btn-warning.focus {
- color: #ffffff;
+ color: #fff;
background-color: #ec971f;
border-color: #985f0d;
}
.btn-warning:hover {
- color: #ffffff;
+ color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
- color: #ffffff;
+ color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
@@ -3325,7 +3319,7 @@ fieldset[disabled] .btn-info.focus {
.btn-warning:active.focus,
.btn-warning.active.focus,
.open > .dropdown-toggle.btn-warning.focus {
- color: #ffffff;
+ color: #fff;
background-color: #d58512;
border-color: #985f0d;
}
@@ -3348,28 +3342,28 @@ fieldset[disabled] .btn-warning.focus {
}
.btn-warning .badge {
color: #f0ad4e;
- background-color: #ffffff;
+ background-color: #fff;
}
.btn-danger {
- color: #ffffff;
+ color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
.btn-danger:focus,
.btn-danger.focus {
- color: #ffffff;
+ color: #fff;
background-color: #c9302c;
border-color: #761c19;
}
.btn-danger:hover {
- color: #ffffff;
+ color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
- color: #ffffff;
+ color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
@@ -3382,7 +3376,7 @@ fieldset[disabled] .btn-warning.focus {
.btn-danger:active.focus,
.btn-danger.active.focus,
.open > .dropdown-toggle.btn-danger.focus {
- color: #ffffff;
+ color: #fff;
background-color: #ac2925;
border-color: #761c19;
}
@@ -3405,11 +3399,11 @@ fieldset[disabled] .btn-danger.focus {
}
.btn-danger .badge {
color: #d9534f;
- background-color: #ffffff;
+ background-color: #fff;
}
.btn-link {
- color: #337ab7;
font-weight: normal;
+ color: #337ab7;
border-radius: 0;
}
.btn-link,
@@ -3419,7 +3413,7 @@ fieldset[disabled] .btn-danger.focus {
fieldset[disabled] .btn-link {
background-color: transparent;
-webkit-box-shadow: none;
- box-shadow: none;
+ box-shadow: none;
}
.btn-link,
.btn-link:hover,
@@ -3437,7 +3431,7 @@ fieldset[disabled] .btn-link {
fieldset[disabled] .btn-link:hover,
.btn-link[disabled]:focus,
fieldset[disabled] .btn-link:focus {
- color: #777777;
+ color: #777;
text-decoration: none;
}
.btn-lg,
@@ -3475,9 +3469,9 @@ input[type="button"].btn-block {
}
.fade {
opacity: 0;
- -webkit-transition: opacity 0.15s linear;
- -o-transition: opacity 0.15s linear;
- transition: opacity 0.15s linear;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
}
.fade.in {
opacity: 1;
@@ -3498,15 +3492,15 @@ tbody.collapse.in {
position: relative;
height: 0;
overflow: hidden;
- -webkit-transition-property: height, visibility;
- -o-transition-property: height, visibility;
- transition-property: height, visibility;
- -webkit-transition-duration: 0.35s;
- -o-transition-duration: 0.35s;
- transition-duration: 0.35s;
-webkit-transition-timing-function: ease;
- -o-transition-timing-function: ease;
- transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
}
.caret {
display: inline-block;
@@ -3536,17 +3530,17 @@ tbody.collapse.in {
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
- list-style: none;
font-size: 14px;
text-align: left;
- background-color: #ffffff;
- border: 1px solid #cccccc;
- border: 1px solid rgba(0, 0, 0, 0.15);
- border-radius: 4px;
- -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
- box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ list-style: none;
+ background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
}
.dropdown-menu.pull-right {
right: 0;
@@ -3564,35 +3558,35 @@ tbody.collapse.in {
clear: both;
font-weight: normal;
line-height: 1.42857143;
- color: #333333;
+ color: #333;
white-space: nowrap;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
- text-decoration: none;
color: #262626;
+ text-decoration: none;
background-color: #f5f5f5;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
- color: #ffffff;
+ color: #fff;
text-decoration: none;
- outline: 0;
background-color: #337ab7;
+ outline: 0;
}
.dropdown-menu > .disabled > a,
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
- color: #777777;
+ color: #777;
}
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
text-decoration: none;
+ cursor: not-allowed;
background-color: transparent;
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
- cursor: not-allowed;
}
.open > .dropdown-menu {
display: block;
@@ -3601,27 +3595,27 @@ tbody.collapse.in {
outline: 0;
}
.dropdown-menu-right {
- left: auto;
right: 0;
+ left: auto;
}
.dropdown-menu-left {
- left: 0;
right: auto;
+ left: 0;
}
.dropdown-header {
display: block;
padding: 3px 20px;
font-size: 12px;
line-height: 1.42857143;
- color: #777777;
+ color: #777;
white-space: nowrap;
}
.dropdown-backdrop {
position: fixed;
- left: 0;
+ top: 0;
right: 0;
bottom: 0;
- top: 0;
+ left: 0;
z-index: 990;
}
.pull-right > .dropdown-menu {
@@ -3630,10 +3624,10 @@ tbody.collapse.in {
}
.dropup .caret,
.navbar-fixed-bottom .dropdown .caret {
+ content: "";
border-top: 0;
border-bottom: 4px dashed;
border-bottom: 4px solid \9;
- content: "";
}
.dropup .dropdown-menu,
.navbar-fixed-bottom .dropdown .dropdown-menu {
@@ -3643,12 +3637,12 @@ tbody.collapse.in {
}
@media (min-width: 768px) {
.navbar-right .dropdown-menu {
- left: auto;
right: 0;
+ left: auto;
}
.navbar-right .dropdown-menu-left {
- left: 0;
right: auto;
+ left: 0;
}
}
.btn-group,
@@ -3698,13 +3692,13 @@ tbody.collapse.in {
margin-left: 0;
}
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
- border-bottom-right-radius: 0;
border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
}
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
- border-bottom-left-radius: 0;
border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
}
.btn-group > .btn-group {
float: left;
@@ -3714,32 +3708,32 @@ tbody.collapse.in {
}
.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
- border-bottom-right-radius: 0;
border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
}
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
- border-bottom-left-radius: 0;
border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
}
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
.btn-group > .btn + .dropdown-toggle {
- padding-left: 8px;
padding-right: 8px;
+ padding-left: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
- padding-left: 12px;
padding-right: 12px;
+ padding-left: 12px;
}
.btn-group.open .dropdown-toggle {
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn-group.open .dropdown-toggle.btn-link {
-webkit-box-shadow: none;
- box-shadow: none;
+ box-shadow: none;
}
.btn .caret {
margin-left: 0;
@@ -3773,14 +3767,14 @@ tbody.collapse.in {
border-radius: 0;
}
.btn-group-vertical > .btn:first-child:not(:last-child) {
- border-top-right-radius: 4px;
border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn:last-child:not(:first-child) {
- border-top-right-radius: 0;
border-top-left-radius: 0;
+ border-top-right-radius: 0;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
@@ -3793,8 +3787,8 @@ tbody.collapse.in {
border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
- border-top-right-radius: 0;
border-top-left-radius: 0;
+ border-top-right-radius: 0;
}
.btn-group-justified {
display: table;
@@ -3804,8 +3798,8 @@ tbody.collapse.in {
}
.btn-group-justified > .btn,
.btn-group-justified > .btn-group {
- float: none;
display: table-cell;
+ float: none;
width: 1%;
}
.btn-group-justified > .btn-group .btn {
@@ -3829,8 +3823,8 @@ tbody.collapse.in {
}
.input-group[class*="col-"] {
float: none;
- padding-left: 0;
padding-right: 0;
+ padding-left: 0;
}
.input-group .form-control {
position: relative;
@@ -3909,10 +3903,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
font-size: 14px;
font-weight: normal;
line-height: 1;
- color: #555555;
+ color: #555;
text-align: center;
- background-color: #eeeeee;
- border: 1px solid #cccccc;
+ background-color: #eee;
+ border: 1px solid #ccc;
border-radius: 4px;
}
.input-group-addon.input-sm {
@@ -3936,8 +3930,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
- border-bottom-right-radius: 0;
border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
}
.input-group-addon:first-child {
border-right: 0;
@@ -3949,8 +3943,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
- border-bottom-left-radius: 0;
border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
}
.input-group-addon:last-child {
border-left: 0;
@@ -3981,8 +3975,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
margin-left: -1px;
}
.nav {
- margin-bottom: 0;
padding-left: 0;
+ margin-bottom: 0;
list-style: none;
}
.nav > li {
@@ -3997,22 +3991,22 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav > li > a:hover,
.nav > li > a:focus {
text-decoration: none;
- background-color: #eeeeee;
+ background-color: #eee;
}
.nav > li.disabled > a {
- color: #777777;
+ color: #777;
}
.nav > li.disabled > a:hover,
.nav > li.disabled > a:focus {
- color: #777777;
+ color: #777;
text-decoration: none;
- background-color: transparent;
cursor: not-allowed;
+ background-color: transparent;
}
.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {
- background-color: #eeeeee;
+ background-color: #eee;
border-color: #337ab7;
}
.nav .nav-divider {
@@ -4025,7 +4019,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
max-width: none;
}
.nav-tabs {
- border-bottom: 1px solid #dddddd;
+ border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
float: left;
@@ -4038,16 +4032,16 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:hover {
- border-color: #eeeeee #eeeeee #dddddd;
+ border-color: #eee #eee #ddd;
}
.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus {
- color: #555555;
- background-color: #ffffff;
- border: 1px solid #dddddd;
- border-bottom-color: transparent;
+ color: #555;
cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
}
.nav-tabs.nav-justified {
width: 100%;
@@ -4057,8 +4051,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
float: none;
}
.nav-tabs.nav-justified > li > a {
- text-align: center;
margin-bottom: 5px;
+ text-align: center;
}
.nav-tabs.nav-justified > .dropdown .dropdown-menu {
top: auto;
@@ -4080,17 +4074,17 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
- border: 1px solid #dddddd;
+ border: 1px solid #ddd;
}
@media (min-width: 768px) {
.nav-tabs.nav-justified > li > a {
- border-bottom: 1px solid #dddddd;
+ border-bottom: 1px solid #ddd;
border-radius: 4px 4px 0 0;
}
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
- border-bottom-color: #ffffff;
+ border-bottom-color: #fff;
}
}
.nav-pills > li {
@@ -4105,7 +4099,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-pills > li.active > a,
.nav-pills > li.active > a:hover,
.nav-pills > li.active > a:focus {
- color: #ffffff;
+ color: #fff;
background-color: #337ab7;
}
.nav-stacked > li {
@@ -4122,8 +4116,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
float: none;
}
.nav-justified > li > a {
- text-align: center;
margin-bottom: 5px;
+ text-align: center;
}
.nav-justified > .dropdown .dropdown-menu {
top: auto;
@@ -4148,17 +4142,17 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
- border: 1px solid #dddddd;
+ border: 1px solid #ddd;
}
@media (min-width: 768px) {
.nav-tabs-justified > li > a {
- border-bottom: 1px solid #dddddd;
+ border-bottom: 1px solid #ddd;
border-radius: 4px 4px 0 0;
}
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
- border-bottom-color: #ffffff;
+ border-bottom-color: #fff;
}
}
.tab-content > .tab-pane {
@@ -4169,8 +4163,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
.nav-tabs .dropdown-menu {
margin-top: -1px;
- border-top-right-radius: 0;
border-top-left-radius: 0;
+ border-top-right-radius: 0;
}
.navbar {
position: relative;
@@ -4189,13 +4183,13 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
}
.navbar-collapse {
- overflow-x: visible;
padding-right: 15px;
padding-left: 15px;
- border-top: 1px solid transparent;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+ overflow-x: visible;
-webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}
.navbar-collapse.in {
overflow-y: auto;
@@ -4219,8 +4213,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.navbar-fixed-top .navbar-collapse,
.navbar-static-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
- padding-left: 0;
padding-right: 0;
+ padding-left: 0;
}
}
.navbar-fixed-top .navbar-collapse,
@@ -4282,10 +4276,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
.navbar-brand {
float: left;
+ height: 50px;
padding: 15px 15px;
font-size: 18px;
line-height: 20px;
- height: 50px;
}
.navbar-brand:hover,
.navbar-brand:focus {
@@ -4303,9 +4297,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.navbar-toggle {
position: relative;
float: right;
- margin-right: 15px;
padding: 9px 10px;
margin-top: 8px;
+ margin-right: 15px;
margin-bottom: 8px;
background-color: transparent;
background-image: none;
@@ -4374,15 +4368,15 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
}
.navbar-form {
- margin-left: -15px;
- margin-right: -15px;
padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
- margin-top: 8px;
- margin-bottom: 8px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
}
@media (min-width: 768px) {
.navbar-form .form-group {
@@ -4445,24 +4439,24 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
@media (min-width: 768px) {
.navbar-form {
width: auto;
- border: 0;
- margin-left: 0;
- margin-right: 0;
padding-top: 0;
padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
-webkit-box-shadow: none;
- box-shadow: none;
+ box-shadow: none;
}
}
.navbar-nav > li > .dropdown-menu {
margin-top: 0;
- border-top-right-radius: 0;
border-top-left-radius: 0;
+ border-top-right-radius: 0;
}
.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
margin-bottom: 0;
- border-top-right-radius: 4px;
border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
@@ -4485,8 +4479,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
@media (min-width: 768px) {
.navbar-text {
float: left;
- margin-left: 15px;
margin-right: 15px;
+ margin-left: 15px;
}
}
@media (min-width: 768px) {
@@ -4506,7 +4500,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
border-color: #e7e7e7;
}
.navbar-default .navbar-brand {
- color: #777777;
+ color: #777;
}
.navbar-default .navbar-brand:hover,
.navbar-default .navbar-brand:focus {
@@ -4514,37 +4508,37 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
background-color: transparent;
}
.navbar-default .navbar-text {
- color: #777777;
+ color: #777;
}
.navbar-default .navbar-nav > li > a {
- color: #777777;
+ color: #777;
}
.navbar-default .navbar-nav > li > a:hover,
.navbar-default .navbar-nav > li > a:focus {
- color: #333333;
+ color: #333;
background-color: transparent;
}
.navbar-default .navbar-nav > .active > a,
.navbar-default .navbar-nav > .active > a:hover,
.navbar-default .navbar-nav > .active > a:focus {
- color: #555555;
+ color: #555;
background-color: #e7e7e7;
}
.navbar-default .navbar-nav > .disabled > a,
.navbar-default .navbar-nav > .disabled > a:hover,
.navbar-default .navbar-nav > .disabled > a:focus {
- color: #cccccc;
+ color: #ccc;
background-color: transparent;
}
.navbar-default .navbar-toggle {
- border-color: #dddddd;
+ border-color: #ddd;
}
.navbar-default .navbar-toggle:hover,
.navbar-default .navbar-toggle:focus {
- background-color: #dddddd;
+ background-color: #ddd;
}
.navbar-default .navbar-toggle .icon-bar {
- background-color: #888888;
+ background-color: #888;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
@@ -4553,52 +4547,52 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .open > a:hover,
.navbar-default .navbar-nav > .open > a:focus {
+ color: #555;
background-color: #e7e7e7;
- color: #555555;
}
@media (max-width: 767px) {
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
- color: #777777;
+ color: #777;
}
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
- color: #333333;
+ color: #333;
background-color: transparent;
}
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
- color: #555555;
+ color: #555;
background-color: #e7e7e7;
}
.navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
.navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
.navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
- color: #cccccc;
+ color: #ccc;
background-color: transparent;
}
}
.navbar-default .navbar-link {
- color: #777777;
+ color: #777;
}
.navbar-default .navbar-link:hover {
- color: #333333;
+ color: #333;
}
.navbar-default .btn-link {
- color: #777777;
+ color: #777;
}
.navbar-default .btn-link:hover,
.navbar-default .btn-link:focus {
- color: #333333;
+ color: #333;
}
.navbar-default .btn-link[disabled]:hover,
fieldset[disabled] .navbar-default .btn-link:hover,
.navbar-default .btn-link[disabled]:focus,
fieldset[disabled] .navbar-default .btn-link:focus {
- color: #cccccc;
+ color: #ccc;
}
.navbar-inverse {
- background-color: #222222;
+ background-color: #222;
border-color: #080808;
}
.navbar-inverse .navbar-brand {
@@ -4606,7 +4600,7 @@ fieldset[disabled] .navbar-default .btn-link:focus {
}
.navbar-inverse .navbar-brand:hover,
.navbar-inverse .navbar-brand:focus {
- color: #ffffff;
+ color: #fff;
background-color: transparent;
}
.navbar-inverse .navbar-text {
@@ -4617,30 +4611,30 @@ fieldset[disabled] .navbar-default .btn-link:focus {
}
.navbar-inverse .navbar-nav > li > a:hover,
.navbar-inverse .navbar-nav > li > a:focus {
- color: #ffffff;
+ color: #fff;
background-color: transparent;
}
.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > .active > a:focus {
- color: #ffffff;
+ color: #fff;
background-color: #080808;
}
.navbar-inverse .navbar-nav > .disabled > a,
.navbar-inverse .navbar-nav > .disabled > a:hover,
.navbar-inverse .navbar-nav > .disabled > a:focus {
- color: #444444;
+ color: #444;
background-color: transparent;
}
.navbar-inverse .navbar-toggle {
- border-color: #333333;
+ border-color: #333;
}
.navbar-inverse .navbar-toggle:hover,
.navbar-inverse .navbar-toggle:focus {
- background-color: #333333;
+ background-color: #333;
}
.navbar-inverse .navbar-toggle .icon-bar {
- background-color: #ffffff;
+ background-color: #fff;
}
.navbar-inverse .navbar-collapse,
.navbar-inverse .navbar-form {
@@ -4649,8 +4643,8 @@ fieldset[disabled] .navbar-default .btn-link:focus {
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .open > a:hover,
.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
background-color: #080808;
- color: #ffffff;
}
@media (max-width: 767px) {
.navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
@@ -4664,19 +4658,19 @@ fieldset[disabled] .navbar-default .btn-link:focus {
}
.navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
.navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
- color: #ffffff;
+ color: #fff;
background-color: transparent;
}
.navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
.navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
- color: #ffffff;
+ color: #fff;
background-color: #080808;
}
.navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
.navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
.navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
- color: #444444;
+ color: #444;
background-color: transparent;
}
}
@@ -4684,20 +4678,20 @@ fieldset[disabled] .navbar-default .btn-link:focus {
color: #9d9d9d;
}
.navbar-inverse .navbar-link:hover {
- color: #ffffff;
+ color: #fff;
}
.navbar-inverse .btn-link {
color: #9d9d9d;
}
.navbar-inverse .btn-link:hover,
.navbar-inverse .btn-link:focus {
- color: #ffffff;
+ color: #fff;
}
.navbar-inverse .btn-link[disabled]:hover,
fieldset[disabled] .navbar-inverse .btn-link:hover,
.navbar-inverse .btn-link[disabled]:focus,
fieldset[disabled] .navbar-inverse .btn-link:focus {
- color: #444444;
+ color: #444;
}
.breadcrumb {
padding: 8px 15px;
@@ -4710,12 +4704,12 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
display: inline-block;
}
.breadcrumb > li + li:before {
- content: "/\00a0";
padding: 0 5px;
- color: #cccccc;
+ color: #ccc;
+ content: "/\00a0";
}
.breadcrumb > .active {
- color: #777777;
+ color: #777;
}
.pagination {
display: inline-block;
@@ -4731,23 +4725,23 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
position: relative;
float: left;
padding: 6px 12px;
- line-height: 1.42857143;
- text-decoration: none;
- color: #337ab7;
- background-color: #ffffff;
- border: 1px solid #dddddd;
margin-left: -1px;
+ line-height: 1.42857143;
+ color: #337ab7;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
margin-left: 0;
- border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
- border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
@@ -4755,8 +4749,8 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
.pagination > li > span:focus {
z-index: 2;
color: #23527c;
- background-color: #eeeeee;
- border-color: #dddddd;
+ background-color: #eee;
+ border-color: #ddd;
}
.pagination > .active > a,
.pagination > .active > span,
@@ -4765,10 +4759,10 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
.pagination > .active > a:focus,
.pagination > .active > span:focus {
z-index: 3;
- color: #ffffff;
+ color: #fff;
+ cursor: default;
background-color: #337ab7;
border-color: #337ab7;
- cursor: default;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
@@ -4776,10 +4770,10 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
- color: #777777;
- background-color: #ffffff;
- border-color: #dddddd;
+ color: #777;
cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
}
.pagination-lg > li > a,
.pagination-lg > li > span {
@@ -4789,13 +4783,13 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
}
.pagination-lg > li:first-child > a,
.pagination-lg > li:first-child > span {
- border-bottom-left-radius: 6px;
border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
}
.pagination-lg > li:last-child > a,
.pagination-lg > li:last-child > span {
- border-bottom-right-radius: 6px;
border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
}
.pagination-sm > li > a,
.pagination-sm > li > span {
@@ -4805,19 +4799,19 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
}
.pagination-sm > li:first-child > a,
.pagination-sm > li:first-child > span {
- border-bottom-left-radius: 3px;
border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
}
.pagination-sm > li:last-child > a,
.pagination-sm > li:last-child > span {
- border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
}
.pager {
padding-left: 0;
margin: 20px 0;
- list-style: none;
text-align: center;
+ list-style: none;
}
.pager li {
display: inline;
@@ -4826,14 +4820,14 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
.pager li > span {
display: inline-block;
padding: 5px 14px;
- background-color: #ffffff;
- border: 1px solid #dddddd;
+ background-color: #fff;
+ border: 1px solid #ddd;
border-radius: 15px;
}
.pager li > a:hover,
.pager li > a:focus {
text-decoration: none;
- background-color: #eeeeee;
+ background-color: #eee;
}
.pager .next > a,
.pager .next > span {
@@ -4847,9 +4841,9 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
.pager .disabled > a:hover,
.pager .disabled > a:focus,
.pager .disabled > span {
- color: #777777;
- background-color: #ffffff;
+ color: #777;
cursor: not-allowed;
+ background-color: #fff;
}
.label {
display: inline;
@@ -4857,7 +4851,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
font-size: 75%;
font-weight: bold;
line-height: 1;
- color: #ffffff;
+ color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@@ -4865,7 +4859,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
}
a.label:hover,
a.label:focus {
- color: #ffffff;
+ color: #fff;
text-decoration: none;
cursor: pointer;
}
@@ -4877,7 +4871,7 @@ a.label:focus {
top: -1px;
}
.label-default {
- background-color: #777777;
+ background-color: #777;
}
.label-default[href]:hover,
.label-default[href]:focus {
@@ -4924,12 +4918,12 @@ a.label:focus {
padding: 3px 7px;
font-size: 12px;
font-weight: bold;
- color: #ffffff;
line-height: 1;
- vertical-align: middle;
- white-space: nowrap;
+ color: #fff;
text-align: center;
- background-color: #777777;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #777;
border-radius: 10px;
}
.badge:empty {
@@ -4946,14 +4940,14 @@ a.label:focus {
}
a.badge:hover,
a.badge:focus {
- color: #ffffff;
+ color: #fff;
text-decoration: none;
cursor: pointer;
}
.list-group-item.active > .badge,
.nav-pills > .active > a > .badge {
color: #337ab7;
- background-color: #ffffff;
+ background-color: #fff;
}
.list-group-item > .badge {
float: right;
@@ -4969,7 +4963,7 @@ a.badge:focus {
padding-bottom: 30px;
margin-bottom: 30px;
color: inherit;
- background-color: #eeeeee;
+ background-color: #eee;
}
.jumbotron h1,
.jumbotron .h1 {
@@ -4985,9 +4979,9 @@ a.badge:focus {
}
.container .jumbotron,
.container-fluid .jumbotron {
- border-radius: 6px;
- padding-left: 15px;
padding-right: 15px;
+ padding-left: 15px;
+ border-radius: 6px;
}
.jumbotron .container {
max-width: 100%;
@@ -4999,8 +4993,8 @@ a.badge:focus {
}
.container .jumbotron,
.container-fluid .jumbotron {
- padding-left: 60px;
padding-right: 60px;
+ padding-left: 60px;
}
.jumbotron h1,
.jumbotron .h1 {
@@ -5012,17 +5006,17 @@ a.badge:focus {
padding: 4px;
margin-bottom: 20px;
line-height: 1.42857143;
- background-color: #ffffff;
- border: 1px solid #dddddd;
+ background-color: #fff;
+ border: 1px solid #ddd;
border-radius: 4px;
- -webkit-transition: border 0.2s ease-in-out;
- -o-transition: border 0.2s ease-in-out;
- transition: border 0.2s ease-in-out;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
}
.thumbnail > img,
.thumbnail a > img {
- margin-left: auto;
margin-right: auto;
+ margin-left: auto;
}
a.thumbnail:hover,
a.thumbnail:focus,
@@ -5031,7 +5025,7 @@ a.thumbnail.active {
}
.thumbnail .caption {
padding: 9px;
- color: #333333;
+ color: #333;
}
.alert {
padding: 15px;
@@ -5065,9 +5059,9 @@ a.thumbnail.active {
color: inherit;
}
.alert-success {
+ color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
- color: #3c763d;
}
.alert-success hr {
border-top-color: #c9e2b3;
@@ -5076,9 +5070,9 @@ a.thumbnail.active {
color: #2b542c;
}
.alert-info {
+ color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
- color: #31708f;
}
.alert-info hr {
border-top-color: #a6e1ec;
@@ -5087,9 +5081,9 @@ a.thumbnail.active {
color: #245269;
}
.alert-warning {
+ color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
- color: #8a6d3b;
}
.alert-warning hr {
border-top-color: #f7e1b5;
@@ -5098,9 +5092,9 @@ a.thumbnail.active {
color: #66512c;
}
.alert-danger {
+ color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
- color: #a94442;
}
.alert-danger hr {
border-top-color: #e4b9c0;
@@ -5133,74 +5127,74 @@ a.thumbnail.active {
}
}
.progress {
- overflow: hidden;
height: 20px;
margin-bottom: 20px;
+ overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
}
.progress-bar {
float: left;
- width: 0%;
+ width: 0;
height: 100%;
font-size: 12px;
line-height: 20px;
- color: #ffffff;
+ color: #fff;
text-align: center;
background-color: #337ab7;
- -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
- -webkit-transition: width 0.6s ease;
- -o-transition: width 0.6s ease;
- transition: width 0.6s ease;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
}
.progress-striped .progress-bar,
.progress-bar-striped {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
-webkit-background-size: 40px 40px;
background-size: 40px 40px;
}
.progress.active .progress-bar,
.progress-bar.active {
-webkit-animation: progress-bar-stripes 2s linear infinite;
- -o-animation: progress-bar-stripes 2s linear infinite;
- animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
}
.progress-bar-success {
background-color: #5cb85c;
}
.progress-striped .progress-bar-success {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.progress-bar-info {
background-color: #5bc0de;
}
.progress-striped .progress-bar-info {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.progress-bar-warning {
background-color: #f0ad4e;
}
.progress-striped .progress-bar-warning {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.progress-bar-danger {
background-color: #d9534f;
}
.progress-striped .progress-bar-danger {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.media {
margin-top: 15px;
@@ -5210,8 +5204,8 @@ a.thumbnail.active {
}
.media,
.media-body {
- zoom: 1;
overflow: hidden;
+ zoom: 1;
}
.media-body {
width: 10000px;
@@ -5251,20 +5245,20 @@ a.thumbnail.active {
list-style: none;
}
.list-group {
- margin-bottom: 20px;
padding-left: 0;
+ margin-bottom: 20px;
}
.list-group-item {
position: relative;
display: block;
padding: 10px 15px;
margin-bottom: -1px;
- background-color: #ffffff;
- border: 1px solid #dddddd;
+ background-color: #fff;
+ border: 1px solid #ddd;
}
.list-group-item:first-child {
- border-top-right-radius: 4px;
border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
}
.list-group-item:last-child {
margin-bottom: 0;
@@ -5273,18 +5267,18 @@ a.thumbnail.active {
}
a.list-group-item,
button.list-group-item {
- color: #555555;
+ color: #555;
}
a.list-group-item .list-group-item-heading,
button.list-group-item .list-group-item-heading {
- color: #333333;
+ color: #333;
}
a.list-group-item:hover,
button.list-group-item:hover,
a.list-group-item:focus,
button.list-group-item:focus {
+ color: #555;
text-decoration: none;
- color: #555555;
background-color: #f5f5f5;
}
button.list-group-item {
@@ -5294,9 +5288,9 @@ button.list-group-item {
.list-group-item.disabled,
.list-group-item.disabled:hover,
.list-group-item.disabled:focus {
- background-color: #eeeeee;
- color: #777777;
+ color: #777;
cursor: not-allowed;
+ background-color: #eee;
}
.list-group-item.disabled .list-group-item-heading,
.list-group-item.disabled:hover .list-group-item-heading,
@@ -5306,13 +5300,13 @@ button.list-group-item {
.list-group-item.disabled .list-group-item-text,
.list-group-item.disabled:hover .list-group-item-text,
.list-group-item.disabled:focus .list-group-item-text {
- color: #777777;
+ color: #777;
}
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
z-index: 2;
- color: #ffffff;
+ color: #fff;
background-color: #337ab7;
border-color: #337ab7;
}
@@ -5458,11 +5452,11 @@ button.list-group-item-danger.active:focus {
}
.panel {
margin-bottom: 20px;
- background-color: #ffffff;
+ background-color: #fff;
border: 1px solid transparent;
border-radius: 4px;
- -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
}
.panel-body {
padding: 15px;
@@ -5470,8 +5464,8 @@ button.list-group-item-danger.active:focus {
.panel-heading {
padding: 10px 15px;
border-bottom: 1px solid transparent;
- border-top-right-radius: 3px;
border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
}
.panel-heading > .dropdown .dropdown-toggle {
color: inherit;
@@ -5492,7 +5486,7 @@ button.list-group-item-danger.active:focus {
.panel-footer {
padding: 10px 15px;
background-color: #f5f5f5;
- border-top: 1px solid #dddddd;
+ border-top: 1px solid #ddd;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
}
@@ -5508,8 +5502,8 @@ button.list-group-item-danger.active:focus {
.panel > .list-group:first-child .list-group-item:first-child,
.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
border-top: 0;
- border-top-right-radius: 3px;
border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
}
.panel > .list-group:last-child .list-group-item:last-child,
.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
@@ -5518,8 +5512,8 @@ button.list-group-item-danger.active:focus {
border-bottom-left-radius: 3px;
}
.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
- border-top-right-radius: 0;
border-top-left-radius: 0;
+ border-top-right-radius: 0;
}
.panel-heading + .list-group .list-group-item:first-child {
border-top-width: 0;
@@ -5535,13 +5529,13 @@ button.list-group-item-danger.active:focus {
.panel > .table caption,
.panel > .table-responsive > .table caption,
.panel > .panel-collapse > .table caption {
- padding-left: 15px;
padding-right: 15px;
+ padding-left: 15px;
}
.panel > .table:first-child,
.panel > .table-responsive:first-child > .table:first-child {
- border-top-right-radius: 3px;
border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
}
.panel > .table:first-child > thead:first-child > tr:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
@@ -5579,8 +5573,8 @@ button.list-group-item-danger.active:focus {
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
- border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
@@ -5606,7 +5600,7 @@ button.list-group-item-danger.active:focus {
.panel > .panel-body + .table-responsive,
.panel > .table + .panel-body,
.panel > .table-responsive + .panel-body {
- border-top: 1px solid #dddddd;
+ border-top: 1px solid #ddd;
}
.panel > .table > tbody:first-child > tr:first-child th,
.panel > .table > tbody:first-child > tr:first-child td {
@@ -5665,8 +5659,8 @@ button.list-group-item-danger.active:focus {
border-bottom: 0;
}
.panel > .table-responsive {
- border: 0;
margin-bottom: 0;
+ border: 0;
}
.panel-group {
margin-bottom: 20px;
@@ -5683,37 +5677,37 @@ button.list-group-item-danger.active:focus {
}
.panel-group .panel-heading + .panel-collapse > .panel-body,
.panel-group .panel-heading + .panel-collapse > .list-group {
- border-top: 1px solid #dddddd;
+ border-top: 1px solid #ddd;
}
.panel-group .panel-footer {
border-top: 0;
}
.panel-group .panel-footer + .panel-collapse .panel-body {
- border-bottom: 1px solid #dddddd;
+ border-bottom: 1px solid #ddd;
}
.panel-default {
- border-color: #dddddd;
+ border-color: #ddd;
}
.panel-default > .panel-heading {
- color: #333333;
+ color: #333;
background-color: #f5f5f5;
- border-color: #dddddd;
+ border-color: #ddd;
}
.panel-default > .panel-heading + .panel-collapse > .panel-body {
- border-top-color: #dddddd;
+ border-top-color: #ddd;
}
.panel-default > .panel-heading .badge {
color: #f5f5f5;
- background-color: #333333;
+ background-color: #333;
}
.panel-default > .panel-footer + .panel-collapse > .panel-body {
- border-bottom-color: #dddddd;
+ border-bottom-color: #ddd;
}
.panel-primary {
border-color: #337ab7;
}
.panel-primary > .panel-heading {
- color: #ffffff;
+ color: #fff;
background-color: #337ab7;
border-color: #337ab7;
}
@@ -5722,7 +5716,7 @@ button.list-group-item-danger.active:focus {
}
.panel-primary > .panel-heading .badge {
color: #337ab7;
- background-color: #ffffff;
+ background-color: #fff;
}
.panel-primary > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #337ab7;
@@ -5813,10 +5807,10 @@ button.list-group-item-danger.active:focus {
.embed-responsive video {
position: absolute;
top: 0;
- left: 0;
bottom: 0;
- height: 100%;
+ left: 0;
width: 100%;
+ height: 100%;
border: 0;
}
.embed-responsive-16by9 {
@@ -5832,12 +5826,12 @@ button.list-group-item-danger.active:focus {
background-color: #f5f5f5;
border: 1px solid #e3e3e3;
border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
}
.well blockquote {
border-color: #ddd;
- border-color: rgba(0, 0, 0, 0.15);
+ border-color: rgba(0, 0, 0, .15);
}
.well-lg {
padding: 24px;
@@ -5852,55 +5846,55 @@ button.list-group-item-danger.active:focus {
font-size: 21px;
font-weight: bold;
line-height: 1;
- color: #000000;
- text-shadow: 0 1px 0 #ffffff;
- opacity: 0.2;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
filter: alpha(opacity=20);
+ opacity: .2;
}
.close:hover,
.close:focus {
- color: #000000;
+ color: #000;
text-decoration: none;
cursor: pointer;
- opacity: 0.5;
filter: alpha(opacity=50);
+ opacity: .5;
}
button.close {
+ -webkit-appearance: none;
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
- -webkit-appearance: none;
}
.modal-open {
overflow: hidden;
}
.modal {
- display: none;
- overflow: hidden;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
+ display: none;
+ overflow: hidden;
-webkit-overflow-scrolling: touch;
outline: 0;
}
.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
-webkit-transform: translate(0, -25%);
- -ms-transform: translate(0, -25%);
- -o-transform: translate(0, -25%);
- transform: translate(0, -25%);
- -webkit-transition: -webkit-transform 0.3s ease-out;
- -o-transition: -o-transform 0.3s ease-out;
- transition: transform 0.3s ease-out;
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
}
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
- -ms-transform: translate(0, 0);
- -o-transform: translate(0, 0);
- transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
}
.modal-open .modal {
overflow-x: hidden;
@@ -5913,15 +5907,15 @@ button.close {
}
.modal-content {
position: relative;
- background-color: #ffffff;
- border: 1px solid #999999;
- border: 1px solid rgba(0, 0, 0, 0.2);
- border-radius: 6px;
- -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
- box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
}
.modal-backdrop {
position: fixed;
@@ -5930,15 +5924,15 @@ button.close {
bottom: 0;
left: 0;
z-index: 1040;
- background-color: #000000;
+ background-color: #000;
}
.modal-backdrop.fade {
- opacity: 0;
filter: alpha(opacity=0);
+ opacity: 0;
}
.modal-backdrop.in {
- opacity: 0.5;
filter: alpha(opacity=50);
+ opacity: .5;
}
.modal-header {
padding: 15px;
@@ -5961,8 +5955,8 @@ button.close {
border-top: 1px solid #e5e5e5;
}
.modal-footer .btn + .btn {
- margin-left: 5px;
margin-bottom: 0;
+ margin-left: 5px;
}
.modal-footer .btn-group .btn + .btn {
margin-left: -1px;
@@ -5983,8 +5977,8 @@ button.close {
margin: 30px auto;
}
.modal-content {
- -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
}
.modal-sm {
width: 300px;
@@ -6000,50 +5994,51 @@ button.close {
z-index: 1070;
display: block;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
font-style: normal;
font-weight: normal;
- letter-spacing: normal;
- line-break: auto;
line-height: 1.42857143;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
- white-space: normal;
+ letter-spacing: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
- font-size: 12px;
- opacity: 0;
+ white-space: normal;
filter: alpha(opacity=0);
+ opacity: 0;
+
+ line-break: auto;
}
.tooltip.in {
- opacity: 0.9;
filter: alpha(opacity=90);
+ opacity: .9;
}
.tooltip.top {
- margin-top: -3px;
padding: 5px 0;
+ margin-top: -3px;
}
.tooltip.right {
- margin-left: 3px;
padding: 0 5px;
+ margin-left: 3px;
}
.tooltip.bottom {
- margin-top: 3px;
padding: 5px 0;
+ margin-top: 3px;
}
.tooltip.left {
- margin-left: -3px;
padding: 0 5px;
+ margin-left: -3px;
}
.tooltip-inner {
max-width: 200px;
padding: 3px 8px;
- color: #ffffff;
+ color: #fff;
text-align: center;
- background-color: #000000;
+ background-color: #000;
border-radius: 4px;
}
.tooltip-arrow {
@@ -6058,56 +6053,56 @@ button.close {
left: 50%;
margin-left: -5px;
border-width: 5px 5px 0;
- border-top-color: #000000;
+ border-top-color: #000;
}
.tooltip.top-left .tooltip-arrow {
- bottom: 0;
right: 5px;
+ bottom: 0;
margin-bottom: -5px;
border-width: 5px 5px 0;
- border-top-color: #000000;
+ border-top-color: #000;
}
.tooltip.top-right .tooltip-arrow {
bottom: 0;
left: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0;
- border-top-color: #000000;
+ border-top-color: #000;
}
.tooltip.right .tooltip-arrow {
top: 50%;
left: 0;
margin-top: -5px;
border-width: 5px 5px 5px 0;
- border-right-color: #000000;
+ border-right-color: #000;
}
.tooltip.left .tooltip-arrow {
top: 50%;
right: 0;
margin-top: -5px;
border-width: 5px 0 5px 5px;
- border-left-color: #000000;
+ border-left-color: #000;
}
.tooltip.bottom .tooltip-arrow {
top: 0;
left: 50%;
margin-left: -5px;
border-width: 0 5px 5px;
- border-bottom-color: #000000;
+ border-bottom-color: #000;
}
.tooltip.bottom-left .tooltip-arrow {
top: 0;
right: 5px;
margin-top: -5px;
border-width: 0 5px 5px;
- border-bottom-color: #000000;
+ border-bottom-color: #000;
}
.tooltip.bottom-right .tooltip-arrow {
top: 0;
left: 5px;
margin-top: -5px;
border-width: 0 5px 5px;
- border-bottom-color: #000000;
+ border-bottom-color: #000;
}
.popover {
position: absolute;
@@ -6118,29 +6113,30 @@ button.close {
max-width: 276px;
padding: 1px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
font-style: normal;
font-weight: normal;
- letter-spacing: normal;
- line-break: auto;
line-height: 1.42857143;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
- white-space: normal;
+ letter-spacing: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
- font-size: 14px;
- background-color: #ffffff;
+ white-space: normal;
+ background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
- border: 1px solid #cccccc;
- border: 1px solid rgba(0, 0, 0, 0.2);
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
- -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+
+ line-break: auto;
}
.popover.top {
margin-top: -10px;
@@ -6155,8 +6151,8 @@ button.close {
margin-left: -10px;
}
.popover-title {
- margin: 0;
padding: 8px 14px;
+ margin: 0;
font-size: 14px;
background-color: #f7f7f7;
border-bottom: 1px solid #ebebeb;
@@ -6178,83 +6174,83 @@ button.close {
border-width: 11px;
}
.popover > .arrow:after {
- border-width: 10px;
content: "";
+ border-width: 10px;
}
.popover.top > .arrow {
+ bottom: -11px;
left: 50%;
margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
border-bottom-width: 0;
- border-top-color: #999999;
- border-top-color: rgba(0, 0, 0, 0.25);
- bottom: -11px;
}
.popover.top > .arrow:after {
- content: " ";
bottom: 1px;
margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
border-bottom-width: 0;
- border-top-color: #ffffff;
}
.popover.right > .arrow {
top: 50%;
left: -11px;
margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
border-left-width: 0;
- border-right-color: #999999;
- border-right-color: rgba(0, 0, 0, 0.25);
}
.popover.right > .arrow:after {
- content: " ";
- left: 1px;
bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
border-left-width: 0;
- border-right-color: #ffffff;
}
.popover.bottom > .arrow {
+ top: -11px;
left: 50%;
margin-left: -11px;
border-top-width: 0;
- border-bottom-color: #999999;
- border-bottom-color: rgba(0, 0, 0, 0.25);
- top: -11px;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
}
.popover.bottom > .arrow:after {
- content: " ";
top: 1px;
margin-left: -10px;
+ content: " ";
border-top-width: 0;
- border-bottom-color: #ffffff;
+ border-bottom-color: #fff;
}
.popover.left > .arrow {
top: 50%;
right: -11px;
margin-top: -11px;
border-right-width: 0;
- border-left-color: #999999;
- border-left-color: rgba(0, 0, 0, 0.25);
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25);
}
.popover.left > .arrow:after {
- content: " ";
right: 1px;
- border-right-width: 0;
- border-left-color: #ffffff;
bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
}
.carousel {
position: relative;
}
.carousel-inner {
position: relative;
- overflow: hidden;
width: 100%;
+ overflow: hidden;
}
.carousel-inner > .item {
- display: none;
position: relative;
- -webkit-transition: 0.6s ease-in-out left;
- -o-transition: 0.6s ease-in-out left;
- transition: 0.6s ease-in-out left;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
}
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
@@ -6262,32 +6258,33 @@ button.close {
}
@media all and (transform-3d), (-webkit-transform-3d) {
.carousel-inner > .item {
- -webkit-transition: -webkit-transform 0.6s ease-in-out;
- -o-transition: -o-transform 0.6s ease-in-out;
- transition: transform 0.6s ease-in-out;
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
-webkit-backface-visibility: hidden;
- backface-visibility: hidden;
+ backface-visibility: hidden;
-webkit-perspective: 1000px;
- perspective: 1000px;
+ perspective: 1000px;
}
.carousel-inner > .item.next,
.carousel-inner > .item.active.right {
- -webkit-transform: translate3d(100%, 0, 0);
- transform: translate3d(100%, 0, 0);
left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
}
.carousel-inner > .item.prev,
.carousel-inner > .item.active.left {
- -webkit-transform: translate3d(-100%, 0, 0);
- transform: translate3d(-100%, 0, 0);
left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
}
.carousel-inner > .item.next.left,
.carousel-inner > .item.prev.right,
.carousel-inner > .item.active {
- -webkit-transform: translate3d(0, 0, 0);
- transform: translate3d(0, 0, 0);
left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
}
}
.carousel-inner > .active,
@@ -6323,42 +6320,42 @@ button.close {
.carousel-control {
position: absolute;
top: 0;
- left: 0;
bottom: 0;
+ left: 0;
width: 15%;
- opacity: 0.5;
- filter: alpha(opacity=50);
font-size: 20px;
- color: #ffffff;
+ color: #fff;
text-align: center;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
background-color: rgba(0, 0, 0, 0);
+ filter: alpha(opacity=50);
+ opacity: .5;
}
.carousel-control.left {
- background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
- background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
- background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));
- background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
- background-repeat: repeat-x;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
}
.carousel-control.right {
- left: auto;
right: 0;
- background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
- background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
- background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));
- background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
- background-repeat: repeat-x;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
}
.carousel-control:hover,
.carousel-control:focus {
- outline: 0;
- color: #ffffff;
+ color: #fff;
text-decoration: none;
- opacity: 0.9;
filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
}
.carousel-control .icon-prev,
.carousel-control .icon-next,
@@ -6366,9 +6363,9 @@ button.close {
.carousel-control .glyphicon-chevron-right {
position: absolute;
top: 50%;
- margin-top: -10px;
z-index: 5;
display: inline-block;
+ margin-top: -10px;
}
.carousel-control .icon-prev,
.carousel-control .glyphicon-chevron-left {
@@ -6384,8 +6381,8 @@ button.close {
.carousel-control .icon-next {
width: 20px;
height: 20px;
- line-height: 1;
font-family: serif;
+ line-height: 1;
}
.carousel-control .icon-prev:before {
content: '\2039';
@@ -6399,10 +6396,10 @@ button.close {
left: 50%;
z-index: 15;
width: 60%;
- margin-left: -30%;
padding-left: 0;
- list-style: none;
+ margin-left: -30%;
text-align: center;
+ list-style: none;
}
.carousel-indicators li {
display: inline-block;
@@ -6410,29 +6407,29 @@ button.close {
height: 10px;
margin: 1px;
text-indent: -999px;
- border: 1px solid #ffffff;
- border-radius: 10px;
cursor: pointer;
background-color: #000 \9;
background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
}
.carousel-indicators .active {
- margin: 0;
width: 12px;
height: 12px;
- background-color: #ffffff;
+ margin: 0;
+ background-color: #fff;
}
.carousel-caption {
position: absolute;
- left: 15%;
right: 15%;
bottom: 20px;
+ left: 15%;
z-index: 10;
padding-top: 20px;
padding-bottom: 20px;
- color: #ffffff;
+ color: #fff;
text-align: center;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}
.carousel-caption .btn {
text-shadow: none;
@@ -6456,8 +6453,8 @@ button.close {
margin-right: -10px;
}
.carousel-caption {
- left: 20%;
right: 20%;
+ left: 20%;
padding-bottom: 30px;
}
.carousel-indicators {
@@ -6496,8 +6493,8 @@ button.close {
.modal-header:after,
.modal-footer:before,
.modal-footer:after {
- content: " ";
display: table;
+ content: " ";
}
.clearfix:after,
.dl-horizontal dd:after,
@@ -6519,8 +6516,8 @@ button.close {
}
.center-block {
display: block;
- margin-left: auto;
margin-right: auto;
+ margin-left: auto;
}
.pull-right {
float: right !important;
diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java b/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java
index c9a8005e..a05571fd 100644
--- a/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java
+++ b/docs-web/src/test/java/com/sismics/docs/rest/TestSecurity.java
@@ -6,7 +6,7 @@ import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
-import junit.framework.Assert;
+import org.junit.Assert;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
diff --git a/docs-web/src/test/resources/hibernate.properties b/docs-web/src/test/resources/hibernate.properties
index edd32f92..2c068af9 100644
--- a/docs-web/src/test/resources/hibernate.properties
+++ b/docs-web/src/test/resources/hibernate.properties
@@ -2,9 +2,13 @@ hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:mem:docs
hibernate.connection.username=sa
hibernate.connection.password=
-hibernate.hbm2ddl.auto=none
+hibernate.hbm2ddl.auto=
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.show_sql=true
hibernate.format_sql=false
hibernate.max_fetch_depth=5
hibernate.cache.use_second_level_cache=false
+hibernate.c3p0.min_size=1
+hibernate.c3p0.max_size=10
+hibernate.c3p0.timeout=0
+hibernate.c3p0.max_statements=0
\ No newline at end of file