Added example.
@@ -0,0 +1,65 @@
|
||||
|
||||
package controllers;
|
||||
|
||||
import helpers.ConfigManager;
|
||||
import helpers.DocumentManager;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import entities.FileModel;
|
||||
|
||||
|
||||
@WebServlet(name = "EditorServlet", urlPatterns = {"/EditorServlet"})
|
||||
public class EditorServlet extends HttpServlet {
|
||||
|
||||
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
String mode = request.getParameter("mode");
|
||||
String fileExt = request.getParameter("fileExt");
|
||||
String fileName = request.getParameter("fileName");
|
||||
|
||||
DocumentManager.Init(request, response);
|
||||
|
||||
if(fileExt != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fileName = DocumentManager.CreateDemo(fileExt);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
response.getWriter().write("Error: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Boolean desktopMode = !"embedded".equals(mode);
|
||||
|
||||
FileModel file = new FileModel();
|
||||
file.SetTypeDesktop(desktopMode);
|
||||
file.SetFileName(fileName);
|
||||
|
||||
request.setAttribute("file", file);
|
||||
request.setAttribute("mode", mode);
|
||||
request.setAttribute("type", desktopMode ? "desktop" : "embedded");
|
||||
request.setAttribute("docserviceApiUrl", ConfigManager.GetProperty("files.docservice.url.api"));
|
||||
request.getRequestDispatcher("editor.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
processRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
processRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletInfo() {
|
||||
return "Short description";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
|
||||
package controllers;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
public class GlobalServletContextListener implements ServletContextListener{
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent arg0) {
|
||||
System.out.println("ServletContextListener destroyed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent arg0) {
|
||||
|
||||
TrustManager[] trustAllCerts = new TrustManager[] {
|
||||
new X509TrustManager() {
|
||||
|
||||
@Override
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] certs, String authType)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] certs, String authType)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
SSLContext sc;
|
||||
|
||||
try
|
||||
{
|
||||
sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyManagementException ex)
|
||||
{
|
||||
}
|
||||
|
||||
HostnameVerifier allHostsValid = new HostnameVerifier() {
|
||||
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
|
||||
|
||||
System.out.println("ServletContextListener started");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
package controllers;
|
||||
|
||||
import helpers.DocumentManager;
|
||||
import helpers.ServiceConverter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URL;
|
||||
import java.util.Scanner;
|
||||
import javafx.util.Pair;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.MultipartConfig;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
import entities.FileType;
|
||||
import helpers.FileUtility;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
@WebServlet(name = "IndexServlet", urlPatterns = {"/IndexServlet"})
|
||||
@MultipartConfig
|
||||
public class IndexServlet extends HttpServlet {
|
||||
|
||||
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
String action = request.getParameter("type");
|
||||
|
||||
if(action == null)
|
||||
{
|
||||
request.getRequestDispatcher("index.jsp").forward(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentManager.Init(request, response);
|
||||
PrintWriter writer = response.getWriter();
|
||||
|
||||
switch (action.toLowerCase()) {
|
||||
case "upload":
|
||||
Upload(request, response, writer);
|
||||
break;
|
||||
case "convert":
|
||||
Convert(request, response, writer);
|
||||
break;
|
||||
case "save":
|
||||
Save(request, response, writer);
|
||||
break;
|
||||
case "track":
|
||||
Track(request, response, writer);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void Upload(HttpServletRequest request, HttpServletResponse response, PrintWriter writer) {
|
||||
response.setContentType("text/plain");
|
||||
|
||||
try
|
||||
{
|
||||
Part httpPostedFile = request.getPart("file");
|
||||
|
||||
String fileName = "";
|
||||
for (String content : httpPostedFile.getHeader("content-disposition").split(";")) {
|
||||
if (content.trim().startsWith("filename")) {
|
||||
fileName = content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
|
||||
}
|
||||
}
|
||||
|
||||
long curSize = httpPostedFile.getSize();
|
||||
if (DocumentManager.GetMaxFileSize() < curSize || curSize <= 0) {
|
||||
writer.write("{ \"error\": \"File size is incorrect\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
String curExt = FileUtility.GetFileExtension(fileName);
|
||||
if (!DocumentManager.GetFileExts().contains(curExt)) {
|
||||
writer.write("{ \"error\": \"File type is not supported\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream fileStream = httpPostedFile.getInputStream();
|
||||
|
||||
fileName = DocumentManager.GetCorrectName(fileName);
|
||||
String fileStoragePath = DocumentManager.StoragePath(fileName, null);
|
||||
|
||||
File file = new File(fileStoragePath);
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = fileStream.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
writer.write("{ \"filename\": \"" + fileName + "\"}");
|
||||
|
||||
}
|
||||
catch (IOException | ServletException e)
|
||||
{
|
||||
writer.write("{ \"error\": \"" + e.getMessage() + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Convert(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
|
||||
{
|
||||
response.setContentType("text/plain");
|
||||
|
||||
try
|
||||
{
|
||||
String fileName = request.getParameter("filename");
|
||||
String fileUri = DocumentManager.GetFileUri(fileName);
|
||||
String fileExt = FileUtility.GetFileExtension(fileName);
|
||||
FileType fileType = FileUtility.GetFileType(fileName);
|
||||
String internalFileExt = DocumentManager.GetInternalExtension(fileType);
|
||||
|
||||
if (DocumentManager.GetConvertExts().contains(fileExt))
|
||||
{
|
||||
String key = ServiceConverter.GenerateRevisionId(fileUri);
|
||||
|
||||
Pair<Integer, String> res = ServiceConverter.GetConvertedUri(fileUri, fileExt, internalFileExt, key, true);
|
||||
|
||||
int result = res.getKey();
|
||||
String newFileUri = res.getValue();
|
||||
|
||||
if (result != 100)
|
||||
{
|
||||
writer.write("{ \"step\" : \"" + result + "\", \"filename\" : \"" + fileName + "\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
String correctName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + internalFileExt);
|
||||
|
||||
URL url = new URL(newFileUri);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
InputStream stream = connection.getInputStream();
|
||||
|
||||
if (stream == null) {
|
||||
throw new Exception("Stream is null");
|
||||
}
|
||||
|
||||
File convertedFile = new File(DocumentManager.StoragePath(correctName, null));
|
||||
try (FileOutputStream out = new FileOutputStream(convertedFile)) {
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = stream.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
//remove source file ?
|
||||
//File sourceFile = new File(DocumentManager.StoragePath(fileName, null));
|
||||
//sourceFile.delete();
|
||||
|
||||
fileName = correctName;
|
||||
}
|
||||
|
||||
writer.write("{ \"filename\" : \"" + fileName + "\"}");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("{ \"error\": \"" + ex.getMessage() + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Save(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
|
||||
{
|
||||
response.setContentType("text/plain");
|
||||
|
||||
String downloadUri = request.getParameter("fileuri");
|
||||
String fileName = request.getParameter("filename");
|
||||
String fileType = request.getParameter("filetype");
|
||||
|
||||
if (downloadUri == null || fileName == null || downloadUri.isEmpty() || fileName.isEmpty()) {
|
||||
writer.write("error: empty fileuri or filename");
|
||||
return;
|
||||
}
|
||||
|
||||
if(fileType == null || fileType.isEmpty())
|
||||
{
|
||||
fileType = FileUtility.GetFileExtension(fileName).replace(".", "");
|
||||
}
|
||||
|
||||
String newType = FileUtility.GetFileExtension(downloadUri).replace(".", "");
|
||||
|
||||
|
||||
if (!newType.equalsIgnoreCase(fileType)) {
|
||||
String key = ServiceConverter.GenerateRevisionId(downloadUri);
|
||||
String newFileUri = "";
|
||||
|
||||
try
|
||||
{
|
||||
Pair<Integer, String> res = ServiceConverter.GetConvertedUri(downloadUri, newType, fileType, key, false);
|
||||
|
||||
int result = res.getKey();
|
||||
newFileUri = res.getValue();
|
||||
|
||||
if (result != 100)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("error:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
downloadUri = newFileUri;
|
||||
newType = fileType;
|
||||
}
|
||||
|
||||
fileName = FileUtility.GetFileNameWithoutExtension(fileName) + "." + newType;
|
||||
|
||||
try
|
||||
{
|
||||
URL url = new URL(downloadUri);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
InputStream stream = connection.getInputStream();
|
||||
|
||||
if (stream == null) {
|
||||
throw new Exception("Stream is null");
|
||||
}
|
||||
|
||||
File savedFile = new File(DocumentManager.StoragePath(fileName, null));
|
||||
try (FileOutputStream out = new FileOutputStream(savedFile)) {
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = stream.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
connection.disconnect();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("error:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
writer.write("success");
|
||||
}
|
||||
|
||||
private static void Track(HttpServletRequest request, HttpServletResponse response, PrintWriter writer) {
|
||||
String userAddress = request.getParameter("userAddress");
|
||||
String fileName = request.getParameter("fileName");
|
||||
|
||||
String storagePath = DocumentManager.StoragePath(fileName, userAddress);
|
||||
String body = "";
|
||||
|
||||
try
|
||||
{
|
||||
Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
|
||||
body = scanner.hasNext() ? scanner.next() : "";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("get request.getInputStream error:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (body.isEmpty())
|
||||
{
|
||||
writer.write("empty request.getInputStream");
|
||||
return;
|
||||
}
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject jsonObj;
|
||||
|
||||
try
|
||||
{
|
||||
Object obj = parser.parse(body);
|
||||
jsonObj = (JSONObject) obj;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writer.write("JSONParser.parse error:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
long status = (long) jsonObj.get("status");
|
||||
|
||||
if(status == 2 || status == 3)//MustSave, Corrupted
|
||||
{
|
||||
String downloadUri = (String) jsonObj.get("url");
|
||||
|
||||
int saved = 1;
|
||||
try
|
||||
{
|
||||
URL url = new URL(downloadUri);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
InputStream stream = connection.getInputStream();
|
||||
|
||||
if (stream == null) {
|
||||
throw new Exception("Stream is null");
|
||||
}
|
||||
|
||||
File savedFile = new File(storagePath);
|
||||
try (FileOutputStream out = new FileOutputStream(savedFile)) {
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = stream.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
saved = 0;
|
||||
}
|
||||
|
||||
writer.write("{{\"c\":\"saved\",\"status\":" + saved + "}}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
processRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
processRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletInfo() {
|
||||
return "Short description";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
package entities;
|
||||
|
||||
import helpers.DocumentManager;
|
||||
import helpers.ServiceConverter;
|
||||
import helpers.FileUtility;
|
||||
|
||||
public class FileModel
|
||||
{
|
||||
private String FileName;
|
||||
private Boolean TypeDesktop;
|
||||
|
||||
public String GetFileName()
|
||||
{
|
||||
return FileName;
|
||||
}
|
||||
|
||||
public void SetFileName(String fileName)
|
||||
{
|
||||
this.FileName = fileName;
|
||||
}
|
||||
|
||||
public Boolean GetTypeDesktop()
|
||||
{
|
||||
return TypeDesktop;
|
||||
}
|
||||
|
||||
public void SetTypeDesktop(Boolean typeDesktop)
|
||||
{
|
||||
this.TypeDesktop = typeDesktop;
|
||||
}
|
||||
|
||||
public String GetFileUri() throws Exception
|
||||
{
|
||||
return DocumentManager.GetFileUri(FileName);
|
||||
}
|
||||
|
||||
public String GetDocumentType()
|
||||
{
|
||||
return FileUtility.GetFileType(FileName).toString().toLowerCase();
|
||||
}
|
||||
|
||||
public String GetKey()
|
||||
{
|
||||
return ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + FileName);
|
||||
}
|
||||
|
||||
public String GetValidateKey()
|
||||
{
|
||||
return ServiceConverter.GenerateValidateKey(GetKey());
|
||||
}
|
||||
|
||||
public String GetCallbackUrl()
|
||||
{
|
||||
return DocumentManager.GetCallback(FileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
package entities;
|
||||
|
||||
public enum FileType {
|
||||
Text,
|
||||
Spreadsheet,
|
||||
Presentation
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
|
||||
package entities;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
|
||||
public class Signature {
|
||||
|
||||
static {}
|
||||
|
||||
public static String Create(Date expire, String key, Object key_id, int user_count, String ip, String secret)
|
||||
{
|
||||
try
|
||||
{
|
||||
JSONObject jsonObj = new JSONObject();
|
||||
|
||||
jsonObj.put("expire", "/Date("+ expire.getTime() +")/");
|
||||
jsonObj.put("key", key);
|
||||
jsonObj.put("key_id", key_id);
|
||||
jsonObj.put("user_count", user_count);
|
||||
jsonObj.put("ip", ip == null ? "" : ip);
|
||||
|
||||
String str = jsonObj.toString();
|
||||
String payload = GetHashBase64(str + secret) + "?" + str;
|
||||
|
||||
return UrlTokenEncode(payload.getBytes("UTF-8"));
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String GetHashBase64(String str)
|
||||
{
|
||||
try
|
||||
{
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
md.update(str.getBytes("UTF-8"));
|
||||
return Base64.getEncoder().encodeToString(md.digest());
|
||||
}
|
||||
catch (NoSuchAlgorithmException | UnsupportedEncodingException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String UrlTokenEncode(byte [] input)
|
||||
{
|
||||
if (input == null)
|
||||
return null;
|
||||
|
||||
if (input.length < 1)
|
||||
return "";
|
||||
|
||||
String base64Str = null;
|
||||
int endPos = 0;
|
||||
char[] base64Chars = null;
|
||||
|
||||
// Step 1: Do a Base64 encoding
|
||||
base64Str = Base64.getEncoder().encodeToString(input);
|
||||
if (base64Str == null)
|
||||
return null;
|
||||
|
||||
// Step 2: Find how many padding chars are present in the end
|
||||
for (endPos = base64Str.length(); endPos > 0; endPos--)
|
||||
{
|
||||
if (base64Str.charAt(endPos - 1) != '=') // Found a non-padding char!
|
||||
{
|
||||
break; // Stop here
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Create char array to store all non-padding chars,
|
||||
// plus a char to indicate how many padding chars are needed
|
||||
base64Chars = new char[endPos + 1];
|
||||
base64Chars[endPos] = (char)((int)'0' + base64Str.length() - endPos); // Store a char at the end, to indicate how many padding chars are needed
|
||||
|
||||
// Step 3: Copy in the other chars. Transform the "+" to "-", and "/" to "_"
|
||||
for (int iter = 0; iter < endPos; iter++)
|
||||
{
|
||||
char c = base64Str.charAt(iter);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '+':
|
||||
base64Chars[iter] = '-';
|
||||
break;
|
||||
|
||||
case '/':
|
||||
base64Chars[iter] = '_';
|
||||
break;
|
||||
|
||||
case '=':
|
||||
base64Chars[iter] = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
base64Chars[iter] = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new String(base64Chars);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
package helpers;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private static Properties properties;
|
||||
|
||||
static
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
private static void Init()
|
||||
{
|
||||
try
|
||||
{
|
||||
properties = new Properties();
|
||||
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("settings.properties");
|
||||
properties.load(stream);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
properties = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String GetProperty(String name){
|
||||
if(properties == null)
|
||||
return "";
|
||||
|
||||
String property = properties.getProperty(name);
|
||||
|
||||
return property == null ? "" : property;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
|
||||
package helpers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javafx.util.Pair;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import entities.FileType;
|
||||
|
||||
|
||||
public class DocumentManager
|
||||
{
|
||||
private static HttpServletRequest request;
|
||||
private static HttpServletResponse response;
|
||||
|
||||
private static final Map<String, String> CacheMap = new HashMap<>();
|
||||
private static final String ExternalIPCacheKey = "ExternalIPCacheKey";
|
||||
|
||||
public static void Init(HttpServletRequest req, HttpServletResponse resp){
|
||||
request = req;
|
||||
response = resp;
|
||||
}
|
||||
|
||||
public static long GetMaxFileSize()
|
||||
{
|
||||
long size;
|
||||
|
||||
try
|
||||
{
|
||||
size = Long.parseLong(ConfigManager.GetProperty("filesize-max"));
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
|
||||
return size > 0 ? size : 5 * 1024 * 1024;
|
||||
}
|
||||
|
||||
public static List<String> GetFileExts()
|
||||
{
|
||||
List<String> res = new ArrayList<>();
|
||||
|
||||
res.addAll(GetViewedExts());
|
||||
res.addAll(GetEditedExts());
|
||||
res.addAll(GetConvertExts());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static List<String> GetViewedExts()
|
||||
{
|
||||
String exts = ConfigManager.GetProperty("files.docservice.viewed-docs");
|
||||
return Arrays.asList(exts.split("\\|"));
|
||||
}
|
||||
|
||||
public static List<String> GetEditedExts()
|
||||
{
|
||||
String exts = ConfigManager.GetProperty("files.docservice.edited-docs");
|
||||
return Arrays.asList(exts.split("\\|"));
|
||||
}
|
||||
|
||||
public static List<String> GetConvertExts()
|
||||
{
|
||||
String exts = ConfigManager.GetProperty("files.docservice.convert-docs");
|
||||
return Arrays.asList(exts.split("\\|"));
|
||||
}
|
||||
|
||||
public static String CurUserHostAddress(String userAddress)
|
||||
{
|
||||
if(userAddress == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
userAddress = InetAddress.getLocalHost().getHostAddress();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
userAddress = "";
|
||||
}
|
||||
}
|
||||
|
||||
return userAddress.replaceAll("[^0-9a-zA-Z.=]", "_");
|
||||
}
|
||||
|
||||
public static String StoragePath(String fileName, String userAddress)
|
||||
{
|
||||
String serverPath = request.getSession().getServletContext().getRealPath("");
|
||||
String storagePath = ConfigManager.GetProperty("storage-folder");
|
||||
String hostAddress = CurUserHostAddress(userAddress);
|
||||
|
||||
String directory = serverPath + "\\" + storagePath + "\\";
|
||||
|
||||
File file = new File(directory);
|
||||
|
||||
if (!file.exists())
|
||||
{
|
||||
file.mkdir();
|
||||
}
|
||||
|
||||
directory = directory + hostAddress + "\\";
|
||||
file = new File(directory);
|
||||
|
||||
if (!file.exists())
|
||||
{
|
||||
file.mkdir();
|
||||
}
|
||||
|
||||
return directory + fileName;
|
||||
}
|
||||
|
||||
public static String GetCorrectName(String fileName)
|
||||
{
|
||||
String baseName = FileUtility.GetFileNameWithoutExtension(fileName);
|
||||
String ext = FileUtility.GetFileExtension(fileName);
|
||||
String name = baseName + ext;
|
||||
|
||||
File file = new File(StoragePath(name, null));
|
||||
|
||||
for (int i = 1; file.exists(); i++)
|
||||
{
|
||||
name = baseName + " (" + i + ")" + ext;
|
||||
file = new File(StoragePath(name, null));
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String CreateDemo(String fileExt) throws Exception
|
||||
{
|
||||
String demoName = "sample." + fileExt;
|
||||
String fileName = GetCorrectName(demoName);
|
||||
|
||||
try
|
||||
{
|
||||
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(demoName);
|
||||
|
||||
File file = new File(StoragePath(fileName, null));
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = stream.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, read);
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static String GetFileUri(String fileName) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
String serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
|
||||
String storagePath = ConfigManager.GetProperty("storage-folder");
|
||||
String hostAddress = CurUserHostAddress(null);
|
||||
|
||||
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + URLEncoder.encode(fileName);
|
||||
|
||||
if (HaveExternalIP(filePath))
|
||||
{
|
||||
return filePath;
|
||||
}
|
||||
|
||||
return GetExternalUri(filePath);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static String GetCallback(String fileName)
|
||||
{
|
||||
String serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
|
||||
String hostAddress = CurUserHostAddress(null);
|
||||
String query = "?type=track&userAddress=" + URLEncoder.encode(hostAddress) + "&fileName=" + URLEncoder.encode(fileName);
|
||||
|
||||
return serverPath + "/IndexServlet" + query;
|
||||
}
|
||||
|
||||
public static Boolean HaveExternalIP(String filePath)
|
||||
{
|
||||
if(CacheMap.containsKey(ExternalIPCacheKey))
|
||||
return Boolean.parseBoolean(CacheMap.get(ExternalIPCacheKey));
|
||||
|
||||
Boolean haveExternalIP = false;
|
||||
|
||||
try
|
||||
{
|
||||
String extension = FileUtility.GetFileExtension(filePath);
|
||||
String internalExtension = GetInternalExtension(FileUtility.GetFileType(filePath));
|
||||
|
||||
Pair<Integer, String> res = ServiceConverter.GetConvertedUri(filePath, extension, internalExtension, UUID.randomUUID().toString(), false);
|
||||
|
||||
if(res != null)
|
||||
{
|
||||
haveExternalIP = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
haveExternalIP = false;
|
||||
}
|
||||
|
||||
CacheMap.put(ExternalIPCacheKey, haveExternalIP.toString());
|
||||
|
||||
return haveExternalIP;
|
||||
}
|
||||
|
||||
public static String GetExternalUri(String localUri) throws Exception
|
||||
{
|
||||
String documentRevisionId = ServiceConverter.GenerateRevisionId(localUri);
|
||||
|
||||
if(CacheMap.containsKey(documentRevisionId))
|
||||
return CacheMap.get(documentRevisionId);
|
||||
|
||||
try
|
||||
{
|
||||
URL url = new URL(localUri);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
String contentType = connection.getContentType();
|
||||
|
||||
String externalUri = ServiceConverter.GetExternalUri(inputStream, inputStream.available(), contentType, documentRevisionId);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
CacheMap.put(documentRevisionId, externalUri);
|
||||
|
||||
return externalUri;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static String GetInternalExtension(FileType fileType)
|
||||
{
|
||||
if(fileType.equals(FileType.Text))
|
||||
return ".docx";
|
||||
|
||||
if(fileType.equals(FileType.Spreadsheet))
|
||||
return ".xlsx";
|
||||
|
||||
if(fileType.equals(FileType.Presentation))
|
||||
return ".pptx";
|
||||
|
||||
return ".docx";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
|
||||
package helpers;
|
||||
|
||||
import entities.FileType;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FileUtility
|
||||
{
|
||||
static {}
|
||||
|
||||
public static FileType GetFileType(String fileName)
|
||||
{
|
||||
String ext = GetFileExtension(fileName).toLowerCase();
|
||||
|
||||
if (ExtsDocument.contains(ext))
|
||||
return FileType.Text;
|
||||
|
||||
if (ExtsSpreadsheet.contains(ext))
|
||||
return FileType.Spreadsheet;
|
||||
|
||||
if (ExtsPresentation.contains(ext))
|
||||
return FileType.Presentation;
|
||||
|
||||
return FileType.Text;
|
||||
}
|
||||
|
||||
public static List<String> ExtsDocument = Arrays.asList
|
||||
(
|
||||
".docx", ".doc", ".odt", ".rtf", ".txt",
|
||||
".html", ".htm", ".mht", ".pdf", ".djvu",
|
||||
".fb2", ".epub", ".xps"
|
||||
);
|
||||
|
||||
public static List<String> ExtsSpreadsheet = Arrays.asList
|
||||
(
|
||||
".xls", ".xlsx", ".ods", ".csv"
|
||||
);
|
||||
|
||||
public static List<String> ExtsPresentation = Arrays.asList
|
||||
(
|
||||
".ppt", ".pptx",".odp"
|
||||
);
|
||||
|
||||
|
||||
public static String GetFileName (String url)
|
||||
{
|
||||
if(url == null) return null;
|
||||
|
||||
//for external file url
|
||||
String tempstorage = ConfigManager.GetProperty("files.docservice.url.tempstorage");
|
||||
if(!tempstorage.isEmpty() && url.startsWith(tempstorage))
|
||||
{
|
||||
Map<String, String> params = GetUrlParams(url);
|
||||
return params == null ? null : params.get("filename");
|
||||
}
|
||||
|
||||
String fileName = url.substring(url.lastIndexOf('/')+1, url.length());
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static String GetFileNameWithoutExtension (String url)
|
||||
{
|
||||
String fileName = GetFileName(url);
|
||||
if(fileName == null) return null;
|
||||
String fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
return fileNameWithoutExt;
|
||||
}
|
||||
|
||||
public static String GetFileExtension (String url)
|
||||
{
|
||||
String fileName = GetFileName(url);
|
||||
if(fileName == null) return null;
|
||||
String fileExt = fileName.substring(fileName.lastIndexOf("."));
|
||||
return fileExt.toLowerCase();
|
||||
}
|
||||
|
||||
public static Map<String, String> GetUrlParams (String url)
|
||||
{
|
||||
try
|
||||
{
|
||||
String query = new URL(url).getQuery();
|
||||
String[] params = query.split("&");
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (String param : params)
|
||||
{
|
||||
String name = param.split("=")[0];
|
||||
String value = param.split("=")[1];
|
||||
map.put(name, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
|
||||
package helpers;
|
||||
|
||||
import entities.Signature;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import javafx.util.Pair;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class ServiceConverter
|
||||
{
|
||||
private static int ConvertTimeout = 120000;
|
||||
private static final String DocumentConverterUrl = ConfigManager.GetProperty("files.docservice.url.converter");
|
||||
private static final String DocumentStorageUrl = ConfigManager.GetProperty("files.docservice.url.storage");
|
||||
private static final MessageFormat ConvertParams = new MessageFormat("?url={0}&outputtype={1}&filetype={2}&title={3}&key={4}&vkey={5}");
|
||||
private static final int MaxTry = 3;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
int timeout = Integer.parseInt(ConfigManager.GetProperty("files.docservice.timeout"));
|
||||
if(timeout > 0)
|
||||
{
|
||||
ConvertTimeout = timeout;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static Pair<Integer, String> GetConvertedUri(String documentUri, String fromExtension, String toExtension, String documentRevisionId, Boolean isAsync) throws Exception
|
||||
{
|
||||
String convertedDocumentUri = null;
|
||||
|
||||
String xml = SendRequestToConvertService(documentUri, fromExtension, toExtension, documentRevisionId, isAsync);
|
||||
|
||||
Document document = ConvertStringToXmlDocument(xml);
|
||||
|
||||
Element responceFromConvertService = document.getDocumentElement();
|
||||
if (responceFromConvertService == null)
|
||||
throw new Exception("Invalid answer format");
|
||||
|
||||
NodeList errorElement = responceFromConvertService.getElementsByTagName("Error");
|
||||
if (errorElement != null && errorElement.getLength() > 0)
|
||||
ProcessConvertServiceResponceError(Integer.parseInt(errorElement.item(0).getTextContent()));
|
||||
|
||||
NodeList endConvertNode = responceFromConvertService.getElementsByTagName("EndConvert");
|
||||
if (endConvertNode == null || endConvertNode.getLength() == 0)
|
||||
throw new Exception("EndConvert node is null");
|
||||
|
||||
Boolean isEndConvert = Boolean.parseBoolean(endConvertNode.item(0).getTextContent());
|
||||
|
||||
NodeList percentNode = responceFromConvertService.getElementsByTagName("Percent");
|
||||
if (percentNode == null || percentNode.getLength() == 0)
|
||||
throw new Exception("Percent node is null");
|
||||
|
||||
Integer percent = Integer.parseInt(percentNode.item(0).getTextContent());
|
||||
|
||||
if (isEndConvert)
|
||||
{
|
||||
NodeList fileUrlNode = responceFromConvertService.getElementsByTagName("FileUrl");
|
||||
if (fileUrlNode == null || fileUrlNode.getLength() == 0)
|
||||
throw new Exception("FileUrl node is null");
|
||||
|
||||
convertedDocumentUri = fileUrlNode.item(0).getTextContent();
|
||||
percent = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
percent = percent >= 100 ? 99 : percent;
|
||||
}
|
||||
|
||||
return new Pair<>(percent, convertedDocumentUri);
|
||||
}
|
||||
|
||||
public static String GetExternalUri(InputStream fileStream, long contentLength, String contentType, String documentRevisionId) throws IOException, Exception
|
||||
{
|
||||
String validateKey = GenerateValidateKey(documentRevisionId, false);
|
||||
|
||||
Object[] args = {"", "", "", "", documentRevisionId, validateKey};
|
||||
|
||||
String urlTostorage = DocumentStorageUrl + ConvertParams.format(args);
|
||||
|
||||
URL url = new URL(urlTostorage);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
|
||||
connection.setDoOutput(true);
|
||||
connection.setDoInput(true);
|
||||
connection.setInstanceFollowRedirects(false);
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", contentType == null ? "application/octet-stream" : contentType);
|
||||
connection.setRequestProperty("charset", "utf-8");
|
||||
connection.setRequestProperty("Content-Length", Long.toString(contentLength));
|
||||
connection.setUseCaches (false);
|
||||
|
||||
try (DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream())) {
|
||||
int read;
|
||||
final byte[] bytes = new byte[1024];
|
||||
while ((read = fileStream.read(bytes)) != -1) {
|
||||
dataOutputStream.write(bytes, 0, read);
|
||||
}
|
||||
|
||||
dataOutputStream.flush();
|
||||
}
|
||||
|
||||
InputStream stream = connection.getInputStream();
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw new Exception("Could not get an answer");
|
||||
}
|
||||
|
||||
String xml = ConvertStreamToString(stream);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
Pair <Integer, String> res = GetResponseUri(xml);
|
||||
|
||||
return res.getValue();
|
||||
}
|
||||
|
||||
public static String GenerateRevisionId(String expectedKey)
|
||||
{
|
||||
if (expectedKey.length() > 20)
|
||||
expectedKey = Integer.toString(expectedKey.hashCode());
|
||||
|
||||
String key = expectedKey.replace("[^0-9-.a-zA-Z_=]", "_");
|
||||
|
||||
return key.substring(0, Math.min(key.length(), 20));
|
||||
}
|
||||
|
||||
public static String GenerateValidateKey(String documentRevisionId)
|
||||
{
|
||||
return GenerateValidateKey(documentRevisionId, true);
|
||||
}
|
||||
|
||||
private static String GenerateValidateKey(String documentRevisionId, Boolean addHostForValidate)
|
||||
{
|
||||
if (documentRevisionId.isEmpty()) return "";
|
||||
|
||||
Date expdate = new Date();
|
||||
documentRevisionId = GenerateRevisionId(documentRevisionId);
|
||||
Object key = GetKey();
|
||||
int userCount = 0;
|
||||
String userIp = null;
|
||||
String skey = GetSKey();
|
||||
|
||||
if (addHostForValidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
userIp = InetAddress.getLocalHost().getHostAddress();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return Signature.Create(expdate, documentRevisionId, key, userCount, userIp, skey);
|
||||
}
|
||||
|
||||
private static Object GetKey()
|
||||
{
|
||||
String prop = ConfigManager.GetProperty("files.docservice.tenantid");
|
||||
return prop == null ? "OnlineEditorsExampleMVC" : prop;
|
||||
}
|
||||
|
||||
private static String GetSKey()
|
||||
{
|
||||
String prop = ConfigManager.GetProperty("files.docservice.key");
|
||||
return prop == null ? "ONLYOFFICE" : prop;
|
||||
}
|
||||
|
||||
private static String SendRequestToConvertService(String documentUri, String fromExtension, String toExtension, String documentRevisionId, Boolean isAsync) throws Exception
|
||||
{
|
||||
fromExtension = fromExtension == null || fromExtension.isEmpty() ? FileUtility.GetFileExtension(documentUri) : fromExtension;
|
||||
|
||||
String title = FileUtility.GetFileName(documentUri);
|
||||
title = title == null || title.isEmpty() ? UUID.randomUUID().toString() : title;
|
||||
|
||||
documentRevisionId = documentRevisionId == null || documentRevisionId.isEmpty() ? documentUri : documentRevisionId;
|
||||
|
||||
documentRevisionId = GenerateRevisionId(documentRevisionId);
|
||||
|
||||
String validateKey = GenerateValidateKey(documentRevisionId, false);
|
||||
|
||||
Object[] args = {
|
||||
URLEncoder.encode(documentUri),
|
||||
toExtension.replace(".", ""),
|
||||
fromExtension.replace(".", ""),
|
||||
title,
|
||||
documentRevisionId,
|
||||
validateKey
|
||||
};
|
||||
|
||||
String urlToConverter = DocumentConverterUrl + ConvertParams.format(args);
|
||||
|
||||
if (isAsync)
|
||||
urlToConverter += "&async=true";
|
||||
|
||||
URL url = new URL(urlToConverter);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(ConvertTimeout);
|
||||
|
||||
InputStream stream = null;
|
||||
int countTry = 0;
|
||||
|
||||
while (countTry < MaxTry)
|
||||
{
|
||||
try
|
||||
{
|
||||
countTry++;
|
||||
stream = connection.getInputStream();
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(!(ex instanceof TimeoutException))
|
||||
throw new Exception("Bad Request");
|
||||
}
|
||||
}
|
||||
if (countTry == MaxTry)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
|
||||
if (stream == null)
|
||||
throw new Exception("Could not get an answer");
|
||||
|
||||
String xml = ConvertStreamToString(stream);
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
private static void ProcessConvertServiceResponceError(int errorCode) throws Exception
|
||||
{
|
||||
String errorMessage = "";
|
||||
String errorMessageTemplate = "Error occurred in the ConvertService: ";
|
||||
|
||||
switch (errorCode)
|
||||
{
|
||||
case -8:
|
||||
errorMessage = errorMessageTemplate + "Error document VKey";
|
||||
break;
|
||||
case -7:
|
||||
errorMessage = errorMessageTemplate + "Error document request";
|
||||
break;
|
||||
case -6:
|
||||
errorMessage = errorMessageTemplate + "Error database";
|
||||
break;
|
||||
case -5:
|
||||
errorMessage = errorMessageTemplate + "Error unexpected guid";
|
||||
break;
|
||||
case -4:
|
||||
errorMessage = errorMessageTemplate + "Error download error";
|
||||
break;
|
||||
case -3:
|
||||
errorMessage = errorMessageTemplate + "Error convertation error";
|
||||
break;
|
||||
case -2:
|
||||
errorMessage = errorMessageTemplate + "Error convertation timeout";
|
||||
break;
|
||||
case -1:
|
||||
errorMessage = errorMessageTemplate + "Error convertation unknown";
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
errorMessage = "ErrorCode = " + errorCode;
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
private static Pair<Integer, String> GetResponseUri(String xml) throws Exception
|
||||
{
|
||||
Document document = ConvertStringToXmlDocument(xml);
|
||||
|
||||
Element responceFromConvertService = document.getDocumentElement();
|
||||
if (responceFromConvertService == null)
|
||||
throw new Exception("Invalid answer format");
|
||||
|
||||
NodeList errorElement = responceFromConvertService.getElementsByTagName("Error");
|
||||
if (errorElement != null && errorElement.getLength() > 0)
|
||||
ProcessConvertServiceResponceError(Integer.parseInt(errorElement.item(0).getTextContent()));
|
||||
|
||||
NodeList endConvert = responceFromConvertService.getElementsByTagName("EndConvert");
|
||||
if (endConvert == null || endConvert.getLength() == 0)
|
||||
throw new Exception("Invalid answer format");
|
||||
|
||||
Boolean isEndConvert = Boolean.parseBoolean(endConvert.item(0).getTextContent());
|
||||
|
||||
int resultPercent = 0;
|
||||
String responseUri = null;
|
||||
|
||||
if (isEndConvert)
|
||||
{
|
||||
NodeList fileUrl = responceFromConvertService.getElementsByTagName("FileUrl");
|
||||
if (fileUrl == null || endConvert.getLength() == 0)
|
||||
throw new Exception("Invalid answer format");
|
||||
|
||||
resultPercent = 100;
|
||||
responseUri = fileUrl.item(0).getTextContent();
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeList percent = responceFromConvertService.getElementsByTagName("Percent");
|
||||
if (percent != null && percent.getLength() > 0)
|
||||
resultPercent = Integer.parseInt(percent.item(0).getTextContent());
|
||||
|
||||
resultPercent = resultPercent >= 100 ? 99 : resultPercent;
|
||||
}
|
||||
|
||||
return new Pair<>(resultPercent, responseUri);
|
||||
}
|
||||
|
||||
private static String ConvertStreamToString(InputStream stream) throws IOException
|
||||
{
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(stream);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
|
||||
String line = bufferedReader.readLine();
|
||||
|
||||
while(line != null) {
|
||||
stringBuilder.append(line);
|
||||
line =bufferedReader.readLine();
|
||||
}
|
||||
|
||||
String result = stringBuilder.toString();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Document ConvertStringToXmlDocument(String xml) throws IOException, ParserConfigurationException, SAXException
|
||||
{
|
||||
DocumentBuilderFactory documentBuildFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder doccumentBuilder = documentBuildFactory.newDocumentBuilder();
|
||||
InputStream inputStream = new ByteArrayInputStream(xml.getBytes("utf-8"));
|
||||
InputSource inputSource = new InputSource(inputStream);
|
||||
Document document = doccumentBuilder.parse(inputSource);
|
||||
|
||||
return document;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
filesize-max=5242880
|
||||
storage-folder=app_data
|
||||
|
||||
files.docservice.viewed-docs=.ppt|.pps|.odp|.pdf|.djvu|.fb2|.epub|.xps
|
||||
files.docservice.edited-docs=.docx|.doc|.odt|.xlsx|.xls|.ods|.csv|.pptx|.ppsx|.rtf|.txt|.mht|.html|.htm
|
||||
files.docservice.convert-docs=.doc|.odt|.xls|.ods|.ppt|.pps|.odp|.rtf|.mht|.html|.htm|.fb2|.epub
|
||||
files.docservice.timeout=120000
|
||||
|
||||
files.docservice.tenantid=ContactUs
|
||||
files.docservice.key=ContactUs
|
||||
|
||||
files.docservice.url.storage=https://doc.onlyoffice.com/FileUploader.ashx
|
||||
files.docservice.url.converter=https://doc.onlyoffice.com/ConvertService.ashx
|
||||
files.docservice.url.tempstorage=https://doc.onlyoffice.com/ResourceService.ashx
|
||||
files.docservice.url.api=https://doc.onlyoffice.com/OfficeWeb/apps/api/documents/api.js?_dc=2014-12-19
|
||||
files.docservice.url.preloader=https://doc.onlyoffice.com/OfficeWeb/apps/api/documents/cache-scripts.html?_dc=2014-12-19
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
||||
<session-config>
|
||||
<session-timeout>
|
||||
30
|
||||
</session-timeout>
|
||||
</session-config>
|
||||
<listener>
|
||||
<listener-class>
|
||||
controllers.GlobalServletContextListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
</web-app>
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (c) Ascensio System SIA 2014. All rights reserved.
|
||||
http://www.onlyoffice.com
|
||||
*/
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
font-family: Arial, Tahoma,sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.form {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 197 B |
|
After Width: | Height: | Size: 232 B |
|
After Width: | Height: | Size: 631 B |
|
After Width: | Height: | Size: 682 B |
|
After Width: | Height: | Size: 728 B |
|
After Width: | Height: | Size: 744 B |
|
After Width: | Height: | Size: 673 B |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
464
OnlineEditorsExample/OnlineEditorsExampleJava/src/main/webapp/css/jquery-ui.css
vendored
Normal file
@@ -0,0 +1,464 @@
|
||||
/*! jQuery UI - v1.9.2 - 2012-11-23
|
||||
* http://jqueryui.com
|
||||
* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
|
||||
* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
|
||||
.ui-helper-clearfix:after { clear: both; }
|
||||
.ui-helper-clearfix { zoom: 1; }
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; }
|
||||
.ui-accordion .ui-accordion-icons { padding-left: 2.2em; }
|
||||
.ui-accordion .ui-accordion-noicons { padding-left: .7em; }
|
||||
.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; }
|
||||
.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
|
||||
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; }
|
||||
|
||||
.ui-autocomplete {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* workarounds */
|
||||
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
|
||||
|
||||
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
|
||||
.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; }
|
||||
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
||||
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
||||
.ui-button-icons-only { width: 3.4em; }
|
||||
button.ui-button-icons-only { width: 3.7em; }
|
||||
|
||||
/*button text element */
|
||||
.ui-button .ui-button-text { display: block; line-height: 1.4; }
|
||||
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
|
||||
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
|
||||
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
|
||||
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
|
||||
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button { padding: .4em 1em; }
|
||||
|
||||
/*button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
|
||||
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
||||
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
|
||||
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
|
||||
/*button sets*/
|
||||
.ui-buttonset { margin-right: 7px; }
|
||||
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
||||
|
||||
/* workarounds */
|
||||
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
||||
|
||||
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
|
||||
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
||||
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
||||
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
||||
.ui-datepicker .ui-datepicker-next { right:2px; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
||||
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
||||
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
||||
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
||||
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
|
||||
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
||||
.ui-datepicker select.ui-datepicker-month,
|
||||
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
||||
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
||||
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
||||
.ui-datepicker td { border: 0; padding: 1px; }
|
||||
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
||||
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
||||
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
||||
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
||||
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
||||
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
||||
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
|
||||
|
||||
/* RTL support */
|
||||
.ui-datepicker-rtl { direction: rtl; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
|
||||
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
||||
.ui-datepicker-cover {
|
||||
position: absolute; /*must have*/
|
||||
z-index: -1; /*must have*/
|
||||
filter: mask(); /*must have*/
|
||||
top: -4px; /*must have*/
|
||||
left: -4px; /*must have*/
|
||||
width: 200px; /*must have*/
|
||||
height: 200px; /*must have*/
|
||||
}
|
||||
.ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; width: 650px; overflow: hidden; }
|
||||
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
||||
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
||||
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
||||
|
||||
.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; }
|
||||
.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
|
||||
.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
|
||||
.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; }
|
||||
.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; }
|
||||
.ui-menu .ui-menu-item a.ui-state-focus,
|
||||
.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }
|
||||
|
||||
.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; }
|
||||
.ui-menu .ui-state-disabled a { cursor: default; }
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons { position: relative; }
|
||||
.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; }
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon { position: static; float: right; }
|
||||
|
||||
.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
|
||||
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
|
||||
.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
|
||||
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
|
||||
|
||||
.ui-slider { position: relative; text-align: left; }
|
||||
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
|
||||
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
|
||||
|
||||
.ui-slider-horizontal { height: .8em; }
|
||||
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
|
||||
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
||||
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
||||
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
||||
|
||||
.ui-slider-vertical { width: .8em; height: 100px; }
|
||||
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
|
||||
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
||||
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
||||
.ui-slider-vertical .ui-slider-range-max { top: 0; }
|
||||
.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
|
||||
.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
|
||||
.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
|
||||
.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
|
||||
.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
|
||||
.ui-spinner-up { top: 0; }
|
||||
.ui-spinner-down { bottom: 0; }
|
||||
|
||||
/* TR overrides */
|
||||
.ui-spinner .ui-icon-triangle-1-s {
|
||||
/* need to fix icons sprite */
|
||||
background-position:-65px -16px;
|
||||
}
|
||||
|
||||
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
||||
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
|
||||
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
|
||||
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; }
|
||||
.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
||||
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
|
||||
|
||||
.ui-tooltip {
|
||||
padding: 8px;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
max-width: 300px;
|
||||
-webkit-box-shadow: 0 0 5px #aaa;
|
||||
box-shadow: 0 0 5px #aaa;
|
||||
}
|
||||
/* Fades and background-images don't work well together in IE6, drop the image */
|
||||
* html .ui-tooltip {
|
||||
background-image: none;
|
||||
}
|
||||
body .ui-tooltip { border-width: 2px; }
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget { font-family: 'Open Sans',sans-serif; font-size: 1.1em; }
|
||||
.ui-widget .ui-widget { font-size: 1em; }
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: 'Open Sans',sans-serif; font-size: 1em; }
|
||||
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff 50% 50% repeat-x; color: #222222; }
|
||||
.ui-widget-content a { color: #222222; }
|
||||
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc 50% 50% repeat-x; color: #222222; font-weight: bold; }
|
||||
.ui-widget-header a { color: #222222; }
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 50% 50% repeat-x; font-weight: normal; color: #555555; }
|
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
|
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada 50% 50% repeat-x; font-weight: normal; color: #212121; }
|
||||
.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #212121; text-decoration: none; }
|
||||
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff 50% 50% repeat-x; font-weight: normal; color: #212121; }
|
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee 50% 50% repeat-x; color: #363636; }
|
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
|
||||
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec 50% 50% repeat-x; color: #cd0a0a; }
|
||||
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
|
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
|
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||
.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-on { background-position: -96px -144px; }
|
||||
.ui-icon-radio-off { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { background: #aaaaaa 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); }
|
||||
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
Copyright (c) Ascensio System SIA 2014. All rights reserved.
|
||||
http://www.onlyoffice.com
|
||||
*/
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
body {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
font-family: 'Open Sans', Tahoma,sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
form {
|
||||
height: 100%;
|
||||
}
|
||||
div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
a, a:hover, a:visited {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
||||
.top-panel {
|
||||
background: url("img/logo.png") no-repeat 30px center #3D4A6B;
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
}
|
||||
.main-panel {
|
||||
margin: 80px auto;
|
||||
width: 600px;
|
||||
}
|
||||
.portal-name {
|
||||
font-size: 20px;
|
||||
}
|
||||
.portal-descr {
|
||||
display: inline-block;
|
||||
line-height: 20px;
|
||||
margin-bottom: 24px;
|
||||
width: 600px;
|
||||
}
|
||||
.save-original {
|
||||
color: #929597;
|
||||
line-height: 20px;
|
||||
margin-left: 16px;
|
||||
white-space: nowrap;
|
||||
width: 272px;
|
||||
}
|
||||
.question {
|
||||
background: url("img/question_small.png") no-repeat center center transparent;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
#hint {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #8E908F;
|
||||
display: none;
|
||||
margin: 4px 0 0 -32px;
|
||||
max-width: 415px;
|
||||
padding: 10px 15px 15px;
|
||||
word-wrap: break-word;
|
||||
z-index: 255;
|
||||
}
|
||||
.corner {
|
||||
background: url("img/corner.png") no-repeat scroll 0 0 transparent;
|
||||
height: 6px;
|
||||
left: 35px;
|
||||
margin-top: -15px;
|
||||
position: absolute;
|
||||
width: 9px;
|
||||
z-index: 261;
|
||||
}
|
||||
.try-descr {
|
||||
font-size: 16px;
|
||||
white-space : nowrap;
|
||||
}
|
||||
|
||||
.try-editor-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.try-editor-list li {
|
||||
float: left;
|
||||
margin: 25px;
|
||||
}
|
||||
.try-editor {
|
||||
background-color: transparent;
|
||||
background-position: center 0;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
height: 30px;
|
||||
padding-top: 100px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.try-editor.document {
|
||||
background-image: url("img/file_doct.png");
|
||||
}
|
||||
.try-editor.spreadsheet {
|
||||
background-image: url("img/file_xlst.png");
|
||||
}
|
||||
.try-editor.presentation {
|
||||
background-image: url("img/file_pptt.png");
|
||||
}
|
||||
|
||||
.button, .button:visited, .button:hover, .button:active {
|
||||
display: inline-block;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
cursor:pointer;
|
||||
border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
touch-callout: none;
|
||||
-o-touch-callout: none;
|
||||
-moz-touch-callout: none;
|
||||
-webkit-touch-callout: none;
|
||||
user-select: none;
|
||||
-o-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
margin-right: 3px;
|
||||
padding: 2px 12px;
|
||||
|
||||
color: #fff;
|
||||
|
||||
background: #3D96C6;
|
||||
background: linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76a6);
|
||||
background: -o-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76a6);
|
||||
background: -moz-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76a6);
|
||||
background: -webkit-linear-gradient(top, #59B1E2, #3D96C6 50%, #3D96C6 51%, #1A76a6);
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#59B1E2', EndColorStr='#1A76a6')";
|
||||
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #4da9dc #4098c9 #2d7399 #4098c9;
|
||||
}
|
||||
|
||||
.button.disable {
|
||||
cursor: default;
|
||||
|
||||
background: #BADDEF;
|
||||
background: linear-gradient(top, #CEE9F6, #BADDEF 50%, #BADDEF 51%, #ABD4EA);
|
||||
background: -o-linear-gradient(top, #CEE9F6, #BADDEF 50%, #BADDEF 51%, #ABD4EA);
|
||||
background: -moz-linear-gradient(top, #CEE9F6, #BADDEF 50%, #BADDEF 51%, #ABD4EA);
|
||||
background: -webkit-linear-gradient(top, #CEE9F6, #BADDEF 50%, #BADDEF 51%, #ABD4EA);
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#CEE9F6', EndColorStr='#ABD4EA')";
|
||||
|
||||
border: 1px solid #BCDCED;
|
||||
}
|
||||
.button.gray {
|
||||
color: #666;
|
||||
|
||||
background: #E9EAEA;
|
||||
background: linear-gradient(top, #F3F3F3, #E9EAEA 50%, #E8E9E9 51%, #DEDEDE);
|
||||
background: -o-linear-gradient(top, #F3F3F3, #E9EAEA 50%, #E8E9E9 51%, #DEDEDE);
|
||||
background: -moz-linear-gradient(top, #F3F3F3, #E9EAEA 50%, #E8E9E9 51%, #DEDEDE);
|
||||
background: -webkit-linear-gradient(top, #F3F3F3, #E9EAEA 50%, #E8E9E9 51%, #DEDEDE);
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#F3F3F3', EndColorStr='#DEDEDE')";
|
||||
|
||||
border: 1px solid #BFBFBF;
|
||||
}
|
||||
|
||||
.file-upload {
|
||||
cursor: pointer;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 !important;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.file-upload span {
|
||||
line-height: 21px;
|
||||
margin: 2px 12px;
|
||||
}
|
||||
.file-upload input {
|
||||
cursor: pointer;
|
||||
font-size: 23px;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transform: translate(-300px, 0) scale(4);
|
||||
}
|
||||
|
||||
#mainProgress {
|
||||
color: #979b9f;
|
||||
display: none;
|
||||
margin: 15px;
|
||||
}
|
||||
#mainProgress #embeddedView {
|
||||
display: none;
|
||||
}
|
||||
#mainProgress.embedded #embeddedView {
|
||||
display: block;
|
||||
}
|
||||
#mainProgress.embedded #uploadSteps {
|
||||
display: none;
|
||||
}
|
||||
.error-message {
|
||||
background: url("img/alert.png") no-repeat scroll 4px 10px #FFECE3;
|
||||
color: #666668 !important;
|
||||
display: none;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
margin: 5px 0;
|
||||
padding: 10px 10px 10px 30px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#mainProgress .error-message a {
|
||||
color: #666668;
|
||||
}
|
||||
.step {
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
background-color: transparent;
|
||||
color: #979B9F;
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
padding-left: 25px;
|
||||
}
|
||||
.current {
|
||||
background-image: url("img/loader16.gif");
|
||||
color: #333;
|
||||
}
|
||||
.done {
|
||||
background-image: url("img/done.png");
|
||||
color: #333;
|
||||
}
|
||||
.error {
|
||||
background-image: url("img/alert.png");
|
||||
}
|
||||
.step-descr {
|
||||
display: block;
|
||||
margin-left: 45px;
|
||||
}
|
||||
#mainProgress .step-descr a {
|
||||
color: #979B9F;
|
||||
}
|
||||
.progress-descr {
|
||||
color: #333;
|
||||
}
|
||||
#loadScripts {
|
||||
display: none;
|
||||
}
|
||||
#iframeScripts {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
}
|
||||
.bottom-panel {
|
||||
bottom: 0;
|
||||
position: fixed;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
.help-block span {
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.button.sample {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.blockTitle {
|
||||
background-color: #E2E2E2 !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
-moz-border-radius: 0 !important;
|
||||
-webkit-border-radius: 0 !important;
|
||||
color: #333 !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: normal !important;
|
||||
padding: 15px 25px !important;
|
||||
}
|
||||
.dialog-close {
|
||||
background: url("img/close.png") no-repeat scroll left top #E2E2E2;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
font-size: 1px;
|
||||
height: 12px;
|
||||
line-height: 1px;
|
||||
margin-top: 4px;
|
||||
width: 12px;
|
||||
}
|
||||
.blockPage {
|
||||
border: none !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
-moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow:0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
padding: 0 !important;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
|
||||
<%@page import="java.text.SimpleDateFormat"%>
|
||||
<%@page import="java.util.Date"%>
|
||||
<%@page import="java.util.Arrays"%>
|
||||
<%@page import="entities.FileModel"%>
|
||||
<%@page import="helpers.DocumentManager"%>
|
||||
<%@page import="helpers.FileUtility"%>
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>ONLYOFFICE™</title>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" type="text/css" href="css/editor.css" />
|
||||
|
||||
<% FileModel Model = (FileModel)request.getAttribute("file"); %>
|
||||
|
||||
<script type="text/javascript" src="${docserviceApiUrl}"></script>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var fileName = "<%= Model.GetFileName() %>";
|
||||
var fileType = "<%= FileUtility.GetFileExtension(Model.GetFileName()).replace(".", "") %>";
|
||||
|
||||
var innerAlert = function (message) {
|
||||
if (console && console.log)
|
||||
console.log(message);
|
||||
};
|
||||
|
||||
var onReady = function () {
|
||||
innerAlert("Document editor ready");
|
||||
};
|
||||
|
||||
var onBack = function () {
|
||||
location.href = "IndexServlet";
|
||||
};
|
||||
|
||||
var onDocumentStateChange = function (event) {
|
||||
var title = document.title.replace(/\*$/g, "");
|
||||
document.title = title + (event.data ? "*" : "");
|
||||
};
|
||||
|
||||
var onRequestEditRights = function () {
|
||||
if (typeof DocsAPI.DocEditor.version == "function") {
|
||||
var version = DocsAPI.DocEditor.version();
|
||||
if ((parseFloat(version) || 0) >= 3) {
|
||||
location.href = location.href.replace(RegExp("action=view\&?", "i"), "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
docEditor.applyEditRights(true);
|
||||
};
|
||||
|
||||
var onDocumentSave = function (event) {
|
||||
SaveFileRequest(fileName, fileType, event.data);
|
||||
};
|
||||
|
||||
var onError = function (event) {
|
||||
if (console && console.log && event)
|
||||
console.log(event.data);
|
||||
};
|
||||
|
||||
var сonnectEditor = function () {
|
||||
|
||||
docEditor = new DocsAPI.DocEditor("iframeEditor",
|
||||
{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
type: "${type}",
|
||||
documentType: "<%= Model.GetDocumentType() %>",
|
||||
|
||||
document: {
|
||||
title: fileName,
|
||||
url: "<%= Model.GetFileUri() %>",
|
||||
fileType: fileType,
|
||||
key: "<%= Model.GetKey() %>",
|
||||
vkey: "<%= Model.GetValidateKey() %>",
|
||||
|
||||
info: {
|
||||
author: "Me",
|
||||
created: "<%= new SimpleDateFormat("MM/dd/yyyy").format(new Date()) %>"
|
||||
},
|
||||
|
||||
permissions: {
|
||||
edit: <%= Boolean.toString(DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(Model.GetFileName()))).toLowerCase() %>,
|
||||
download: true
|
||||
}
|
||||
},
|
||||
editorConfig: {
|
||||
mode: "<%= DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(Model.GetFileName())) && !"view".equals(request.getAttribute("mode")) ? "edit" : "view" %>",
|
||||
lang: "en",
|
||||
callbackUrl: "<%= Model.GetCallbackUrl() %>",
|
||||
|
||||
embedded: {
|
||||
saveUrl: "<%= Model.GetFileUri() %>",
|
||||
embedUrl: "<%= Model.GetFileUri() %>",
|
||||
shareUrl: "<%= Model.GetFileUri() %>",
|
||||
toolbarDocked: "top"
|
||||
}
|
||||
},
|
||||
events: {
|
||||
"onReady": onReady,
|
||||
"onBack": <%= "embedded".equals(request.getAttribute("type")) ? "" : "onBack" %>,
|
||||
"onDocumentStateChange": onDocumentStateChange,
|
||||
'onRequestEditRights': onRequestEditRights,
|
||||
"onSave": onDocumentSave,
|
||||
"onError": onError
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener("load", сonnectEditor);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent("load", сonnectEditor);
|
||||
}
|
||||
|
||||
function getXmlHttp() {
|
||||
var xmlhttp;
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch (e) {
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch (ex) {
|
||||
xmlhttp = false;
|
||||
}
|
||||
}
|
||||
if (!xmlhttp && typeof XMLHttpRequest !== "undefined") {
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
}
|
||||
return xmlhttp;
|
||||
}
|
||||
|
||||
function SaveFileRequest(fileName, fileType, fileUri) {
|
||||
var req = getXmlHttp();
|
||||
if (console && console.log) {
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState === 4) {
|
||||
console.log(req.statusText);
|
||||
if (req.status === 200) {
|
||||
console.log(req.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var requestAddress = "/OnlineEditorsExampleJava/IndexServlet?type=save"
|
||||
+ "&filename=" + encodeURIComponent(fileName)
|
||||
+ "&filetype=" + encodeURIComponent(fileType)
|
||||
+ "&fileuri=" + encodeURIComponent(fileUri);
|
||||
|
||||
req.open("GET", requestAddress, true);
|
||||
req.send();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="form">
|
||||
<div id="iframeEditor"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,135 @@
|
||||
<%@page import="helpers.DocumentManager"%>
|
||||
<%@page import="helpers.ConfigManager"%>
|
||||
<%@page import="java.util.Calendar"%>
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>ONLYOFFICE™</title>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:900,800,700,600,500,400,300&subset=latin,cyrillic-ext,cyrillic,latin-ext" />
|
||||
<link rel="stylesheet" type="text/css" href="css/stylesheet.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="top-panel"></div>
|
||||
|
||||
<div class="main-panel">
|
||||
<span class="portal-name">ONLYOFFICE™ Online Editors</span>
|
||||
<br />
|
||||
<br />
|
||||
<span class="portal-descr">Get started with a demo-sample of ONLYOFFICE™ Online Editors, the first html5-based editors. You may upload your own documents for testing using the "Choose file" button and selecting the necessary files on your PC.</span>
|
||||
|
||||
<div class="file-upload button gray">
|
||||
<span>Choose file</span>
|
||||
<form class="fileupload" action="server/php/" method="POST" enctype="multipart/form-data">
|
||||
|
||||
</form>
|
||||
<input type="file" id="fileupload" name="file" data-url="IndexServlet?type=upload" />
|
||||
</div>
|
||||
<label class="save-original">
|
||||
<input type="checkbox" id="checkOriginalFormat" />Save document in original format
|
||||
</label>
|
||||
<span class="question"></span>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<span class="try-descr">You are also enabled to view and edit documents pre-uploaded to the portal.</span>
|
||||
|
||||
<ul class="try-editor-list">
|
||||
<li>
|
||||
<a href="EditorServlet?fileExt=docx" class="try-editor document" target="_blank">
|
||||
Sample Document
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="EditorServlet?fileExt=xlsx" class="try-editor spreadsheet" target="_blank">
|
||||
Sample Spreadsheet
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="EditorServlet?fileExt=pptx" class="try-editor presentation" target="_blank">
|
||||
Sample Presentation
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div class="help-block">
|
||||
<span>Want to learn how it works?</span>
|
||||
<br />
|
||||
Read the editor <a href="https://api.onlyoffice.com/">API Documentation</a>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div class="help-block">
|
||||
<span>Any questions?</span>
|
||||
<br />
|
||||
Please, <a href="mailto:sales@onlyoffice.com">submit your request</a> and we'll help you shortly.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="hint">
|
||||
<div class="corner"></div>
|
||||
If you check this option the file will be saved both in the original and converted into Office Open XML format for faster viewing and editing. In other case the document will be overwritten by its copy in Office Open XML format.
|
||||
</div>
|
||||
|
||||
<div id="mainProgress">
|
||||
<div id="uploadSteps">
|
||||
<span id="step1" class="step">1. Loading the file</span>
|
||||
<span class="step-descr">The file loading process will take some time depending on the file size, presence or absence of additional elements in it (macros, etc.) and the connection speed.</span>
|
||||
<br />
|
||||
<span id="step2" class="step">2. File conversion</span>
|
||||
<span class="step-descr">The file is being converted into Office Open XML format for the document faster viewing and editing.</span>
|
||||
<br />
|
||||
<span id="step3" class="step">3. Loading editor scripts</span>
|
||||
<span class="step-descr">The scripts for the editor are loaded only once and are will be cached on your computer in future. It might take some time depending on the connection speed.</span>
|
||||
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
|
||||
<br />
|
||||
<br />
|
||||
<span class="progress-descr">Please note, that the speed of all operations greatly depends on the server and the client locations. In case they differ or are located in different countries/continents, there might be lack of speed and greater wait time. The best results are achieved when the server and client computers are located in one and the same place (city).</span>
|
||||
<br />
|
||||
<br />
|
||||
<div class="error-message">
|
||||
<span></span>
|
||||
<br />
|
||||
Please select another file and try again. If you have questions please <a href="mailto:sales@onlyoffice.com">contact us.</a>
|
||||
</div>
|
||||
</div>
|
||||
<iframe id="embeddedView" src="" height="345px" width="600px" frameborder="0" scrolling="no" allowtransparency></iframe>
|
||||
<br />
|
||||
<div id="beginEmbedded" class="button disable">Embedded view</div>
|
||||
<div id="beginView" class="button disable">View</div>
|
||||
<div id="beginEdit" class="button disable">Edit</div>
|
||||
<div id="cancelEdit" class="button gray">Cancel</div>
|
||||
</div>
|
||||
|
||||
<span id="loadScripts" data-docs="<%= ConfigManager.GetProperty("files.docservice.url.preloader") %>"></span>
|
||||
|
||||
<div class="bottom-panel">
|
||||
© Ascensio System SIA <%= Calendar.getInstance().get(Calendar.YEAR) %>. All rights reserved.
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="scripts/jquery.blockUI.js"></script>
|
||||
<script type="text/javascript" src="scripts/jquery.iframe-transport.js"></script>
|
||||
<script type="text/javascript" src="scripts/jquery.fileupload.js"></script>
|
||||
<script type="text/javascript" src="scripts/jquery.dropdownToggle.js"></script>
|
||||
<script type="text/javascript" src="scripts/jscript.js"></script>
|
||||
|
||||
<script language="javascript" type="text/javascript">
|
||||
var ConverExtList = "<%= String.join(",", DocumentManager.GetConvertExts()) %>";
|
||||
var EditedExtList = "<%= String.join(",", DocumentManager.GetEditedExts()) %>";
|
||||
var UrlConverter = "IndexServlet?type=convert";
|
||||
var UrlEditor = "EditorServlet";
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
9440
OnlineEditorsExample/OnlineEditorsExampleJava/src/main/webapp/scripts/jquery-1.8.2.js
vendored
Normal file
5
OnlineEditorsExample/OnlineEditorsExampleJava/src/main/webapp/scripts/jquery-ui.js
vendored
Normal file
@@ -0,0 +1,576 @@
|
||||
/*!
|
||||
* jQuery blockUI plugin
|
||||
* Version 2.55 (18-JAN-2013)
|
||||
* @requires jQuery v1.7 or later
|
||||
*
|
||||
* Examples at: http://malsup.com/jquery/block/
|
||||
* Copyright (c) 2007-2013 M. Alsup
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
|
||||
*/
|
||||
|
||||
;(function() {
|
||||
"use strict";
|
||||
|
||||
function setup($) {
|
||||
$.fn._fadeIn = $.fn.fadeIn;
|
||||
|
||||
var noOp = $.noop || function() {};
|
||||
|
||||
// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
|
||||
// retarded userAgent strings on Vista)
|
||||
var msie = /MSIE/.test(navigator.userAgent);
|
||||
var ie6 = /MSIE 6.0/.test(navigator.userAgent);
|
||||
var mode = document.documentMode || 0;
|
||||
// var setExpr = msie && (($.browser.version < 8 && !mode) || mode < 8);
|
||||
var setExpr = $.isFunction( document.createElement('div').style.setExpression );
|
||||
|
||||
// global $ methods for blocking/unblocking the entire page
|
||||
$.blockUI = function(opts) { install(window, opts); };
|
||||
$.unblockUI = function(opts) { remove(window, opts); };
|
||||
|
||||
// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
|
||||
$.growlUI = function(title, message, timeout, onClose) {
|
||||
var $m = $('<div class="growlUI"></div>');
|
||||
if (title) $m.append('<h1>'+title+'</h1>');
|
||||
if (message) $m.append('<h2>'+message+'</h2>');
|
||||
if (timeout === undefined) timeout = 3000;
|
||||
$.blockUI({
|
||||
message: $m, fadeIn: 700, fadeOut: 1000, centerY: false,
|
||||
timeout: timeout, showOverlay: false,
|
||||
onUnblock: onClose,
|
||||
css: $.blockUI.defaults.growlCSS
|
||||
});
|
||||
};
|
||||
|
||||
// plugin method for blocking element content
|
||||
$.fn.block = function(opts) {
|
||||
var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
|
||||
this.each(function() {
|
||||
var $el = $(this);
|
||||
if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
|
||||
return;
|
||||
$el.unblock({ fadeOut: 0 });
|
||||
});
|
||||
|
||||
return this.each(function() {
|
||||
if ($.css(this,'position') == 'static') {
|
||||
this.style.position = 'relative';
|
||||
$(this).data('blockUI.static', true);
|
||||
}
|
||||
this.style.zoom = 1; // force 'hasLayout' in ie
|
||||
install(this, opts);
|
||||
});
|
||||
};
|
||||
|
||||
// plugin method for unblocking element content
|
||||
$.fn.unblock = function(opts) {
|
||||
return this.each(function() {
|
||||
remove(this, opts);
|
||||
});
|
||||
};
|
||||
|
||||
$.blockUI.version = 2.55; // 2nd generation blocking at no extra cost!
|
||||
|
||||
// override these in your code to change the default behavior and style
|
||||
$.blockUI.defaults = {
|
||||
// message displayed when blocking (use null for no message)
|
||||
message: '<h1>Please wait...</h1>',
|
||||
|
||||
title: null, // title string; only used when theme == true
|
||||
draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
|
||||
|
||||
theme: false, // set to true to use with jQuery UI themes
|
||||
|
||||
// styles for the message when blocking; if you wish to disable
|
||||
// these and use an external stylesheet then do this in your code:
|
||||
// $.blockUI.defaults.css = {};
|
||||
css: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
width: '30%',
|
||||
top: '40%',
|
||||
left: '35%',
|
||||
textAlign: 'center',
|
||||
color: '#000',
|
||||
border: '3px solid #aaa',
|
||||
backgroundColor:'#fff',
|
||||
cursor: 'wait'
|
||||
},
|
||||
|
||||
// minimal style set used when themes are used
|
||||
themedCSS: {
|
||||
//width: '30%',
|
||||
top: '20%',
|
||||
left: '50%',
|
||||
marginLeft: "-325px"
|
||||
},
|
||||
|
||||
// styles for the overlay
|
||||
overlayCSS: {
|
||||
backgroundColor: '#000',
|
||||
opacity: 0.6,
|
||||
cursor: 'wait'
|
||||
},
|
||||
|
||||
// style to replace wait cursor before unblocking to correct issue
|
||||
// of lingering wait cursor
|
||||
cursorReset: 'default',
|
||||
|
||||
// styles applied when using $.growlUI
|
||||
growlCSS: {
|
||||
width: '350px',
|
||||
top: '10px',
|
||||
left: '',
|
||||
right: '10px',
|
||||
border: 'none',
|
||||
padding: '5px',
|
||||
opacity: 0.6,
|
||||
cursor: 'default',
|
||||
color: '#fff',
|
||||
backgroundColor: '#000',
|
||||
'-webkit-border-radius':'10px',
|
||||
'-moz-border-radius': '10px',
|
||||
'border-radius': '10px'
|
||||
},
|
||||
|
||||
// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
|
||||
// (hat tip to Jorge H. N. de Vasconcelos)
|
||||
/*jshint scripturl:true */
|
||||
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
|
||||
|
||||
// force usage of iframe in non-IE browsers (handy for blocking applets)
|
||||
forceIframe: false,
|
||||
|
||||
// z-index for the blocking overlay
|
||||
baseZ: 1000,
|
||||
|
||||
// set these to true to have the message automatically centered
|
||||
centerX: true, // <-- only effects element blocking (page block controlled via css above)
|
||||
centerY: true,
|
||||
|
||||
// allow body element to be stetched in ie6; this makes blocking look better
|
||||
// on "short" pages. disable if you wish to prevent changes to the body height
|
||||
allowBodyStretch: true,
|
||||
|
||||
// enable if you want key and mouse events to be disabled for content that is blocked
|
||||
bindEvents: true,
|
||||
|
||||
// be default blockUI will supress tab navigation from leaving blocking content
|
||||
// (if bindEvents is true)
|
||||
constrainTabKey: true,
|
||||
|
||||
// fadeIn time in millis; set to 0 to disable fadeIn on block
|
||||
fadeIn: 200,
|
||||
|
||||
// fadeOut time in millis; set to 0 to disable fadeOut on unblock
|
||||
fadeOut: 400,
|
||||
|
||||
// time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
|
||||
timeout: 0,
|
||||
|
||||
// disable if you don't want to show the overlay
|
||||
showOverlay: true,
|
||||
|
||||
// if true, focus will be placed in the first available input field when
|
||||
// page blocking
|
||||
focusInput: true,
|
||||
|
||||
// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
|
||||
// no longer needed in 2012
|
||||
// applyPlatformOpacityRules: true,
|
||||
|
||||
// callback method invoked when fadeIn has completed and blocking message is visible
|
||||
onBlock: null,
|
||||
|
||||
// callback method invoked when unblocking has completed; the callback is
|
||||
// passed the element that has been unblocked (which is the window object for page
|
||||
// blocks) and the options that were passed to the unblock call:
|
||||
// onUnblock(element, options)
|
||||
onUnblock: null,
|
||||
|
||||
// callback method invoked when the overlay area is clicked.
|
||||
// setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
|
||||
onOverlayClick: null,
|
||||
|
||||
// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
|
||||
quirksmodeOffsetHack: 4,
|
||||
|
||||
// class name of the message block
|
||||
blockMsgClass: 'blockMsg',
|
||||
|
||||
// if it is already blocked, then ignore it (don't unblock and reblock)
|
||||
ignoreIfBlocked: false
|
||||
};
|
||||
|
||||
// private data and functions follow...
|
||||
|
||||
var pageBlock = null;
|
||||
var pageBlockEls = [];
|
||||
|
||||
function install(el, opts) {
|
||||
var css, themedCSS;
|
||||
var full = (el == window);
|
||||
var msg = (opts && opts.message !== undefined ? opts.message : undefined);
|
||||
opts = $.extend({}, $.blockUI.defaults, opts || {});
|
||||
|
||||
if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
|
||||
return;
|
||||
|
||||
opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
|
||||
css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
|
||||
if (opts.onOverlayClick)
|
||||
opts.overlayCSS.cursor = 'pointer';
|
||||
|
||||
themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
|
||||
msg = msg === undefined ? opts.message : msg;
|
||||
|
||||
// remove the current block (if there is one)
|
||||
if (full && pageBlock)
|
||||
remove(window, {fadeOut:0});
|
||||
|
||||
// if an existing element is being used as the blocking content then we capture
|
||||
// its current place in the DOM (and current display style) so we can restore
|
||||
// it when we unblock
|
||||
if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
|
||||
var node = msg.jquery ? msg[0] : msg;
|
||||
var data = {};
|
||||
$(el).data('blockUI.history', data);
|
||||
data.el = node;
|
||||
data.parent = node.parentNode;
|
||||
data.display = node.style.display;
|
||||
data.position = node.style.position;
|
||||
if (data.parent)
|
||||
data.parent.removeChild(node);
|
||||
}
|
||||
|
||||
$(el).data('blockUI.onUnblock', opts.onUnblock);
|
||||
var z = opts.baseZ;
|
||||
|
||||
// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
|
||||
// layer1 is the iframe layer which is used to supress bleed through of underlying content
|
||||
// layer2 is the overlay layer which has opacity and a wait cursor (by default)
|
||||
// layer3 is the message content that is displayed while blocking
|
||||
var lyr1, lyr2, lyr3, s;
|
||||
if (msie || opts.forceIframe)
|
||||
lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
|
||||
else
|
||||
lyr1 = $('<div class="blockUI" style="display:none"></div>');
|
||||
|
||||
if (opts.theme)
|
||||
lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
|
||||
else
|
||||
lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
|
||||
|
||||
if (opts.theme && full) {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
|
||||
if ( opts.title ) {
|
||||
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
|
||||
}
|
||||
s += '<div class="ui-widget-content ui-dialog-content"></div>';
|
||||
s += '</div>';
|
||||
}
|
||||
else if (opts.theme) {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
|
||||
if ( opts.title ) {
|
||||
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
|
||||
}
|
||||
s += '<div class="ui-widget-content ui-dialog-content"></div>';
|
||||
s += '</div>';
|
||||
}
|
||||
else if (full) {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
|
||||
}
|
||||
else {
|
||||
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
|
||||
}
|
||||
lyr3 = $(s);
|
||||
|
||||
// if we have a message, style it
|
||||
if (msg) {
|
||||
if (opts.theme) {
|
||||
lyr3.css(themedCSS);
|
||||
lyr3.addClass('ui-widget-content');
|
||||
}
|
||||
else
|
||||
lyr3.css(css);
|
||||
}
|
||||
|
||||
// style the overlay
|
||||
if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
|
||||
lyr2.css(opts.overlayCSS);
|
||||
lyr2.css('position', full ? 'fixed' : 'absolute');
|
||||
|
||||
// make iframe layer transparent in IE
|
||||
if (msie || opts.forceIframe)
|
||||
lyr1.css('opacity',0.0);
|
||||
|
||||
//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
|
||||
var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
|
||||
$.each(layers, function() {
|
||||
this.appendTo($par);
|
||||
});
|
||||
|
||||
if (opts.theme && opts.draggable && $.fn.draggable) {
|
||||
lyr3.draggable({
|
||||
handle: '.ui-dialog-titlebar',
|
||||
cancel: 'li'
|
||||
});
|
||||
}
|
||||
|
||||
// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
|
||||
var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
|
||||
if (ie6 || expr) {
|
||||
// give body 100% height
|
||||
if (full && opts.allowBodyStretch && $.support.boxModel)
|
||||
$('html,body').css('height','100%');
|
||||
|
||||
// fix ie6 issue when blocked element has a border width
|
||||
if ((ie6 || !$.support.boxModel) && !full) {
|
||||
var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
|
||||
var fixT = t ? '(0 - '+t+')' : 0;
|
||||
var fixL = l ? '(0 - '+l+')' : 0;
|
||||
}
|
||||
|
||||
// simulate fixed position
|
||||
$.each(layers, function(i,o) {
|
||||
var s = o[0].style;
|
||||
s.position = 'absolute';
|
||||
if (i < 2) {
|
||||
if (full)
|
||||
s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
|
||||
else
|
||||
s.setExpression('height','this.parentNode.offsetHeight + "px"');
|
||||
if (full)
|
||||
s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
|
||||
else
|
||||
s.setExpression('width','this.parentNode.offsetWidth + "px"');
|
||||
if (fixL) s.setExpression('left', fixL);
|
||||
if (fixT) s.setExpression('top', fixT);
|
||||
}
|
||||
else if (opts.centerY) {
|
||||
if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
|
||||
s.marginTop = 0;
|
||||
}
|
||||
else if (!opts.centerY && full) {
|
||||
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
|
||||
var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
|
||||
s.setExpression('top',expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// show the message
|
||||
if (msg) {
|
||||
if (opts.theme)
|
||||
lyr3.find('.ui-widget-content').append(msg);
|
||||
else
|
||||
lyr3.append(msg);
|
||||
if (msg.jquery || msg.nodeType)
|
||||
$(msg).show();
|
||||
}
|
||||
|
||||
if ((msie || opts.forceIframe) && opts.showOverlay)
|
||||
lyr1.show(); // opacity is zero
|
||||
if (opts.fadeIn) {
|
||||
var cb = opts.onBlock ? opts.onBlock : noOp;
|
||||
var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
|
||||
var cb2 = msg ? cb : noOp;
|
||||
if (opts.showOverlay)
|
||||
lyr2._fadeIn(opts.fadeIn, cb1);
|
||||
if (msg)
|
||||
lyr3._fadeIn(opts.fadeIn, cb2);
|
||||
}
|
||||
else {
|
||||
if (opts.showOverlay)
|
||||
lyr2.show();
|
||||
if (msg)
|
||||
lyr3.show();
|
||||
if (opts.onBlock)
|
||||
opts.onBlock();
|
||||
}
|
||||
|
||||
// bind key and mouse events
|
||||
bind(1, el, opts);
|
||||
|
||||
if (full) {
|
||||
pageBlock = lyr3[0];
|
||||
pageBlockEls = $(':input:enabled:visible',pageBlock);
|
||||
if (opts.focusInput)
|
||||
setTimeout(focus, 20);
|
||||
}
|
||||
else
|
||||
center(lyr3[0], opts.centerX, opts.centerY);
|
||||
|
||||
if (opts.timeout) {
|
||||
// auto-unblock
|
||||
var to = setTimeout(function() {
|
||||
if (full)
|
||||
$.unblockUI(opts);
|
||||
else
|
||||
$(el).unblock(opts);
|
||||
}, opts.timeout);
|
||||
$(el).data('blockUI.timeout', to);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the block
|
||||
function remove(el, opts) {
|
||||
var full = (el == window);
|
||||
var $el = $(el);
|
||||
var data = $el.data('blockUI.history');
|
||||
var to = $el.data('blockUI.timeout');
|
||||
if (to) {
|
||||
clearTimeout(to);
|
||||
$el.removeData('blockUI.timeout');
|
||||
}
|
||||
opts = $.extend({}, $.blockUI.defaults, opts || {});
|
||||
bind(0, el, opts); // unbind events
|
||||
|
||||
if (opts.onUnblock === null) {
|
||||
opts.onUnblock = $el.data('blockUI.onUnblock');
|
||||
$el.removeData('blockUI.onUnblock');
|
||||
}
|
||||
|
||||
var els;
|
||||
if (full) // crazy selector to handle odd field errors in ie6/7
|
||||
els = $('body').children().filter('.blockUI').add('body > .blockUI');
|
||||
else
|
||||
els = $el.find('>.blockUI');
|
||||
|
||||
// fix cursor issue
|
||||
if ( opts.cursorReset ) {
|
||||
if ( els.length > 1 )
|
||||
els[1].style.cursor = opts.cursorReset;
|
||||
if ( els.length > 2 )
|
||||
els[2].style.cursor = opts.cursorReset;
|
||||
}
|
||||
|
||||
if (full)
|
||||
pageBlock = pageBlockEls = null;
|
||||
|
||||
if (opts.fadeOut) {
|
||||
els.fadeOut(opts.fadeOut);
|
||||
setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut);
|
||||
}
|
||||
else
|
||||
reset(els, data, opts, el);
|
||||
}
|
||||
|
||||
// move blocking element back into the DOM where it started
|
||||
function reset(els,data,opts,el) {
|
||||
var $el = $(el);
|
||||
els.each(function(i,o) {
|
||||
// remove via DOM calls so we don't lose event handlers
|
||||
if (this.parentNode)
|
||||
this.parentNode.removeChild(this);
|
||||
});
|
||||
|
||||
if (data && data.el) {
|
||||
data.el.style.display = data.display;
|
||||
data.el.style.position = data.position;
|
||||
if (data.parent)
|
||||
data.parent.appendChild(data.el);
|
||||
$el.removeData('blockUI.history');
|
||||
}
|
||||
|
||||
if ($el.data('blockUI.static')) {
|
||||
$el.css('position', 'static'); // #22
|
||||
}
|
||||
|
||||
if (typeof opts.onUnblock == 'function')
|
||||
opts.onUnblock(el,opts);
|
||||
|
||||
// fix issue in Safari 6 where block artifacts remain until reflow
|
||||
var body = $(document.body), w = body.width(), cssW = body[0].style.width;
|
||||
body.width(w-1).width(w);
|
||||
body[0].style.width = cssW;
|
||||
}
|
||||
|
||||
// bind/unbind the handler
|
||||
function bind(b, el, opts) {
|
||||
var full = el == window, $el = $(el);
|
||||
|
||||
// don't bother unbinding if there is nothing to unbind
|
||||
if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
|
||||
return;
|
||||
|
||||
$el.data('blockUI.isBlocked', b);
|
||||
|
||||
// don't bind events when overlay is not in use or if bindEvents is false
|
||||
if (!opts.bindEvents || (b && !opts.showOverlay))
|
||||
return;
|
||||
|
||||
// bind anchors and inputs for mouse and key events
|
||||
var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
|
||||
if (b)
|
||||
$(document).bind(events, opts, handler);
|
||||
else
|
||||
$(document).unbind(events, handler);
|
||||
|
||||
// former impl...
|
||||
// var $e = $('a,:input');
|
||||
// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
|
||||
}
|
||||
|
||||
// event handler to suppress keyboard/mouse events when blocking
|
||||
function handler(e) {
|
||||
// allow tab navigation (conditionally)
|
||||
if (e.keyCode && e.keyCode == 9) {
|
||||
if (pageBlock && e.data.constrainTabKey) {
|
||||
var els = pageBlockEls;
|
||||
var fwd = !e.shiftKey && e.target === els[els.length-1];
|
||||
var back = e.shiftKey && e.target === els[0];
|
||||
if (fwd || back) {
|
||||
setTimeout(function(){focus(back);},10);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
var opts = e.data;
|
||||
var target = $(e.target);
|
||||
if (target.hasClass('blockOverlay') && opts.onOverlayClick)
|
||||
opts.onOverlayClick();
|
||||
|
||||
// allow events within the message content
|
||||
if (target.parents('div.' + opts.blockMsgClass).length > 0)
|
||||
return true;
|
||||
|
||||
// allow events for content that is not being blocked
|
||||
return target.parents().children().filter('div.blockUI').length === 0;
|
||||
}
|
||||
|
||||
function focus(back) {
|
||||
if (!pageBlockEls)
|
||||
return;
|
||||
var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
|
||||
if (e)
|
||||
e.focus();
|
||||
}
|
||||
|
||||
function center(el, x, y) {
|
||||
var p = el.parentNode, s = el.style;
|
||||
var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
|
||||
var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
|
||||
if (x) s.left = l > 0 ? (l+'px') : '0';
|
||||
if (y) s.top = t > 0 ? (t+'px') : '0';
|
||||
}
|
||||
|
||||
function sz(el, p) {
|
||||
return parseInt($.css(el,p),10)||0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*global define:true */
|
||||
if (typeof define === 'function' && define.amd && define.amd.jQuery) {
|
||||
define(['jquery'], setup);
|
||||
} else {
|
||||
setup(jQuery);
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,124 @@
|
||||
;(function() {
|
||||
var
|
||||
dropdownToggleHash = {};
|
||||
jQuery.extend({
|
||||
dropdownToggle: function(options) {
|
||||
// default options
|
||||
options = jQuery.extend({
|
||||
//switcherSelector: "#id" or ".class", - button
|
||||
//dropdownID: "id", - drop panel
|
||||
//anchorSelector: "#id" or ".class", - near field
|
||||
//noActiveSwitcherSelector: "#id" or ".class", - dont hide
|
||||
addTop: 0,
|
||||
addLeft: 0,
|
||||
position: "absolute",
|
||||
fixWinSize: true,
|
||||
enableAutoHide: true,
|
||||
showFunction: null,
|
||||
afterShowFunction: null,
|
||||
hideFunction: null,
|
||||
alwaysUp: false,
|
||||
simpleToggle: false,
|
||||
rightPos: false
|
||||
}, options);
|
||||
|
||||
var _toggle = function(switcherObj, dropdownID, addTop, addLeft, fixWinSize, position, anchorSelector, showFunction, alwaysUp, simpleToggle, afterShowFunction) {
|
||||
var dropdownItem = jq("#" + dropdownID);
|
||||
|
||||
if (typeof (simpleToggle) === "undefined" || simpleToggle === false) {
|
||||
fixWinSize = fixWinSize === true;
|
||||
addTop = addTop || 0;
|
||||
addLeft = addLeft || 0;
|
||||
position = position || "absolute";
|
||||
|
||||
var targetPos = jq(anchorSelector || switcherObj).offset();
|
||||
|
||||
if (!targetPos) return;
|
||||
|
||||
var elemPosLeft = targetPos.left;
|
||||
var elemPosTop = targetPos.top + jq(anchorSelector || switcherObj).outerHeight();
|
||||
if (options.rightPos) {
|
||||
elemPosLeft = Math.max(0,targetPos.left - dropdownItem.outerWidth() + jq(anchorSelector || switcherObj).outerWidth());
|
||||
}
|
||||
|
||||
var w = jq(window);
|
||||
var topPadding = w.scrollTop();
|
||||
var leftPadding = w.scrollLeft();
|
||||
|
||||
if (position === "fixed") {
|
||||
addTop -= topPadding;
|
||||
addLeft -= leftPadding;
|
||||
}
|
||||
|
||||
var scrWidth = w.width();
|
||||
var scrHeight = w.height();
|
||||
|
||||
if (fixWinSize && (!options.rightPos)
|
||||
&& (targetPos.left + addLeft + dropdownItem.outerWidth()) > (leftPadding + scrWidth)) {
|
||||
elemPosLeft = Math.max(0, leftPadding + scrWidth - dropdownItem.outerWidth()) - addLeft;
|
||||
}
|
||||
|
||||
if (fixWinSize
|
||||
&& (elemPosTop + dropdownItem.outerHeight()) > (topPadding + scrHeight)
|
||||
&& (targetPos.top - dropdownItem.outerHeight()) > topPadding
|
||||
|| alwaysUp) {
|
||||
elemPosTop = targetPos.top - dropdownItem.outerHeight();
|
||||
}
|
||||
|
||||
dropdownItem.css(
|
||||
{
|
||||
"position": position,
|
||||
"top": elemPosTop + addTop,
|
||||
"left": elemPosLeft + addLeft
|
||||
});
|
||||
}
|
||||
if (typeof showFunction === "function") {
|
||||
showFunction(switcherObj, dropdownItem);
|
||||
}
|
||||
|
||||
dropdownItem.toggle();
|
||||
|
||||
if (typeof afterShowFunction === "function") {
|
||||
afterShowFunction(switcherObj, dropdownItem);
|
||||
}
|
||||
};
|
||||
|
||||
var _registerAutoHide = function(event, switcherSelector, dropdownSelector, hideFunction) {
|
||||
if (jq(dropdownSelector).is(":visible")) {
|
||||
var $targetElement = jq((event.target) ? event.target : event.srcElement);
|
||||
if (!$targetElement.parents().andSelf().is(switcherSelector + ", " + dropdownSelector)) {
|
||||
if (typeof hideFunction === "function")
|
||||
hideFunction($targetElement);
|
||||
jq(dropdownSelector).hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (options.switcherSelector && options.dropdownID) {
|
||||
var toggleFunc = function(e) {
|
||||
_toggle(jq(this), options.dropdownID, options.addTop, options.addLeft, options.fixWinSize, options.position, options.anchorSelector, options.showFunction, options.alwaysUp, options.simpleToggle, options.afterShowFunction);
|
||||
};
|
||||
if (!dropdownToggleHash.hasOwnProperty(options.switcherSelector + options.dropdownID)) {
|
||||
jq(document).on("click", options.switcherSelector, toggleFunc);
|
||||
dropdownToggleHash[options.switcherSelector + options.dropdownID] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.enableAutoHide && options.dropdownID) {
|
||||
var hideFunc = function(e) {
|
||||
var allSwitcherSelectors = options.noActiveSwitcherSelector ?
|
||||
options.switcherSelector + ", " + options.noActiveSwitcherSelector : options.switcherSelector;
|
||||
_registerAutoHide(e, allSwitcherSelectors, "#" + options.dropdownID, options.hideFunction);
|
||||
|
||||
};
|
||||
jq(document).unbind("click", hideFunc);
|
||||
jq(document).bind("click", hideFunc);
|
||||
}
|
||||
|
||||
return {
|
||||
toggle: _toggle,
|
||||
registerAutoHide: _registerAutoHide
|
||||
};
|
||||
}
|
||||
});
|
||||
})();
|
||||
1149
OnlineEditorsExample/OnlineEditorsExampleJava/src/main/webapp/scripts/jquery.fileupload.js
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* jQuery Iframe Transport Plugin 1.2
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://creativecommons.org/licenses/MIT/
|
||||
*/
|
||||
|
||||
/*jslint unparam: true */
|
||||
/*global jQuery */
|
||||
|
||||
(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Helper variable to create unique names for the transport iframes:
|
||||
var counter = 0;
|
||||
|
||||
// The iframe transport accepts three additional options:
|
||||
// options.fileInput: a jQuery collection of file input fields
|
||||
// options.paramName: the parameter name for the file form data,
|
||||
// overrides the name property of the file input field(s)
|
||||
// options.formData: an array of objects with name and value properties,
|
||||
// equivalent to the return data of .serializeArray(), e.g.:
|
||||
// [{name: a, value: 1}, {name: b, value: 2}]
|
||||
$.ajaxTransport('iframe', function (options, originalOptions, jqXHR) {
|
||||
if (options.type === 'POST' || options.type === 'GET') {
|
||||
var form,
|
||||
iframe;
|
||||
return {
|
||||
send: function (headers, completeCallback) {
|
||||
form = $('<form style="display:none;"></form>');
|
||||
// javascript:false as initial iframe src
|
||||
// prevents warning popups on HTTPS in IE6.
|
||||
// IE versions below IE8 cannot set the name property of
|
||||
// elements that have already been added to the DOM,
|
||||
// so we set the name along with the iframe HTML markup:
|
||||
iframe = $(
|
||||
'<iframe src="javascript:false;" name="iframe-transport-' +
|
||||
(counter += 1) + '"></iframe>'
|
||||
).bind('load', function () {
|
||||
var fileInputClones;
|
||||
iframe
|
||||
.unbind('load')
|
||||
.bind('load', function () {
|
||||
// The complete callback returns the
|
||||
// iframe content document as response object:
|
||||
completeCallback(
|
||||
200,
|
||||
'success',
|
||||
{'iframe': iframe.contents()}
|
||||
);
|
||||
// Fix for IE endless progress bar activity bug
|
||||
// (happens on form submits to iframe targets):
|
||||
$('<iframe src="javascript:false;"></iframe>')
|
||||
.appendTo(form);
|
||||
form.remove();
|
||||
});
|
||||
form
|
||||
.prop('target', iframe.prop('name'))
|
||||
.prop('action', options.url)
|
||||
.prop('method', options.type);
|
||||
if (options.formData) {
|
||||
$.each(options.formData, function (index, field) {
|
||||
$('<input type="hidden"/>')
|
||||
.prop('name', field.name)
|
||||
.val(field.value)
|
||||
.appendTo(form);
|
||||
});
|
||||
}
|
||||
if (options.fileInput && options.fileInput.length &&
|
||||
options.type === 'POST') {
|
||||
fileInputClones = options.fileInput.clone();
|
||||
// Insert a clone for each file input field:
|
||||
options.fileInput.after(function (index) {
|
||||
return fileInputClones[index];
|
||||
});
|
||||
if (options.paramName) {
|
||||
options.fileInput.each(function () {
|
||||
$(this).prop('name', options.paramName);
|
||||
});
|
||||
}
|
||||
// Appending the file input fields to the hidden form
|
||||
// removes them from their original location:
|
||||
form
|
||||
.append(options.fileInput)
|
||||
.prop('enctype', 'multipart/form-data')
|
||||
// enctype must be set as encoding for IE:
|
||||
.prop('encoding', 'multipart/form-data');
|
||||
}
|
||||
form.submit();
|
||||
// Insert the file input fields at their original location
|
||||
// by replacing the clones with the originals:
|
||||
if (fileInputClones && fileInputClones.length) {
|
||||
options.fileInput.each(function (index, input) {
|
||||
var clone = $(fileInputClones[index]);
|
||||
$(input).prop('name', clone.prop('name'));
|
||||
clone.replaceWith(input);
|
||||
});
|
||||
}
|
||||
});
|
||||
form.append(iframe).appendTo('body');
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
// javascript:false as iframe src aborts the request
|
||||
// and prevents warning popups on HTTPS in IE6.
|
||||
// concat is used to avoid the "Script URL" JSLint error:
|
||||
iframe
|
||||
.unbind('load')
|
||||
.prop('src', 'javascript'.concat(':false;'));
|
||||
}
|
||||
if (form) {
|
||||
form.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// The iframe transport returns the iframe content document as response.
|
||||
// The following adds converters from iframe to text, json, html, and script:
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'iframe text': function (iframe) {
|
||||
return iframe.text();
|
||||
},
|
||||
'iframe json': function (iframe) {
|
||||
return $.parseJSON(iframe.text());
|
||||
},
|
||||
'iframe html': function (iframe) {
|
||||
return iframe.find('body').html();
|
||||
},
|
||||
'iframe script': function (iframe) {
|
||||
return $.globalEval(iframe.text());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
Copyright (c) Ascensio System SIA 2014. All rights reserved.
|
||||
http://www.onlyoffice.com
|
||||
*/
|
||||
if (typeof jQuery !== "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
jq(function () {
|
||||
jq("#fileupload").fileupload({
|
||||
dataType: "json",
|
||||
add: function (e, data) {
|
||||
jq(".error").removeClass("error");
|
||||
jq(".done").removeClass("done");
|
||||
jq(".current").removeClass("current");
|
||||
jq("#step1").addClass("current");
|
||||
jq("#mainProgress .error-message").hide().find("span").text("");
|
||||
jq("#mainProgress").removeClass("embedded");
|
||||
|
||||
jq.blockUI({
|
||||
theme: true,
|
||||
title: "Getting ready to load the file" + "<div class=\"dialog-close\"></div>",
|
||||
message: jq("#mainProgress"),
|
||||
overlayCSS: { "background-color": "#aaa" },
|
||||
themedCSS: { width: "656px", top: "20%", left: "50%", marginLeft: "-328px" }
|
||||
});
|
||||
jq("#beginEdit, #beginView, #beginEmbedded").addClass("disable");
|
||||
|
||||
data.submit();
|
||||
},
|
||||
always: function (e, data) {
|
||||
if (!jq("#mainProgress").is(":visible")) {
|
||||
return;
|
||||
}
|
||||
var response = data.result;
|
||||
if (response.error) {
|
||||
jq(".current").removeClass("current");
|
||||
jq(".step:not(.done)").addClass("error");
|
||||
jq("#mainProgress .error-message").show().find("span").text(response.error);
|
||||
jq('#hiddenFileName').val("");
|
||||
return;
|
||||
}
|
||||
|
||||
jq("#hiddenFileName").val(response.filename);
|
||||
|
||||
jq("#step1").addClass("done").removeClass("current");
|
||||
jq("#step2").addClass("current");
|
||||
|
||||
checkConvert();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var timer = null;
|
||||
var checkConvert = function () {
|
||||
if (timer !== null) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
if (!jq("#mainProgress").is(":visible")) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fileName = jq("#hiddenFileName").val();
|
||||
var posExt = fileName.lastIndexOf(".");
|
||||
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : "";
|
||||
|
||||
if (ConverExtList.indexOf(posExt) === -1) {
|
||||
loadScripts();
|
||||
return;
|
||||
}
|
||||
|
||||
if (jq("#checkOriginalFormat").is(":checked")) {
|
||||
loadScripts();
|
||||
return;
|
||||
}
|
||||
|
||||
timer = setTimeout(function () {
|
||||
var requestAddress = UrlConverter
|
||||
+ "&filename=" + encodeURIComponent(jq("#hiddenFileName").val());
|
||||
|
||||
jq.ajax({
|
||||
async: true,
|
||||
contentType: "text/xml",
|
||||
type: "get",
|
||||
url: requestAddress,
|
||||
complete: function (data) {
|
||||
var responseText = data.responseText;
|
||||
var response = jq.parseJSON(responseText);
|
||||
if (response.error) {
|
||||
jq(".current").removeClass("current");
|
||||
jq(".step:not(.done)").addClass("error");
|
||||
jq("#mainProgress .error-message").show().find("span").text(response.error);
|
||||
jq('#hiddenFileName').val("");
|
||||
return;
|
||||
}
|
||||
|
||||
jq("#hiddenFileName").val(response.filename);
|
||||
|
||||
if (response.step && response.step < 100) {
|
||||
checkConvert();
|
||||
} else {
|
||||
loadScripts();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
var loadScripts = function () {
|
||||
if (!jq("#mainProgress").is(":visible")) {
|
||||
return;
|
||||
}
|
||||
jq("#step2").addClass("done").removeClass("current");
|
||||
jq("#step3").addClass("current");
|
||||
|
||||
if (jq("#loadScripts").is(":empty")) {
|
||||
var urlScripts = jq("#loadScripts").attr("data-docs");
|
||||
var frame = "<iframe id=\"iframeScripts\" width=1 height=1 style=\"position: absolute; visibility: hidden;\" ></iframe>";
|
||||
jq("#loadScripts").html(frame);
|
||||
document.getElementById("iframeScripts").onload = onloadScripts;
|
||||
jq("#loadScripts iframe").attr("src", urlScripts);
|
||||
} else {
|
||||
onloadScripts();
|
||||
}
|
||||
};
|
||||
|
||||
var onloadScripts = function () {
|
||||
if (!jq("#mainProgress").is(":visible")) {
|
||||
return;
|
||||
}
|
||||
jq("#step3").addClass("done").removeClass("current");
|
||||
jq("#beginView, #beginEmbedded").removeClass("disable");
|
||||
|
||||
var fileName = jq("#hiddenFileName").val();
|
||||
var posExt = fileName.lastIndexOf(".");
|
||||
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : "";
|
||||
|
||||
if (EditedExtList.indexOf(posExt) !== -1) {
|
||||
jq("#beginEdit").removeClass("disable");
|
||||
}
|
||||
};
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=edit&fileName=" + fileId;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
});
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=view&fileName=" + fileId;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
});
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=embedded&fileName=" + fileId;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
|
||||
jq("#embeddedView").attr("src", url);
|
||||
});
|
||||
|
||||
jq(document).on("click", "#cancelEdit, .dialog-close", function () {
|
||||
jq('#hiddenFileName').val("");
|
||||
jq("#embeddedView").attr("src", "");
|
||||
jq.unblockUI();
|
||||
});
|
||||
|
||||
jq.dropdownToggle({
|
||||
switcherSelector: ".question",
|
||||
dropdownID: "hint"
|
||||
});
|
||||
}
|
||||