Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5bc89fc514 | |||
| fa620baa9c | |||
| f3f88ad659 | |||
| 79959c5ff9 | |||
| 469b5a584f | |||
| ea83e95a00 | |||
| 307e732608 | |||
| aad0d068d3 | |||
| ebb6730a1b | |||
| 26a183133c | |||
| 2f6c2c216a | |||
| 50c44fc9a8 | |||
| 1a8df78222 | |||
| 44bc6b8b97 | |||
| db7a8e9c2a | |||
| 6f93b03449 | |||
| b5fdf0fc9f | |||
| 19e73f0c5d | |||
| 01a21a58b2 | |||
| 2360c19f4a | |||
| 46f662b5c3 | |||
| e5704e7e3e | |||
| f97b9ac62e | |||
| 776dc69d87 | |||
| dc44d5120b | |||
| 099cdeae5e | |||
| 687a90431c | |||
| 9de234da91 | |||
| 47b10a4238 | |||
| 6b68f4a513 | |||
| ad6aaa8d77 | |||
| fb4aba3d29 | |||
| 83916db267 | |||
| de0b447344 | |||
| 6f2d16c2b9 | |||
| e91ee99f99 | |||
| 5ac6fb65fb | |||
| a6fa615bc4 | |||
| d72f91d810 | |||
| 064cd9cc87 | |||
| 859809810d | |||
| 82c3420414 | |||
| e0fe2482c6 | |||
| 00e64ee83d | |||
| fd5996c572 | |||
| ca9b07fabc | |||
| d90fd9d38e | |||
| 02fbb78e51 | |||
| 2e2f571c93 | |||
| 6831a510fb | |||
| a5b59adacb | |||
| e79cb7d873 | |||
| fc7ce1883e | |||
| c2d9deb322 | |||
| 1a8672734d | |||
| af140c30a4 | |||
| c45d1ee83d | |||
| 00786bf157 | |||
| 252cadea16 | |||
| 5febb10d22 | |||
| 1913c292d2 | |||
| 430b6de5f0 | |||
| 6adc1af638 | |||
| 33508b7383 | |||
| a78f3bd52b | |||
| 6319d7c427 | |||
| 242f0fc025 | |||
| 99ea6367e8 | |||
| e5844a913f | |||
| dcf3d3c43c | |||
| b81c96f2a3 | |||
| 9731625ecc | |||
| 242b9026f1 | |||
| cbfb8971ed | |||
| 653caa8675 | |||
| 2cc4370516 | |||
| c57ab9a06a | |||
| d6287469b6 | |||
| 4da8cb705f | |||
| b4190f35df | |||
| 1af0feb325 | |||
| 7fdcbf7a28 | |||
| b4d9b73f78 | |||
| ba55773c47 | |||
| 69fc33fdf9 | |||
| 377f0041c5 | |||
| 88cafa9f56 | |||
| dc8ed79230 | |||
| 7066f13193 | |||
| c589c3713e | |||
| 233f41237e | |||
| 1229abc0b9 | |||
| 1088d27fea | |||
| 26cb947d9f | |||
| 201db42fc5 | |||
| e0955f2729 | |||
| adfd104416 | |||
| e8d6183c0d | |||
| 6a3c9f9410 | |||
| 56ed20f1f7 | |||
| 59e50e4797 | |||
| 02e39cb4d0 | |||
| 5dcbf12afe | |||
| bd8e96047d | |||
| ddc7b72871 | |||
| 395ca6817d | |||
| cab5602f78 | |||
| f16639b45e | |||
| 3c79bddde3 | |||
| 3ec139c8bd | |||
| 6132a2873a | |||
| e4549c7baf | |||
| 0c9b1f70e6 | |||
| 7d0cb03bf5 | |||
| 3c5798cfa2 | |||
| 86b3572003 | |||
| a8e902e910 | |||
| 89517a6821 |
@@ -1,7 +1,28 @@
|
||||
from lxml import etree
|
||||
from lxml import etree, html
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
def convertHTML(source: str, sourceFrom: str):
|
||||
htmlParser = html.HTMLParser(remove_comments=True, remove_blank_text=True)
|
||||
xmlParser = etree.XMLParser(remove_comments=True, remove_blank_text=True)
|
||||
|
||||
if sourceFrom == "xml":
|
||||
xmldoc = etree.parse(BytesIO(source.encode("utf-8")), xmlParser)
|
||||
return html.tostring(xmldoc, method="html", pretty_print=True, doctype="<!DOCTYPE html>").decode()
|
||||
elif sourceFrom == "html":
|
||||
htmldoc = html.parse(BytesIO(source.encode("utf-8")), htmlParser)
|
||||
return etree.tostring(htmldoc, method="xml", pretty_print=True, doctype="", xml_declaration=True, encoding="utf-8").decode()
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
def formatHTML(source: str, prettify: bool) -> str:
|
||||
parser = html.HTMLParser(remove_blank_text=True, remove_comments=True, remove_pis=True)
|
||||
htmlDoc = html.parse(BytesIO(source.encode("utf-8")),parser=parser)
|
||||
if not prettify:
|
||||
return html.tostring(htmlDoc).decode().replace("\n", "").replace("> ", ">")
|
||||
return etree.tostring(htmlDoc, encoding='unicode', pretty_print=True)
|
||||
|
||||
def formatXML(source: str, prettify: bool) -> str:
|
||||
"""Method used to format XML
|
||||
|
||||
@@ -58,9 +79,11 @@ def xpath(source: str, xpath: str) -> str:
|
||||
else:
|
||||
result_string = ""
|
||||
for e in result:
|
||||
result_string += etree.tostring(e, pretty_print=True).decode() + "\n"
|
||||
return result_string, "node"
|
||||
|
||||
if isinstance(e, etree._Element):
|
||||
result_string += etree.tostring(e, pretty_print=True).decode() + "\n"
|
||||
else:
|
||||
result_string += str(e) + "\n"
|
||||
return result_string, "node"
|
||||
|
||||
|
||||
def xsd(source: str, xsd: str) -> bool:
|
||||
@@ -77,10 +100,12 @@ def xsd(source: str, xsd: str) -> bool:
|
||||
document_input = BytesIO(source.encode("utf-8"))
|
||||
xml = etree.parse(document_input).getroot()
|
||||
|
||||
if xml_schema.validate(xml):
|
||||
return "XML is valid."
|
||||
else:
|
||||
return "XML is NOT valid."
|
||||
try:
|
||||
xml_schema.assertValid(xml)
|
||||
return "XML is valid"
|
||||
except etree.DocumentInvalid as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
|
||||
def xslt(source: str, xslt: str) -> str:
|
||||
|
||||
@@ -29,17 +29,23 @@ def process_xml(request: request, type: str) -> str:
|
||||
try:
|
||||
request_data = json.loads(request.get_data(as_text=True))
|
||||
data = request_data['data']
|
||||
process = request_data['process']
|
||||
processorData = request_data['processorData']
|
||||
if (type == "xsd"):
|
||||
response_json['result'] = Parser.xsd(data, process)
|
||||
response_json['result'] = Parser.xsd(data, processorData)
|
||||
elif (type == "xslt"):
|
||||
response_json['result'] = Parser.xslt(data, process)
|
||||
response_json['result'] = Parser.xslt(data, processorData)
|
||||
elif (type == "xpath"):
|
||||
response_json['result'], response_json['type'] = Parser.xpath(data, process)
|
||||
response_json['result'], response_json['type'] = Parser.xpath(data, processorData)
|
||||
elif (type == "prettify"):
|
||||
response_json['result'] = Parser.formatXML(data, True)
|
||||
elif (type == "minimize"):
|
||||
response_json['result'] = Parser.formatXML(data, False)
|
||||
elif (type == "prettifyHtml"):
|
||||
response_json['result'] = Parser.formatHTML(data, True)
|
||||
elif (type == "minimizeHtml"):
|
||||
response_json['result'] = Parser.formatHTML(data, False)
|
||||
elif (type == "convertHTML"):
|
||||
response_json['result'] = Parser.convertHTML(data, processorData)
|
||||
else:
|
||||
raise ValueError("Valid operation types are: xsd, xslt, xpath")
|
||||
|
||||
@@ -54,7 +60,7 @@ def process_xml(request: request, type: str) -> str:
|
||||
code = 400
|
||||
finally:
|
||||
exec_time = (time.time_ns() - start) / 10**6
|
||||
response_json['time'] = f"{exec_time:.03f}"
|
||||
response_json['duration'] = f"{exec_time:.03f}"
|
||||
response_json['processor'] = "libxml2 over lxml"
|
||||
return json.dumps(response_json), code
|
||||
|
||||
@@ -79,5 +85,17 @@ def prettify():
|
||||
def minimize():
|
||||
return process_xml(request, "minimize")
|
||||
|
||||
@app.route("/html/prettify",methods=["POST"])
|
||||
def prettifyHtml():
|
||||
return process_xml(request, "prettifyHtml")
|
||||
|
||||
@app.route("/html/minimize",methods=["POST"])
|
||||
def minimizeHtml():
|
||||
return process_xml(request, "minimizeHtml")
|
||||
|
||||
@app.route("/html/convert",methods=["POST"])
|
||||
def XMLToHTMLConvertion():
|
||||
return process_xml(request, "convertHTML")
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.r11.tools.controller;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.r11.tools.model.MockedMessageDto;
|
||||
import com.r11.tools.service.KlausService;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -9,12 +8,12 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Returns the homepage and provides the api for javascript async requests.
|
||||
@@ -36,14 +35,12 @@ public class MockController {
|
||||
|
||||
/**
|
||||
* Updates queried message with given set of data
|
||||
* @param body {@link MockedMessageDto} json representation
|
||||
* @param message {@link MockedMessageDto} json representation
|
||||
* @return confirmation and 200 OK
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PutMapping
|
||||
public ResponseEntity<String> updateMessage(@RequestBody String body){
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
MockedMessageDto message = mapper.readValue(body, MockedMessageDto.class);
|
||||
public ResponseEntity<String> updateMessage(@RequestBody MockedMessageDto message){
|
||||
return klausService.setMockedResponse(message);
|
||||
}
|
||||
|
||||
@@ -59,40 +56,10 @@ public class MockController {
|
||||
MockedMessageDto message ;
|
||||
if(uuidValue == null || uuidValue.equals("")) clientUUID = UUID.randomUUID();
|
||||
else clientUUID = UUID.fromString(uuidValue);
|
||||
message = klausService
|
||||
.getMockedMessageByClientUUID(clientUUID)
|
||||
.orElse( buildDefaultMessage(clientUUID) );
|
||||
|
||||
message = klausService.getMockedResponse(clientUUID.toString());
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs message with default set of data
|
||||
* @param uuid the key-uuid of given set of messages
|
||||
* @return message with default dataset
|
||||
*/
|
||||
private MockedMessageDto buildDefaultMessage(UUID uuid){
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Keep-Alive", "timeout=60");
|
||||
headers.put("Connection", "keep-alive");
|
||||
headers.put("Date", LocalDateTime.now().toString());
|
||||
MockedMessageDto mockedMessageDto = MockedMessageDto.builder()
|
||||
.clientUUID(uuid)
|
||||
.contentType(MediaType.APPLICATION_XML_VALUE)
|
||||
.messageBody("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<note>\n" +
|
||||
" <to>Tove</to>\n" +
|
||||
" <from>Jani</from>\n" +
|
||||
" <heading>Reminder</heading>\n" +
|
||||
" <body>Don't forget me this weekend!</body>\n" +
|
||||
"</note>")
|
||||
.httpHeaders(headers)
|
||||
.httpStatus(200)
|
||||
.build();
|
||||
klausService.setMockedResponse(mockedMessageDto);
|
||||
return mockedMessageDto;
|
||||
}
|
||||
/**
|
||||
* It's one of the most important features - the bread and butter of the Mocked Service. It's link that allows
|
||||
* to receive mocked response from the server and use it to mock!
|
||||
@@ -101,7 +68,7 @@ public class MockController {
|
||||
*/
|
||||
@RequestMapping(value = "/r/{clientUUID}")
|
||||
public ResponseEntity getMockedResponse(
|
||||
@PathVariable UUID clientUUID) {
|
||||
@PathVariable String clientUUID) {
|
||||
MockedMessageDto mockedMessageDto = klausService.getMockedResponse(clientUUID);
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
if (mockedMessageDto.getHttpHeaders() != null) mockedMessageDto.getHttpHeaders().forEach(httpHeaders::set);
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.UUID;
|
||||
public class MockedMessage implements Serializable {
|
||||
@Indexed
|
||||
@Id
|
||||
private UUID clientUUID;
|
||||
private String clientUUID;
|
||||
private String contentType;
|
||||
private String messageBody;
|
||||
private Map<String, String> httpHeaders;
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.UUID;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MockedMessageDto implements Serializable{
|
||||
private UUID clientUUID;
|
||||
private String clientUUID;
|
||||
private String contentType;
|
||||
private String messageBody;
|
||||
private Map<String, String> httpHeaders;
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
package com.r11.tools.repository;
|
||||
|
||||
import com.r11.tools.model.MockedMessage;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Spring repository that allows to retrieve message list by key-uuid from redis database
|
||||
* @author Rafał Żukowicz
|
||||
*/
|
||||
@Repository
|
||||
@Transactional
|
||||
public interface MockedResponseRepository extends CrudRepository<MockedMessage, UUID> {
|
||||
/**
|
||||
* Finds all messages by their uuid
|
||||
* @param clientUUID the key-uuid of given set of messages
|
||||
* @return Optional of list of {@link com.r11.tools.model.MockedMessage}
|
||||
*/
|
||||
Optional<MockedMessage> findAllByClientUUID(UUID clientUUID);
|
||||
}
|
||||
public interface MockedResponseRepository extends CrudRepository<MockedMessage, String> {}
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.springframework.stereotype.Service;
|
||||
*/
|
||||
@Service
|
||||
public interface KlausService {
|
||||
Optional<MockedMessageDto> getMockedMessageByClientUUID(UUID clientUUID);
|
||||
MockedMessageDto getMockedResponse(UUID clientUUID);
|
||||
MockedMessageDto getMockedResponse(String clientUUID);
|
||||
ResponseEntity<String> setMockedResponse(MockedMessageDto mockedMessageDto);
|
||||
}
|
||||
|
||||
@@ -10,11 +10,14 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Service for {@link com.r11.tools.controller.MockController} and {@link com.r11.tools.controller.MockController}
|
||||
@@ -31,18 +34,6 @@ public class KlausServiceImpl implements KlausService {
|
||||
private final MockedResponseRepository mockedResponseRepository;
|
||||
|
||||
|
||||
/**
|
||||
* Returns all messages of given key-uuid
|
||||
* @param clientUUID the key-uuid of given set of messages
|
||||
* @return List of {@link MockedMessageDto}
|
||||
*/
|
||||
@Override
|
||||
public Optional<MockedMessageDto> getMockedMessageByClientUUID(UUID clientUUID){
|
||||
Optional<MockedMessage> mockedMessageOptional = mockedResponseRepository.findAllByClientUUID(clientUUID);
|
||||
log.info("Message for UUID: "+clientUUID+" has been fetched from DB.");
|
||||
return mockedMessageMapper.optionalMockedMessageToOptionalMockedMessageDTO(mockedMessageOptional);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link MockedMessageDto} of given id and key-uuid. If message doesn't then empty message is returned
|
||||
* @param clientUUID the key-uuid of given set of messages
|
||||
@@ -50,18 +41,44 @@ public class KlausServiceImpl implements KlausService {
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public MockedMessageDto getMockedResponse(UUID clientUUID){
|
||||
public MockedMessageDto getMockedResponse(String clientUUID){
|
||||
Optional<MockedMessage> optionalMockedMessage = mockedResponseRepository.findById(clientUUID);
|
||||
MockedMessageDto mockedMessageDto = MockedMessageDto.builder()
|
||||
.clientUUID(clientUUID)
|
||||
.build();
|
||||
MockedMessageDto mockedMessageDto;
|
||||
if (optionalMockedMessage.isPresent()) {
|
||||
mockedMessageDto = mockedMessageMapper.mockedMessageToMockedMessageDto(optionalMockedMessage.get());
|
||||
//log.info(mockedMessageDto.toString().replaceAll("\"", "\\\\\""));
|
||||
return mockedMessageDto;
|
||||
} else {
|
||||
MockedMessageDto defaultMessage = buildDefaultMessage(clientUUID);
|
||||
setMockedResponse(defaultMessage);
|
||||
return defaultMessage;
|
||||
}
|
||||
//log.info(mockedMessageDto.toString().replaceAll("\"", "\\\\\""));
|
||||
return mockedMessageDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs message with default set of data
|
||||
* @param uuid the key-uuid of given set of messages
|
||||
* @return message with default dataset
|
||||
*/
|
||||
|
||||
|
||||
private MockedMessageDto buildDefaultMessage(String uuid){
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Keep-Alive", "timeout=60");
|
||||
headers.put("Connection", "keep-alive");
|
||||
headers.put("Date", LocalDateTime.now().toString());
|
||||
return MockedMessageDto.builder()
|
||||
.clientUUID(uuid)
|
||||
.contentType(MediaType.APPLICATION_XML_VALUE)
|
||||
.messageBody("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<note>\n" +
|
||||
" <to>Tove</to>\n" +
|
||||
" <from>Jani</from>\n" +
|
||||
" <heading>Reminder</heading>\n" +
|
||||
" <body>Don't forget me this weekend!</body>\n" +
|
||||
"</note>")
|
||||
.httpHeaders(headers)
|
||||
.httpStatus(200)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,8 +89,10 @@ public class KlausServiceImpl implements KlausService {
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public ResponseEntity<String> setMockedResponse(MockedMessageDto mockedMessageDto) {
|
||||
mockedResponseRepository.save(mockedMessageMapper.mockedMessageDtoToMockedMessage(mockedMessageDto));
|
||||
//log.info(mockedMessageDto.toString().replaceAll("\"", "\\\\\""));
|
||||
MockedMessage message = mockedMessageMapper.mockedMessageDtoToMockedMessage(mockedMessageDto);
|
||||
message.setCreatedAt(LocalDateTime.now());
|
||||
log.info("SAVE:"+message.toString().replace("\n"," "));
|
||||
mockedResponseRepository.save(message);
|
||||
return new ResponseEntity<>("MockedResponse has been setup successfully!", new HttpHeaders(),
|
||||
HttpStatus.ACCEPTED);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@ spring.redis.host=redis
|
||||
spring.redis.port=6379
|
||||
|
||||
#retention
|
||||
retention.minutes-to-delete-message=120
|
||||
retention.minutes-to-delete-message=1440
|
||||
retention.minutes-to-delete-history-record=1440
|
||||
retention.retention-cooldown=1440
|
||||
|
||||
@@ -2,11 +2,7 @@ package com.r11.tools;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.r11.tools.controller.JsonController;
|
||||
import com.r11.tools.controller.ProcessorInfoController;
|
||||
import com.r11.tools.controller.XPathController;
|
||||
import com.r11.tools.controller.XsdController;
|
||||
import com.r11.tools.controller.XsltController;
|
||||
import com.r11.tools.controller.*;
|
||||
import com.r11.tools.controller.internal.RestControllerRegistry;
|
||||
import com.r11.tools.xml.Saxon;
|
||||
import com.r11.tools.xml.Xalan;
|
||||
@@ -44,9 +40,9 @@ public class SparkApplication {
|
||||
|
||||
RestControllerRegistry registry = new RestControllerRegistry();
|
||||
registry.registerController(new ProcessorInfoController(logger, saxon, xalan));
|
||||
registry.registerController(new XsdController(gson, logger, xalan));
|
||||
registry.registerController(new XPathController(gson, logger, saxon, xalan));
|
||||
registry.registerController(new XsltController(gson, logger, saxon, xalan));
|
||||
|
||||
registry.registerController(new XmlController(gson, logger, saxon, xalan));
|
||||
registry.registerController(new MultipleXMLController(gson,logger, saxon));
|
||||
registry.registerController(new JsonController(gson, jsongson, logger));
|
||||
|
||||
registry.register();
|
||||
|
||||
@@ -36,7 +36,7 @@ public class JsonController implements RestController {
|
||||
try {
|
||||
Object requestJson = this.gson.fromJson(request.body(), Object.class);
|
||||
|
||||
responseJson.addProperty("data", this.prettyGson.toJson(requestJson));
|
||||
responseJson.addProperty("result", this.prettyGson.toJson(requestJson));
|
||||
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public class JsonController implements RestController {
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("data", cause == null ? e.getMessage() : cause.getMessage());
|
||||
responseJson.addProperty("result", cause == null ? e.getMessage() : cause.getMessage());
|
||||
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
|
||||
|
||||
|
||||
@@ -65,17 +65,17 @@ public class JsonController implements RestController {
|
||||
|
||||
response.status(200);
|
||||
|
||||
responseJson.addProperty("data", this.gson.toJson(requestJson));
|
||||
responseJson.addProperty("result", this.gson.toJson(requestJson));
|
||||
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
|
||||
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
} catch (Exception e) {
|
||||
this.logger.error("Error on minimizeing Json " + e);
|
||||
this.logger.error("Error on minimizing Json " + e);
|
||||
Throwable cause = e.getCause();
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("data", cause == null ? e.getMessage() : cause.getMessage());
|
||||
responseJson.addProperty("result", cause == null ? e.getMessage() : cause.getMessage());
|
||||
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
|
||||
|
||||
response.body(this.prettyGson.toJson(responseJson));
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.r11.tools.controller;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.r11.tools.controller.internal.*;
|
||||
import com.r11.tools.model.XMLMultipleFilesBody;
|
||||
import com.r11.tools.model.XMLResponseBody;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
@GlobalControllerManifest
|
||||
public class MultipleXMLController implements RestController {
|
||||
|
||||
private final Gson gson;
|
||||
private final Logger logger;
|
||||
|
||||
private final XmlEngine engine;
|
||||
|
||||
public MultipleXMLController(Gson gson, Logger logger, XmlEngine engine) {
|
||||
this.gson = gson;
|
||||
this.logger = logger;
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/multiple/xslt")
|
||||
public void acceptRequestXslt(Request request, Response response) {
|
||||
acceptRequest(request, response, XmlJobType.XSLT);
|
||||
}
|
||||
|
||||
private void acceptRequest(Request request, Response response, XmlJobType xmlJobType) {
|
||||
XMLMultipleFilesBody requestBody;
|
||||
try {
|
||||
requestBody = this.gson.fromJson(request.body(), XMLMultipleFilesBody.class);
|
||||
} catch (Exception e) {
|
||||
requestErrorResponse(response, e);
|
||||
return;
|
||||
}
|
||||
processRequest(new MultipleXmlJob(response, requestBody, engine, xmlJobType));
|
||||
}
|
||||
|
||||
private void processRequest(MultipleXmlJob xmlJob) {
|
||||
XMLResponseBody responseBody = null;
|
||||
long timeStart = System.currentTimeMillis();
|
||||
long duration;
|
||||
|
||||
try {
|
||||
responseBody = processData(xmlJob);
|
||||
|
||||
duration = System.currentTimeMillis() - timeStart;
|
||||
responseBody.setDuration(duration);
|
||||
|
||||
xmlJob.getResponse().status(200);
|
||||
|
||||
this.logger.info("Request (" + xmlJob.getXmlJobType() + ", " +
|
||||
xmlJob.getEngine().getVersion() +
|
||||
") processed in " + duration + " ms.");
|
||||
|
||||
} catch (Exception ex) {
|
||||
responseBody = processingErrorResponse(ex, xmlJob);
|
||||
|
||||
} finally {
|
||||
xmlJob.getResponse().body(this.gson.toJson(responseBody));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private XMLResponseBody processData(MultipleXmlJob xmlJob) throws Exception {
|
||||
XmlEngine engine = xmlJob.getEngine();
|
||||
XMLMultipleFilesBody requestBody = xmlJob.getRequestBody();
|
||||
String result = engine.processXSLT(requestBody.getData(), requestBody.getProcessorData());
|
||||
return new XMLResponseBody(result, "OK", requestBody.getVersion());
|
||||
}
|
||||
|
||||
|
||||
private XMLResponseBody processingErrorResponse(Exception ex, MultipleXmlJob xmlJob) {
|
||||
XmlEngine engine = xmlJob.getEngine();
|
||||
XmlJobType xmlJobType = xmlJob.getXmlJobType();
|
||||
Response response = xmlJob.getResponse();
|
||||
|
||||
XMLResponseBody responseBody =
|
||||
new XMLResponseBody(ex.getMessage(), "ERR", engine.getVersion(), -1);
|
||||
|
||||
response.status(400);
|
||||
this.logger.error("Error on processing " + xmlJobType + " using " + engine.getVersion() + ". " + ex);
|
||||
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
private void requestErrorResponse(Response response, Exception ex) {
|
||||
XMLResponseBody responseBody = new XMLResponseBody(ex.getMessage(), "ERR", "N/A", -1);
|
||||
response.status(400);
|
||||
response.body(this.gson.toJson(responseBody));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.r11.tools.controller;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.r11.tools.controller.internal.*;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
@GlobalControllerManifest
|
||||
public class XPathController implements RestController {
|
||||
|
||||
private final Gson gson;
|
||||
private final Logger logger;
|
||||
|
||||
private final XmlEngine saxon;
|
||||
private final XmlEngine xalan;
|
||||
|
||||
public XPathController(Gson gson, Logger logger, XmlEngine saxon, XmlEngine xalan) {
|
||||
this.gson = gson;
|
||||
this.logger = logger;
|
||||
this.saxon = saxon;
|
||||
this.xalan = xalan;
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xpath")
|
||||
public void transform(Request request, Response response) {
|
||||
String body = request.body();
|
||||
|
||||
JsonObject requestJson;
|
||||
try {
|
||||
requestJson = this.gson.fromJson(body, JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
JsonObject responseJson = new JsonObject();
|
||||
responseJson.addProperty("result", e.getMessage());
|
||||
responseJson.addProperty("processor", "N/A");
|
||||
responseJson.addProperty("status", "ERR");
|
||||
responseJson.addProperty("time", "N/A");
|
||||
|
||||
response.status(400);
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
return;
|
||||
}
|
||||
|
||||
String data = requestJson.get("data").getAsString();
|
||||
String query = requestJson.get("process").getAsString();
|
||||
String processor = requestJson.get("processor").getAsString();
|
||||
String version = requestJson.get("version").getAsString();
|
||||
|
||||
if (processor == null) {
|
||||
response.body("saxon, xalan");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject responseJson = new JsonObject();
|
||||
switch (processor) {
|
||||
case "saxon":
|
||||
processWithSaxon(response, data, query, version, responseJson);
|
||||
break;
|
||||
case "xalan":
|
||||
processWithXalan(response, data, query, responseJson);
|
||||
break;
|
||||
default:
|
||||
response.body("saxon, xalan");
|
||||
}
|
||||
}
|
||||
|
||||
private void processWithXalan(Response response, String data, String query, JsonObject responseJson) {
|
||||
long timeStart;
|
||||
long duration;
|
||||
response.header("processor", xalan.getVersion());
|
||||
timeStart = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
XPathQueryResult xPathQueryResult = xalan.processXPath(data, query, "");
|
||||
|
||||
response.status(200);
|
||||
|
||||
responseJson.addProperty("result", xPathQueryResult.getData().trim());
|
||||
responseJson.addProperty("status", "OK");
|
||||
responseJson.addProperty("type", xPathQueryResult.getType());
|
||||
} catch (Exception ex) {
|
||||
this.logger.error("Error on processing XPath using Xalan. " + ex);
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("result", ex.getMessage());
|
||||
responseJson.addProperty("status", "ERR");
|
||||
}
|
||||
|
||||
duration = System.currentTimeMillis() - timeStart;
|
||||
this.logger.info("Request (XPath, Xalan) processed in " + duration + " ms.");
|
||||
|
||||
responseJson.addProperty("processor", xalan.getVersion());
|
||||
responseJson.addProperty("time", duration);
|
||||
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
}
|
||||
|
||||
private void processWithSaxon(Response response, String data, String query, String version, JsonObject responseJson) {
|
||||
long timeStart;
|
||||
String tmp;
|
||||
long duration;
|
||||
response.header("processor", "Saxon " + saxon.getVersion() + " " + version + " over s9api");
|
||||
timeStart = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
tmp = saxon.processXPath(data, query, version).getData().trim();
|
||||
|
||||
response.status(200);
|
||||
|
||||
responseJson.addProperty("result", tmp);
|
||||
responseJson.addProperty("status", "OK");
|
||||
} catch (Exception ex) {
|
||||
this.logger.error("Error on processing XPath using Saxon. " + ex);
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("result", ex.getMessage());
|
||||
responseJson.addProperty("status", "ERR");
|
||||
}
|
||||
|
||||
duration = System.currentTimeMillis() - timeStart;
|
||||
this.logger.info("Request (XPath, Saxon) processed in " + duration + " ms.");
|
||||
|
||||
responseJson.addProperty("processor", "Saxon " + saxon.getVersion() + " " + version + " over s9api");
|
||||
responseJson.addProperty("time", duration);
|
||||
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.r11.tools.controller;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.r11.tools.controller.internal.*;
|
||||
import com.r11.tools.model.XMLRequestBody;
|
||||
import com.r11.tools.model.XMLResponseBody;
|
||||
import com.r11.tools.model.XPathQueryResult;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
/**
|
||||
* Controller used to handle XML tools: XPath, XSD validation, XQuery and XSLT
|
||||
* @author Adam Bem
|
||||
*/
|
||||
@GlobalControllerManifest
|
||||
public class XmlController implements RestController {
|
||||
|
||||
private final Gson gson;
|
||||
private final Logger logger;
|
||||
|
||||
private final XmlEngine saxon;
|
||||
private final XmlEngine xalan;
|
||||
|
||||
public XmlController(Gson gson, Logger logger, XmlEngine saxon, XmlEngine xalan) {
|
||||
this.gson = gson;
|
||||
this.logger = logger;
|
||||
this.saxon = saxon;
|
||||
this.xalan = xalan;
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xpath")
|
||||
public void acceptRequestXPath(Request request, Response response) {
|
||||
acceptRequest(request, response, XmlJobType.XPath);
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xquery")
|
||||
public void acceptRequestXQuery(Request request, Response response) {
|
||||
acceptRequest(request, response, XmlJobType.XQuery);
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xsd")
|
||||
public void acceptRequestXsd(Request request, Response response) {
|
||||
acceptRequest(request, response, XmlJobType.XSD);
|
||||
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xslt")
|
||||
public void acceptRequestXslt(Request request, Response response) {
|
||||
acceptRequest(request, response, XmlJobType.XSLT);
|
||||
}
|
||||
|
||||
private void acceptRequest(Request request, Response response, XmlJobType xmlJobType) {
|
||||
XMLRequestBody requestBody;
|
||||
try {
|
||||
requestBody = this.gson.fromJson(request.body(), XMLRequestBody.class);
|
||||
} catch (Exception e) {
|
||||
requestErrorResponse(response, e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestBody.getProcessor() == null) {
|
||||
invalidEngineSelectedResponse(response);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (requestBody.getProcessor().toLowerCase()) {
|
||||
case "saxon":
|
||||
processRequest(new XmlJob(response, requestBody, saxon, xmlJobType));
|
||||
return;
|
||||
|
||||
case "xalan":
|
||||
processRequest(new XmlJob(response, requestBody, xalan, xmlJobType));
|
||||
return;
|
||||
|
||||
default:
|
||||
invalidEngineSelectedResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void processRequest(XmlJob xmlJob) {
|
||||
XMLResponseBody responseBody = null;
|
||||
long timeStart = System.currentTimeMillis();
|
||||
long duration;
|
||||
|
||||
try {
|
||||
responseBody = processData(xmlJob);
|
||||
|
||||
duration = System.currentTimeMillis() - timeStart;
|
||||
responseBody.setDuration(duration);
|
||||
|
||||
xmlJob.getResponse().status(200);
|
||||
|
||||
this.logger.info("Request (" + xmlJob.getXmlJobType() + ", " +
|
||||
xmlJob.getEngine().getVersion() +
|
||||
") processed in " + duration + " ms.");
|
||||
|
||||
} catch (Exception ex) {
|
||||
responseBody = processingErrorResponse(ex, xmlJob);
|
||||
|
||||
} finally {
|
||||
xmlJob.getResponse().body(this.gson.toJson(responseBody));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private XMLResponseBody processData(XmlJob xmlJob) throws Exception {
|
||||
if (xmlJob.getXmlJobType() == XmlJobType.XPath)
|
||||
return processXPath(xmlJob);
|
||||
else
|
||||
return processOther(xmlJob);
|
||||
}
|
||||
|
||||
private XMLResponseBody processXPath(XmlJob xmlJob) throws Exception {
|
||||
XmlEngine engine = xmlJob.getEngine();
|
||||
XMLRequestBody requestBody = xmlJob.getRequestBody();
|
||||
|
||||
XPathQueryResult xPathQueryResult =
|
||||
engine.processXPath(requestBody.getData(), requestBody.getProcessorData(), requestBody.getVersion());
|
||||
|
||||
return new XMLResponseBody(xPathQueryResult.getData().trim(),
|
||||
"OK", engine.getVersion(), xPathQueryResult.getType());
|
||||
}
|
||||
|
||||
private XMLResponseBody processOther(XmlJob xmlJob) throws Exception {
|
||||
XmlEngine engine = xmlJob.getEngine();
|
||||
XMLRequestBody requestBody = xmlJob.getRequestBody();
|
||||
|
||||
String result = null;
|
||||
switch (xmlJob.getXmlJobType()) {
|
||||
case XSLT:
|
||||
result = engine.processXSLT(requestBody.getData(), requestBody.getProcessorData());
|
||||
break;
|
||||
case XSD:
|
||||
result = engine.validate(requestBody.getData(), requestBody.getProcessorData()).trim();
|
||||
break;
|
||||
case XQuery:
|
||||
result = engine.executeXQuery(requestBody.getData(),
|
||||
requestBody.getProcessorData(),
|
||||
requestBody.getVersion());
|
||||
break;
|
||||
}
|
||||
return new XMLResponseBody(result, "OK", requestBody.getVersion());
|
||||
}
|
||||
|
||||
private XMLResponseBody processingErrorResponse(Exception ex, XmlJob xmlJob) {
|
||||
XmlEngine engine = xmlJob.getEngine();
|
||||
XmlJobType xmlJobType = xmlJob.getXmlJobType();
|
||||
Response response = xmlJob.getResponse();
|
||||
|
||||
XMLResponseBody responseBody =
|
||||
new XMLResponseBody(ex.getMessage(), "ERR", engine.getVersion(), -1);
|
||||
|
||||
response.status(400);
|
||||
this.logger.error("Error on processing " + xmlJobType + " using " + engine.getVersion() + ". " + ex);
|
||||
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
private void invalidEngineSelectedResponse(Response response) {
|
||||
XMLResponseBody responseBody =
|
||||
new XMLResponseBody("Valid engines are: saxon, xalan", "ERR", "N/A", -1);
|
||||
response.body(this.gson.toJson(responseBody));
|
||||
response.status(400);
|
||||
}
|
||||
|
||||
private void requestErrorResponse(Response response, Exception ex) {
|
||||
XMLResponseBody responseBody = new XMLResponseBody(ex.getMessage(), "ERR", "N/A", -1);
|
||||
response.status(400);
|
||||
response.body(this.gson.toJson(responseBody));
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.r11.tools.controller;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.r11.tools.controller.internal.GlobalControllerManifest;
|
||||
import com.r11.tools.controller.internal.HandlerType;
|
||||
import com.r11.tools.controller.internal.RestController;
|
||||
import com.r11.tools.controller.internal.ScopedControllerManifest;
|
||||
import com.r11.tools.xml.Xalan;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
@GlobalControllerManifest
|
||||
public class XsdController implements RestController {
|
||||
|
||||
private final Gson gson;
|
||||
private final Logger logger;
|
||||
|
||||
private final XmlEngine xalan;
|
||||
|
||||
public XsdController(Gson gson, Logger logger, XmlEngine xalan) {
|
||||
this.gson = gson;
|
||||
this.logger = logger;
|
||||
this.xalan = xalan;
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xsd")
|
||||
public Response transform(Request request, Response response) {
|
||||
String body = request.body();
|
||||
|
||||
JsonObject requestJson;
|
||||
try {
|
||||
requestJson = this.gson.fromJson(body, JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
JsonObject responseJson = new JsonObject();
|
||||
responseJson.addProperty("result", e.getMessage());
|
||||
responseJson.addProperty("processor", "N/A");
|
||||
responseJson.addProperty("status", "ERR");
|
||||
responseJson.addProperty("time", "N/A");
|
||||
|
||||
response.status(400);
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
return response;
|
||||
}
|
||||
|
||||
String data = requestJson.get("data").getAsString();
|
||||
String xsd = requestJson.get("process").getAsString();
|
||||
|
||||
response.header("processor", xalan.getVersion());
|
||||
|
||||
long timeStart = System.currentTimeMillis();
|
||||
String tmp;
|
||||
|
||||
JsonObject responseJson = new JsonObject();
|
||||
try {
|
||||
tmp = xalan.validate(data, xsd).trim();
|
||||
|
||||
response.status(200);
|
||||
|
||||
responseJson.addProperty("result", tmp);
|
||||
responseJson.addProperty("status", "OK");
|
||||
} catch (Exception ex) {
|
||||
this.logger.error("Error on validation against XSD using Xalan. " + ex);
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("result", ex.getMessage());
|
||||
responseJson.addProperty("status", "ERR");
|
||||
}
|
||||
|
||||
long duration = System.currentTimeMillis() - timeStart;
|
||||
this.logger.info("Request (XSD, Xalan) processed in " + duration + " ms.");
|
||||
|
||||
responseJson.addProperty("processor", xalan.getVersion());
|
||||
responseJson.addProperty("time", duration);
|
||||
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package com.r11.tools.controller;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.r11.tools.controller.internal.GlobalControllerManifest;
|
||||
import com.r11.tools.controller.internal.HandlerType;
|
||||
import com.r11.tools.controller.internal.RestController;
|
||||
import com.r11.tools.controller.internal.ScopedControllerManifest;
|
||||
import com.r11.tools.xml.Saxon;
|
||||
import com.r11.tools.xml.Xalan;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
@GlobalControllerManifest
|
||||
public class XsltController implements RestController {
|
||||
|
||||
private final Gson gson;
|
||||
private final Logger logger;
|
||||
|
||||
private final XmlEngine saxon;
|
||||
private final XmlEngine xalan;
|
||||
|
||||
public XsltController(Gson gson, Logger logger, XmlEngine saxon, XmlEngine xalan) {
|
||||
this.gson = gson;
|
||||
this.logger = logger;
|
||||
this.saxon = saxon;
|
||||
this.xalan = xalan;
|
||||
}
|
||||
|
||||
@ScopedControllerManifest(method = HandlerType.POST, path = "/xslt")
|
||||
public void transform(Request request, Response response) {
|
||||
String body = request.body();
|
||||
|
||||
JsonObject requestJson;
|
||||
try {
|
||||
requestJson = this.gson.fromJson(body, JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
JsonObject responseJson = new JsonObject();
|
||||
responseJson.addProperty("result", e.getMessage());
|
||||
responseJson.addProperty("processor", "N/A");
|
||||
responseJson.addProperty("status", "ERR");
|
||||
responseJson.addProperty("time", "N/A");
|
||||
|
||||
response.status(400);
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
return;
|
||||
}
|
||||
|
||||
String data = requestJson.get("data").getAsString();
|
||||
String query = requestJson.get("process").getAsString();
|
||||
String processor = requestJson.get("processor").getAsString();
|
||||
String version = requestJson.get("version").getAsString();
|
||||
|
||||
if (processor == null) {
|
||||
response.body("saxon, xalan");
|
||||
return;
|
||||
}
|
||||
JsonObject responseJson = new JsonObject();
|
||||
switch (processor) {
|
||||
case "saxon":
|
||||
processWithSaxon(response, data, query, version, responseJson);
|
||||
return;
|
||||
|
||||
case "xalan":
|
||||
processWithXalan(response, data, query, responseJson);
|
||||
return;
|
||||
|
||||
default:
|
||||
response.body("saxon, xalan");
|
||||
}
|
||||
}
|
||||
|
||||
private void processWithXalan(Response response, String data, String query, JsonObject responseJson) {
|
||||
long duration;
|
||||
long timeStart;
|
||||
String tmp;
|
||||
timeStart = System.currentTimeMillis();
|
||||
try {
|
||||
tmp = xalan.processXSLT(data, query);
|
||||
|
||||
response.status(200);
|
||||
|
||||
responseJson.addProperty("result", tmp);
|
||||
responseJson.addProperty("status", "OK");
|
||||
} catch (Exception ex) {
|
||||
this.logger.error("Error on processing XSLT using Xalan. " + ex);
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("result", ex.getMessage());
|
||||
responseJson.addProperty("status", "ERR");
|
||||
}
|
||||
|
||||
duration = System.currentTimeMillis() - timeStart;
|
||||
this.logger.info("Request (XSLT, Xalan) processed in " + duration + " ms.");
|
||||
|
||||
responseJson.addProperty("processor", xalan.getVersion());
|
||||
responseJson.addProperty("time", duration);
|
||||
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
}
|
||||
|
||||
private void processWithSaxon(Response response, String data, String query, String version, JsonObject responseJson) {
|
||||
long duration;
|
||||
String tmp;
|
||||
long timeStart;
|
||||
timeStart = System.currentTimeMillis();
|
||||
try {
|
||||
tmp = saxon.processXSLT(data, query);
|
||||
|
||||
response.status(200);
|
||||
|
||||
responseJson.addProperty("result", tmp);
|
||||
responseJson.addProperty("status", "OK");
|
||||
} catch (Exception ex) {
|
||||
this.logger.error("Error on processing XSLT using Saxon. " + ex);
|
||||
|
||||
response.status(400);
|
||||
|
||||
responseJson.addProperty("result", ex.getMessage());
|
||||
responseJson.addProperty("status", "ERR");
|
||||
}
|
||||
|
||||
duration = System.currentTimeMillis() - timeStart;
|
||||
this.logger.info("Request (XSLT, Saxon) processed in " + duration + " ms.");
|
||||
|
||||
responseJson.addProperty("processor", "Saxon " + saxon.getVersion() + " " + version);
|
||||
responseJson.addProperty("time", duration);
|
||||
|
||||
response.body(this.gson.toJson(responseJson));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.r11.tools.controller.internal;
|
||||
|
||||
import com.r11.tools.model.XMLMultipleFilesBody;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import spark.Response;
|
||||
|
||||
public class MultipleXmlJob {
|
||||
|
||||
private final Response response;
|
||||
private final XMLMultipleFilesBody requestBody;
|
||||
private final XmlEngine engine;
|
||||
private final XmlJobType xmlJobType;
|
||||
|
||||
public MultipleXmlJob(Response response, XMLMultipleFilesBody requestBody, XmlEngine engine, XmlJobType xmlJobType) {
|
||||
this.response = response;
|
||||
this.requestBody = requestBody;
|
||||
this.engine = engine;
|
||||
this.xmlJobType = xmlJobType;
|
||||
}
|
||||
|
||||
public Response getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public XMLMultipleFilesBody getRequestBody() {
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
public XmlEngine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public XmlJobType getXmlJobType() {
|
||||
return xmlJobType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.r11.tools.controller.internal;
|
||||
|
||||
import com.r11.tools.model.XMLRequestBody;
|
||||
import com.r11.tools.xml.XmlEngine;
|
||||
import spark.Response;
|
||||
|
||||
public class XmlJob {
|
||||
private final Response response;
|
||||
private final XMLRequestBody requestBody;
|
||||
private final XmlEngine engine;
|
||||
private final XmlJobType xmlJobType;
|
||||
|
||||
public XmlJob(Response response, XMLRequestBody requestBody, XmlEngine engine, XmlJobType xmlJobType) {
|
||||
this.response = response;
|
||||
this.requestBody = requestBody;
|
||||
this.engine = engine;
|
||||
this.xmlJobType = xmlJobType;
|
||||
}
|
||||
|
||||
public Response getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public XMLRequestBody getRequestBody() {
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
public XmlEngine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public XmlJobType getXmlJobType() {
|
||||
return xmlJobType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.r11.tools.controller.internal;
|
||||
|
||||
public enum XmlJobType {
|
||||
XPath("XPath"), XSD("XSD"), XQuery("XQuery"), XSLT("XSLT");
|
||||
|
||||
XmlJobType(String type) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.r11.tools.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class XMLMultipleFilesBody {
|
||||
|
||||
@SerializedName("data")
|
||||
private XMLMultipleFilesData[] data;
|
||||
@SerializedName("processorData")
|
||||
private String processorData;
|
||||
@SerializedName("processor")
|
||||
private String processor;
|
||||
@SerializedName("version")
|
||||
private String version;
|
||||
|
||||
|
||||
public String getProcessorData() {
|
||||
return processorData;
|
||||
}
|
||||
|
||||
public String getProcessor() {
|
||||
return processor;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public XMLMultipleFilesData[] getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.r11.tools.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class XMLMultipleFilesData {
|
||||
@SerializedName("fileName")
|
||||
private String filename;
|
||||
@SerializedName("fileData")
|
||||
private String data;
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.r11.tools.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* POJO class used to contain body of XML related requests
|
||||
* @author Adam Bem
|
||||
*/
|
||||
public class XMLRequestBody {
|
||||
@SerializedName("data")
|
||||
private String data;
|
||||
@SerializedName("processorData")
|
||||
private String processorData;
|
||||
@SerializedName("processor")
|
||||
private String processor;
|
||||
@SerializedName("version")
|
||||
private String version;
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getProcessorData() {
|
||||
return processorData;
|
||||
}
|
||||
|
||||
public String getProcessor() {
|
||||
return processor;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.r11.tools.model;
|
||||
|
||||
public class XMLResponseBody {
|
||||
|
||||
private String result;
|
||||
private String status;
|
||||
private String processor;
|
||||
private long duration;
|
||||
|
||||
// Optional
|
||||
private String type;
|
||||
|
||||
public XMLResponseBody(String result, String status, String processor) {
|
||||
this.result = result;
|
||||
this.status = status;
|
||||
this.processor = processor;
|
||||
}
|
||||
public XMLResponseBody(String result, String status, String processor, long duration) {
|
||||
this.result = result;
|
||||
this.status = status;
|
||||
this.processor = processor;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public XMLResponseBody(String result, String status, String processor, String type) {
|
||||
this.result = result;
|
||||
this.status = status;
|
||||
this.processor = processor;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getProcessor() {
|
||||
return processor;
|
||||
}
|
||||
|
||||
public void setProcessor(String processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.r11.tools.controller.internal;
|
||||
package com.r11.tools.model;
|
||||
|
||||
/**
|
||||
* Class used to store data received from parser and type of that data (node, string, etc.)
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.r11.tools.xml;
|
||||
|
||||
import com.r11.tools.controller.internal.XPathQueryResult;
|
||||
import com.r11.tools.model.XMLMultipleFilesData;
|
||||
import com.r11.tools.model.XPathQueryResult;
|
||||
import net.sf.saxon.s9api.*;
|
||||
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Comparator;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Handler for Saxon engine
|
||||
@@ -13,6 +18,64 @@ import java.io.StringWriter;
|
||||
*/
|
||||
public class Saxon implements XmlEngine{
|
||||
|
||||
/**
|
||||
* Transforms many XML documents via XSLT.
|
||||
* @param data XML Files to be transformed.
|
||||
* @param transform XSLT
|
||||
* @return transformed xml
|
||||
* @throws SaxonApiException thrown on stylesheet or transformation error
|
||||
* @throws IOException thrown when file does not exist, or cannot be read.
|
||||
*/
|
||||
public String processXSLT(XMLMultipleFilesData[] data, String transform) throws SaxonApiException, IOException{
|
||||
Processor processor = new Processor(false);
|
||||
XsltCompiler compiler = processor.newXsltCompiler();
|
||||
|
||||
String filesPath = "/tmp/"+UUID.randomUUID()+"/";
|
||||
try{
|
||||
createXMLFilesFromData(data, filesPath);
|
||||
Path transformPath = createXSLTFileAndReturnPath(transform,filesPath);
|
||||
XsltExecutable stylesheet = compiler.compile( new StreamSource( transformPath.toFile() ));
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
Serializer out = processor.newSerializer(sw);
|
||||
out.setOutputProperty(Serializer.Property.METHOD, "xml");
|
||||
out.setOutputProperty(Serializer.Property.INDENT, "yes");
|
||||
Xslt30Transformer transformer = stylesheet.load30();
|
||||
transformer.transform( new StreamSource( new File(filesPath+data[0].getFilename()) ) , out );
|
||||
return sw.toString();
|
||||
} finally {
|
||||
deleteTemporaryFiles(filesPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createXMLFilesFromData( XMLMultipleFilesData[] data , String filesPath ) throws IOException {
|
||||
Files.createDirectories(Paths.get(filesPath));
|
||||
for (XMLMultipleFilesData fileData : data) {
|
||||
Path filePath = Files.createFile( Paths.get(filesPath + fileData.getFilename() ) );
|
||||
try (FileWriter writer = new FileWriter(filePath.toFile())) {
|
||||
writer.write(fileData.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Path createXSLTFileAndReturnPath( String xsltTransform, String filesPath ) throws IOException {
|
||||
Path transformPath = Files.createFile( Paths.get(filesPath + "transform.xsl") );
|
||||
FileWriter writer = new FileWriter(transformPath.toFile());
|
||||
writer.write(xsltTransform);
|
||||
writer.close();
|
||||
|
||||
return transformPath;
|
||||
}
|
||||
|
||||
private void deleteTemporaryFiles(String filesPath) throws IOException {
|
||||
Files
|
||||
.walk( Paths.get(filesPath) )
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms string containing xml document via xslt
|
||||
* @param data xml to be transformed
|
||||
@@ -39,10 +102,33 @@ public class Saxon implements XmlEngine{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method evaluates XQuery expression on given xml
|
||||
* @param data xml
|
||||
* @param xquery expression
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String executeXQuery(String data, String xquery, String version) throws Exception {
|
||||
Processor processor = new Processor(false);
|
||||
|
||||
XQueryCompiler compiler = processor.newXQueryCompiler();
|
||||
compiler.setLanguageVersion(version);
|
||||
|
||||
XQueryExecutable executable = compiler.compile(xquery);
|
||||
|
||||
XQueryEvaluator evaluator = executable.load();
|
||||
evaluator.setSource(new StreamSource(new StringReader(data)));
|
||||
|
||||
XdmValue result = evaluator.evaluate();
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process xpath and return either node or wrapped atomic value
|
||||
* @param data xml to be querried
|
||||
* @param query xpath queryy
|
||||
* @param data xml to be processed
|
||||
* @param query xpath query
|
||||
* @param version processor version
|
||||
* @return string xml representation of the node
|
||||
* @throws Exception thrown on node building errors or invalid xpath
|
||||
@@ -76,6 +162,6 @@ public class Saxon implements XmlEngine{
|
||||
* @return version of the processor
|
||||
*/
|
||||
public String getVersion() {
|
||||
return new Processor(false).getSaxonProductVersion();
|
||||
return "Saxon " + new Processor(false).getSaxonProductVersion();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.r11.tools.xml;
|
||||
|
||||
import com.r11.tools.controller.internal.XPathQueryResult;
|
||||
import com.r11.tools.model.XMLMultipleFilesData;
|
||||
import com.r11.tools.model.XPathQueryResult;
|
||||
import org.apache.xpath.XPathAPI;
|
||||
import org.apache.xpath.objects.XObject;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
@@ -18,7 +18,10 @@ import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
import java.io.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Handler for Xalan engine
|
||||
@@ -58,6 +61,18 @@ public class Xalan implements XmlEngine{
|
||||
return nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.TEXT_NODE;
|
||||
}
|
||||
|
||||
private boolean isAttributeNode(Node n) {
|
||||
if (n == null)
|
||||
return false;
|
||||
short nodeType = n.getNodeType();
|
||||
return nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.ATTRIBUTE_NODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processXSLT(XMLMultipleFilesData[] data, String transform) throws Exception {
|
||||
throw new UnsupportedOperationException("Xalan does not support multiple files XSLT processing");
|
||||
}
|
||||
|
||||
/**
|
||||
* Process xpath and return either node or wrapped atomic value
|
||||
* @param data xml
|
||||
@@ -93,7 +108,10 @@ public class Xalan implements XmlEngine{
|
||||
for (Node nn = n.getNextSibling(); isTextNode(nn); nn = nn.getNextSibling()) {
|
||||
resultString.append(nn.getNodeValue());
|
||||
}
|
||||
} else {
|
||||
} else if (isAttributeNode(n)) {
|
||||
resultString.append(n.getNodeValue());
|
||||
}
|
||||
else {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(outputStream)));
|
||||
resultString.append(outputStream);
|
||||
@@ -133,4 +151,9 @@ public class Xalan implements XmlEngine{
|
||||
validator.validate(dataSource);
|
||||
return "XML file is valid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String executeXQuery(String data, String xquery, String version) throws Exception {
|
||||
throw new UnsupportedOperationException("Xalan doesn't support XQuery evaluation");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
package com.r11.tools.xml;
|
||||
|
||||
import com.r11.tools.controller.internal.XPathQueryResult;
|
||||
import com.r11.tools.model.XMLMultipleFilesData;
|
||||
import com.r11.tools.model.XPathQueryResult;
|
||||
|
||||
public interface XmlEngine {
|
||||
|
||||
String processXSLT(XMLMultipleFilesData[] data, String transform) throws Exception;
|
||||
XPathQueryResult processXPath(String data, String query, String version) throws Exception;
|
||||
String processXSLT(String data, String transform) throws Exception;
|
||||
String validate(String data, String xsd) throws Exception;
|
||||
|
||||
String executeXQuery(String data, String xquery, String version) throws Exception;
|
||||
|
||||
public String getVersion();
|
||||
|
||||
}
|
||||
|
||||
28
Frontend/.dockerignore
Normal file
28
Frontend/.dockerignore
Normal file
@@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
15
Frontend/.eslintrc.cjs
Normal file
15
Frontend/.eslintrc.cjs
Normal file
@@ -0,0 +1,15 @@
|
||||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier/skip-formatting'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest'
|
||||
}
|
||||
}
|
||||
28
Frontend/.gitignore
vendored
Normal file
28
Frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
8
Frontend/.prettierrc.json
Normal file
8
Frontend/.prettierrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
@@ -1,20 +1,30 @@
|
||||
FROM nginx:stable-alpine
|
||||
FROM node:20.9.0-bullseye-slim as build-stage
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY ./ .
|
||||
RUN npm run build
|
||||
|
||||
|
||||
|
||||
FROM nginx:stable-alpine3.17-slim as production-stage
|
||||
RUN mkdir /app
|
||||
|
||||
RUN apk add --no-cache tzdata
|
||||
ENV TZ Europe/Warsaw
|
||||
|
||||
COPY ./tools/ /usr/share/nginx/html/tools/
|
||||
COPY ./lawful/ /usr/share/nginx/html/lawful/
|
||||
COPY ./assets/ /usr/share/nginx/html/assets/
|
||||
COPY ./index.html /usr/share/nginx/html
|
||||
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
||||
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
RUN mkdir -p /scripts
|
||||
COPY insert_version.sh /scripts/
|
||||
WORKDIR /scripts
|
||||
|
||||
RUN chmod +x insert_version.sh
|
||||
RUN ./insert_version.sh
|
||||
|
||||
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
|
||||
FROM node:20.9.0-bullseye-slim as dev
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
ENV HOST=0.0.0.0
|
||||
COPY . .
|
||||
EXPOSE 8080
|
||||
CMD ["npm", "run", "dev"]
|
||||
|
||||
89
Frontend/README.md
Normal file
89
Frontend/README.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Modern frontend for Release 11 Tools
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
|
||||
## Structure of Vuejs 3 components and views in this project
|
||||
|
||||
For this document's needs components and views will be named "modules" even though this is not a correct term for these files officially.
|
||||
|
||||
### Main structure
|
||||
|
||||
- \<script\>
|
||||
- \<template\>
|
||||
- \<style\> - if really needed
|
||||
|
||||
### Scripts
|
||||
|
||||
#### Elements should be placed in this order:
|
||||
- Imports
|
||||
- Props - constant defined by defineProps function, named "props" in code
|
||||
This name allows to have readable code sending data to parent module:
|
||||
```TS
|
||||
props.exampleProp
|
||||
```
|
||||
- Emits - constant defined by defineEmits function, named "emit" in code. This name allows to have readable code sending data to parent module:
|
||||
```TS
|
||||
emit("update:modelValue", exampleVariable)
|
||||
```
|
||||
- Interfaces
|
||||
- Refs - constants defined by ref functions with appropriate values
|
||||
- Injects - variables assigned by "inject" function
|
||||
- Other variables/constants
|
||||
- onFunctions - functions like onBeforeUpdate
|
||||
- Other functions
|
||||
|
||||
#### Rules regarding functions:
|
||||
- Functions ought to have descriptive name
|
||||
- Ought to do one thing. ie. function sendRequest should send request, but not prepare request body or process response data
|
||||
- In practice, if function has more than 10 SLoC, it probably should be split
|
||||
- DO NOT use "any" type. Just don't. *Optional
|
||||
- Function used in other function should be placed below it (if possible, as function can be called from many places in the code)
|
||||
|
||||
#### Rules regarding variables and refs:
|
||||
- Variables ought to have descriptive name
|
||||
|
||||
In cases not covered in this convention, TypeScript, VueJS 3 conventions and good programming practices are applied
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
@import url('https://necolas.github.io/normalize.css/8.0.1/normalize.css');
|
||||
@import url('r11addons.css');
|
||||
@import url('r11tables.css');
|
||||
@import url('r11tool.css');
|
||||
@import url('r11tooltip.css');
|
||||
@import url('r11modal.css');
|
||||
Binary file not shown.
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2021 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="fontello" horiz-adv-x="1000" >
|
||||
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="plus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
|
||||
|
||||
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
59
Frontend/assets/css/common/fontello.css
vendored
59
Frontend/assets/css/common/fontello.css
vendored
@@ -1,59 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('font/fontello.eot?49304387');
|
||||
src: url('font/fontello.eot?49304387#iefix') format('embedded-opentype'),
|
||||
url('font/fontello.woff2?49304387') format('woff2'),
|
||||
url('font/fontello.woff?49304387') format('woff'),
|
||||
url('font/fontello.ttf?49304387') format('truetype'),
|
||||
url('font/fontello.svg?49304387#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
|
||||
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
|
||||
/*
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.svg?49304387#fontello') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[class^="icon-"]:before, [class*=" icon-"]:before {
|
||||
font-family: "fontello";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: never;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
margin-right: .2em;
|
||||
text-align: center;
|
||||
/* opacity: .8; */
|
||||
|
||||
/* For safety - reset parent styles, that can break glyph codes*/
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
/* fix buttons height, for twitter bootstrap */
|
||||
line-height: 1em;
|
||||
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
/* remove if not needed */
|
||||
margin-left: .2em;
|
||||
|
||||
/* you can be more comfortable with increased icons size */
|
||||
/* font-size: 120%; */
|
||||
|
||||
/* Font smoothing. That was taken from TWBS */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Uncomment for 3D effect */
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
|
||||
.icon-plus:before { content: '\e801'; } /* '' */
|
||||
.icon-cancel:before { content: '\e802'; } /* '' */
|
||||
@@ -1,150 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "Nunito";
|
||||
src: url('../fonts/Nunito-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
||||
|
||||
html {
|
||||
background-image: url("../images/background.jpg");
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-weight: 200;
|
||||
|
||||
color: #2e3133;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
div#header {
|
||||
background-color: #FFFFFF;
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#logo {
|
||||
padding: 20px 20px 20px;
|
||||
width: 250px;
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
iframe#iframe {
|
||||
flex-grow: 1;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
div#content {
|
||||
width: 100%;
|
||||
height: calc(100% - 80px);
|
||||
display: flex;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
div#leftBar {
|
||||
float: left;
|
||||
width: 200px;
|
||||
background-color: transparent;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
div#copyright{
|
||||
color:rgb(192, 192, 192);
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div#copyright a, a:visited, a:active {
|
||||
color: rgb(192, 192, 192);
|
||||
}
|
||||
|
||||
#toolList {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 10px 0 0 0;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
float: left;
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: calc(100% - 80px);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.toolListRow a {
|
||||
display: block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 20px 50px 25px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.toolListRow a:hover {
|
||||
background-color: #2A93B0;
|
||||
color: white;
|
||||
transform: scale(1.25, 1.25);
|
||||
transition-duration: .3s;
|
||||
}
|
||||
|
||||
#leftElements {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#titlebar {
|
||||
/* padding: 10px 0; */
|
||||
color: black;
|
||||
height: fit-content;
|
||||
margin: 0px 20px;
|
||||
font-size: 36px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
#menu {
|
||||
display: flex;
|
||||
height: fit-content;
|
||||
|
||||
}
|
||||
|
||||
#menu a {
|
||||
display: block;
|
||||
margin: 0px 10px;
|
||||
padding: 0px 10px;
|
||||
font-size: 28px;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#menu a.active {
|
||||
border-bottom: 3px solid #2A93B0;
|
||||
|
||||
}
|
||||
|
||||
#menu a:hover {
|
||||
transform: scale(1.25, 1.25);
|
||||
transition-duration: .3s;
|
||||
}
|
||||
|
||||
.separator{
|
||||
width: 100%;
|
||||
padding:6px;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
.json-block {
|
||||
height: 600px;
|
||||
width: 97%;
|
||||
}
|
||||
|
||||
.json-border {
|
||||
border: 2px solid rgba(93, 99, 96, 0.705);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.json-border:focus {
|
||||
box-shadow: 0 0 5px rgb(81, 203, 238);
|
||||
border: 2px solid rgba(93, 99, 96, 0.705);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/*! Theme: Default Description: Original highlight.js style Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org> Maintainer: @highlightjs/core-team Website: https://highlightjs.org/ License: see project LICENSE Touched: 2021 */
|
||||
pre code.hljs{
|
||||
display:block;
|
||||
overflow-x:auto;
|
||||
padding:1em
|
||||
}
|
||||
code.hljs{
|
||||
padding:3px 5px
|
||||
}
|
||||
.hljs{
|
||||
background:#FFFFFF;
|
||||
color:#444
|
||||
}
|
||||
.hljs-comment{
|
||||
color:#697070
|
||||
}
|
||||
.hljs-punctuation,.hljs-tag{
|
||||
color:#444a
|
||||
}
|
||||
.hljs-tag .hljs-attr,.hljs-tag .hljs-name{
|
||||
color:#444
|
||||
}
|
||||
.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{
|
||||
font-weight:700
|
||||
}
|
||||
.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{
|
||||
color:#800
|
||||
}
|
||||
.hljs-section,.hljs-title{
|
||||
color:#800;
|
||||
font-weight:700
|
||||
}
|
||||
.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{
|
||||
color:#ab5656
|
||||
}
|
||||
.hljs-literal{
|
||||
color:#695
|
||||
}
|
||||
.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{
|
||||
color:#397300
|
||||
}
|
||||
.hljs-meta{
|
||||
color:#1f7199
|
||||
}
|
||||
.hljs-meta .hljs-string{
|
||||
color:#38a
|
||||
}
|
||||
.hljs-emphasis{
|
||||
font-style:italic
|
||||
}
|
||||
.hljs-strong{
|
||||
font-weight:700
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200&display=swap');
|
||||
|
||||
body {
|
||||
font-family: "Nunito", sans-serif;
|
||||
background-color: #FFFFFF;
|
||||
margin: 0px;
|
||||
|
||||
}
|
||||
h1, h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2::before {
|
||||
background: url('/assets/images/sygnet_color.svg') no-repeat;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#header {
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#logo {
|
||||
width: 250px;
|
||||
margin: 0px 20px;
|
||||
}
|
||||
|
||||
#content {
|
||||
width: 1024px;
|
||||
margin: auto;
|
||||
text-align: justify;
|
||||
background-color: #FFFFFF;
|
||||
padding: 20px 20px;
|
||||
border-radius: 15px;
|
||||
margin-top: 100px;
|
||||
}
|
||||
Binary file not shown.
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2021 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="fontello" horiz-adv-x="1000" >
|
||||
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="plus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
|
||||
|
||||
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
59
Frontend/assets/css/tools/fontello.css
vendored
59
Frontend/assets/css/tools/fontello.css
vendored
@@ -1,59 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('font/fontello.eot?49304387');
|
||||
src: url('font/fontello.eot?49304387#iefix') format('embedded-opentype'),
|
||||
url('font/fontello.woff2?49304387') format('woff2'),
|
||||
url('font/fontello.woff?49304387') format('woff'),
|
||||
url('font/fontello.ttf?49304387') format('truetype'),
|
||||
url('font/fontello.svg?49304387#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
|
||||
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
|
||||
/*
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.svg?49304387#fontello') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[class^="icon-"]:before, [class*=" icon-"]:before {
|
||||
font-family: "fontello";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: never;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
margin-right: .2em;
|
||||
text-align: center;
|
||||
/* opacity: .8; */
|
||||
|
||||
/* For safety - reset parent styles, that can break glyph codes*/
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
/* fix buttons height, for twitter bootstrap */
|
||||
line-height: 1em;
|
||||
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
/* remove if not needed */
|
||||
margin-left: .2em;
|
||||
|
||||
/* you can be more comfortable with increased icons size */
|
||||
/* font-size: 120%; */
|
||||
|
||||
/* Font smoothing. That was taken from TWBS */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Uncomment for 3D effect */
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
|
||||
.icon-plus:before { content: '\e801'; } /* '' */
|
||||
.icon-cancel:before { content: '\e802'; } /* '' */
|
||||
@@ -1,34 +0,0 @@
|
||||
@import url('https://necolas.github.io/normalize.css/8.0.1/normalize.css');
|
||||
/* @import url('https://fonts.googleapis.com/icon?family=Material+Icons'); */
|
||||
@import url('r11addons.css');
|
||||
@import url('r11tables.css');
|
||||
@import url('r11tool.css');
|
||||
@import url('r11tooltip.css');
|
||||
@import url('r11modal.css');
|
||||
@import url('r11flexbox.css');
|
||||
@import url('r11popup.css');
|
||||
@import url('../../highlight.css');
|
||||
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(https://fonts.gstatic.com/s/materialicons/v140/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2');
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-moz-font-feature-settings: 'liga';
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2021 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="fontello" horiz-adv-x="1000" >
|
||||
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="plus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
|
||||
|
||||
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
59
Frontend/assets/css/tools/mock/fontello.css
vendored
59
Frontend/assets/css/tools/mock/fontello.css
vendored
@@ -1,59 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('font/fontello.eot?49304387');
|
||||
src: url('font/fontello.eot?49304387#iefix') format('embedded-opentype'),
|
||||
url('font/fontello.woff2?49304387') format('woff2'),
|
||||
url('font/fontello.woff?49304387') format('woff'),
|
||||
url('font/fontello.ttf?49304387') format('truetype'),
|
||||
url('font/fontello.svg?49304387#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
|
||||
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
|
||||
/*
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.svg?49304387#fontello') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[class^="icon-"]:before, [class*=" icon-"]:before {
|
||||
font-family: "fontello";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: never;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
margin-right: .2em;
|
||||
text-align: center;
|
||||
/* opacity: .8; */
|
||||
|
||||
/* For safety - reset parent styles, that can break glyph codes*/
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
/* fix buttons height, for twitter bootstrap */
|
||||
line-height: 1em;
|
||||
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
/* remove if not needed */
|
||||
margin-left: .2em;
|
||||
|
||||
/* you can be more comfortable with increased icons size */
|
||||
/* font-size: 120%; */
|
||||
|
||||
/* Font smoothing. That was taken from TWBS */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Uncomment for 3D effect */
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
|
||||
.icon-plus:before { content: '\e801'; } /* '' */
|
||||
.icon-cancel:before { content: '\e802'; } /* '' */
|
||||
@@ -1,4 +0,0 @@
|
||||
.overflowedTableContent {
|
||||
max-height: 750px;
|
||||
overflow: scroll;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
.modification-button.btn-tile:hover {
|
||||
color: #ca1111;
|
||||
}
|
||||
|
||||
.modification-button.btn-tile {
|
||||
width: 10%;
|
||||
margin: 20% 0 0 0;
|
||||
font-size: 14px;
|
||||
color: #00000020
|
||||
}
|
||||
|
||||
.modification-button.btn-addtile {
|
||||
font-size: 38px;
|
||||
color: #00000030;
|
||||
}
|
||||
|
||||
.modification-button.btn-copy {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
align-content: center;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modification-button.btn-copy img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.modification-button.btn-addtile:hover {
|
||||
color: #58ac43;
|
||||
}
|
||||
|
||||
.tile {
|
||||
width: 100%;
|
||||
padding-top: 40%;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
background: #D5D7E6;
|
||||
margin-bottom: 10px;
|
||||
cursor: default;
|
||||
border-bottom: 1px solid darkgray;
|
||||
}
|
||||
|
||||
.tile:hover {
|
||||
filter: brightness(110%);
|
||||
}
|
||||
|
||||
.tile.active {
|
||||
background: #2A93B0;
|
||||
color: white;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.tile.active .btn-tile {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tile .content {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0 2% 0 7%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.content p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.refresh-button{
|
||||
float: right;
|
||||
border: none;
|
||||
background-color: unset;
|
||||
font-size: xx-large;
|
||||
}
|
||||
|
||||
.refresh-button:hover{
|
||||
animation-name: rotation;
|
||||
animation-duration: 0.8s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
|
||||
@keyframes rotation{
|
||||
from{
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#editable-block {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#uuid-edit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#uuid-edit-field {
|
||||
display: flex;
|
||||
width: fit-content;
|
||||
align-items: center;
|
||||
width: 70%;
|
||||
margin-right: 10px;
|
||||
|
||||
}
|
||||
|
||||
#uuid-edit-field .uuid-inputField-icon{
|
||||
background: none;
|
||||
color: black;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#uuid-edit-field .uuid-inputField-icon:hover{
|
||||
color: #2A93B0;
|
||||
}
|
||||
|
||||
#uuid-input {
|
||||
border: none;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#uuid-input:focus {
|
||||
outline: none;
|
||||
|
||||
}
|
||||
|
||||
#uuid-validation-strategy input {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
background-color: #CCD1CF;
|
||||
|
||||
}
|
||||
|
||||
.disabled #uuid-input {
|
||||
background-color: #CCD1CF;
|
||||
|
||||
}
|
||||
|
||||
.uuid-inputField-icon-span {
|
||||
font-size: x-large;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
#overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
opacity: 0;
|
||||
background: rgba(0, 0 , 0, 0.5);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#overlay.active {
|
||||
pointer-events: all;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
width: 390px;
|
||||
min-height: 71px;
|
||||
max-height: 700px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
padding: 5px;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.modal.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.modal div.header {
|
||||
width: 384px;
|
||||
height: 24px;
|
||||
background: #2e3133;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
padding: 3px;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal div.header button {
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
background: 0;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal div.header button:hover {
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.modal div.body {
|
||||
width: 370px;
|
||||
padding: 10px;
|
||||
background: #f0f0f0;
|
||||
color: #2e3133;
|
||||
min-height: 16px;
|
||||
text-align: justify;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.modal div.function {
|
||||
width: 385px;
|
||||
min-height: 30px;
|
||||
padding-top: 5px;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.modal div.function button {
|
||||
min-height: 22px;
|
||||
min-width: 34px;
|
||||
max-width: 74px;
|
||||
padding: 3px 20px;
|
||||
outline: none;
|
||||
border: 1px solid #f0f0f0;
|
||||
background: rgba(205,205,205,1);
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal div.function button:hover {
|
||||
filter: brightness(110%);
|
||||
}
|
||||
|
||||
.r-exclamation:before {
|
||||
content: '!';
|
||||
color: #3bc4f1;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
.popup-flex:not(.hiddable-container){
|
||||
animation: blur 0.5s ease-in-out ;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
.popup-flex{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 50;
|
||||
flex-direction: column;
|
||||
gap: 2%;
|
||||
position: fixed;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.popup-body{
|
||||
min-width: 33%;
|
||||
max-width: 60%;
|
||||
max-height: 70%;
|
||||
background-color: white;
|
||||
box-shadow: 10px 10px 5px lightblue;
|
||||
min-height: 45%;
|
||||
border-radius: 1em;
|
||||
text-align: center;
|
||||
padding: 10px 15px 15px 15px;
|
||||
color: black;
|
||||
border: 1px #2A93B0 solid;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.popup-button-close-container{
|
||||
text-align: right;
|
||||
margin-right: 2%;
|
||||
margin-top: 1%;
|
||||
font-size: xx-large;
|
||||
font-weight: bold;
|
||||
position: sticky;
|
||||
top:0
|
||||
}
|
||||
|
||||
.hiddable-popup-option{
|
||||
flex-grow: 1;
|
||||
overflow: auto;
|
||||
padding: 1.5%;
|
||||
}
|
||||
|
||||
.popup-button-close{
|
||||
background: padding-box;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.popup-button-close:hover{
|
||||
color: #2A93B0;
|
||||
}
|
||||
|
||||
.hiddable-container{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.hidden-popup-type{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#history-request-body{
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
@keyframes blur {
|
||||
0% {
|
||||
backdrop-filter: blur(0px);
|
||||
}
|
||||
|
||||
50% {
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
100% {
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
.table-map {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.table-map input{
|
||||
font-size: 16px;
|
||||
padding: 7px;
|
||||
border: 1px solid rgba(145, 146, 146, 0.849);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.table-map input.key {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.modification-button.btn-add {
|
||||
font-size: 16px;
|
||||
color: #00000030;
|
||||
margin: auto 0 auto 0;
|
||||
}
|
||||
|
||||
.modification-button.btn-add:hover {
|
||||
color:#58ac43;
|
||||
}
|
||||
|
||||
.modification-button.btn-hashmap {
|
||||
font-size: 16px;
|
||||
color: #00000030;
|
||||
margin: auto 0 auto 0;
|
||||
}
|
||||
|
||||
.modification-button.btn-hashmap:hover {
|
||||
color: #ca1111;
|
||||
}
|
||||
|
||||
.table-default {
|
||||
width: 80%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.table-default tr {
|
||||
background: #f0f0f02d;
|
||||
}
|
||||
|
||||
.table-default tr.bottom-border {
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
.table-default th {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.table-default tr.even {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.table-doc td, .table-doc th{
|
||||
border-spacing: 0px;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
.table-doc td {
|
||||
background-color: rgba(155, 165, 160, 0.342);
|
||||
}
|
||||
|
||||
.table-doc th {
|
||||
background-color: #3bc4f1;
|
||||
text-align: left;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table-default td{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#header-table tr td {
|
||||
border: 1px black solid;
|
||||
padding: 1.5%;
|
||||
|
||||
}
|
||||
|
||||
#header-table{
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.history-header-name{
|
||||
min-width: 10vw;
|
||||
}
|
||||
|
||||
#historyTable, td{
|
||||
padding: 1%;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "Nunito";
|
||||
src: url('font/Nunito-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
||||
|
||||
input {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.hyperlink, .hyperlink:visited, .hyperlink:active {
|
||||
color: rgb(47, 125, 146);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hyperlink:hover {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
.bordered-field {
|
||||
background-color: #FFFFFF;
|
||||
border: 2px solid rgba(93, 99, 96, 0.705);
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
.bordered-field:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 5px rgba(81, 203, 238);
|
||||
border: 2px solid #00000070;
|
||||
}
|
||||
|
||||
.bordered-field:disabled {
|
||||
background: #eeeeeed2;
|
||||
}
|
||||
|
||||
.vertically-resizeable {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tool {
|
||||
width: 55%;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.tool.extended {
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
.tool .tool-context {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.tool.extended .tool-extention {
|
||||
width: 20%;
|
||||
padding-top: 2%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool .tool-extention {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-extention {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tool-extention.active {
|
||||
opacity: 100%;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.clickable-text {
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: none;
|
||||
border: none;
|
||||
font-weight: 300;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.clickable-text.highlight:hover {
|
||||
color: #3bc4f1;
|
||||
}
|
||||
|
||||
.clickable-text.switch {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.clickable-text.switch span.toggleIndicator:before {
|
||||
content: '>';
|
||||
}
|
||||
|
||||
.clickable-text.switch span.toggleIndicator.active:before {
|
||||
content: 'v';
|
||||
}
|
||||
|
||||
.modification-button {
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: none;
|
||||
border: none;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.text-aligned-to-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.centered-vertically {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.display-space-between {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.display-space-evenly {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.float-left {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.version-span {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: rgba(85,85,85,0.555);
|
||||
}
|
||||
|
||||
.block-display {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.block-label {
|
||||
display: block;
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
.tabmenu {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid rgba(185, 185, 185, 0.5);
|
||||
}
|
||||
|
||||
.tabitem {
|
||||
flex-grow: 1;
|
||||
cursor: pointer;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.tabitem:hover {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.tabitem.active {
|
||||
background: rgba(33, 34, 34, 0.705);
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
cursor:default;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.big-font {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.action-button.active {
|
||||
background: #2A93B0;
|
||||
border: 1px solid #7ed0eb;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
.action-button.active:hover {
|
||||
filter: brightness(110%);
|
||||
}
|
||||
|
||||
.action-button {
|
||||
background: #CCD1CF;
|
||||
border:1px solid rgba(186, 197, 191, 0.507);
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
font-weight: 700;
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.quater-width {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.half-width {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.tree-fourth-width {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.half-width.with-padding {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.max-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.max-width.with-padding {
|
||||
width: 94%;
|
||||
}
|
||||
|
||||
.max-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.height-300 {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.max-height.with-padding {
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
.small-margins {
|
||||
margin: 3%;
|
||||
}
|
||||
|
||||
.small-vertical-margin {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.medium-vertical-margin {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.large-vertical-margin {
|
||||
margin-top: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.textarea-300 {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.centered-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tabcontent.active {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hiddable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hiddable.active {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
/* In case of collision with classes that use 'active' */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* TODO: Add proper class */
|
||||
/* textarea {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
} */
|
||||
|
||||
/* TODO: Add proper class */
|
||||
/* code{
|
||||
line-height: 150%;
|
||||
} */
|
||||
@@ -1,76 +0,0 @@
|
||||
.tooltip-window {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
background: #FFFFFF;
|
||||
padding: 15px 30px;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.tooltip-window.lite {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.tip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tip.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* TODO: Remove !important. It's bad practice and it can cause errors in future */
|
||||
.section-button {
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
font-size: 18px;
|
||||
background: #b4b4b4c5;
|
||||
cursor: pointer;
|
||||
border-bottom: darkgray 2px solid !important;
|
||||
}
|
||||
|
||||
.section-button:hover {
|
||||
backdrop-filter: brightness(110%);
|
||||
}
|
||||
|
||||
.section-button .active {
|
||||
background: #00000030;
|
||||
}
|
||||
|
||||
.List .collapsibleContent {
|
||||
border-left: #bdc5c9 2px solid;
|
||||
overflow: hidden;
|
||||
background: #ffffff50;
|
||||
}
|
||||
|
||||
/* TODO: .section class is to generic. It should be renamed */
|
||||
.section{
|
||||
padding: 10px 0px 20px 0px ;
|
||||
}
|
||||
|
||||
/* TODO: content subclass already in use. Creating content class overrides the subclass.
|
||||
Make .content a subclass of .content */
|
||||
/* .content {
|
||||
padding: 0px 15px 0px 15px ;
|
||||
text-align: justify;
|
||||
overflow: hidden;
|
||||
transition: max-height .2s ease-out;
|
||||
max-height: 0px;
|
||||
border-left: #c0c2c3 2px solid;
|
||||
|
||||
} */
|
||||
|
||||
.collapsibleMini::before{
|
||||
content: "►";
|
||||
}
|
||||
|
||||
.collapsibleMini.active::before{
|
||||
content: "▼";
|
||||
}
|
||||
|
||||
/* TODO: Add proper class */
|
||||
/* button:hover{
|
||||
filter: brightness(110%);
|
||||
} */
|
||||
@@ -1,520 +0,0 @@
|
||||
@import url('https://necolas.github.io/normalize.css/8.0.1/normalize.css');
|
||||
@import url('fontello.css');
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito";
|
||||
src: url('../../fonts/Nunito-VariableFont_wght.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.hyperlink, .hyperlink:visited, .hyperlink:active {
|
||||
color: rgb(47, 125, 146);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hyperlink:hover {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
.tooltip-window {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
/* filter: drop-shadow(-2px 0px 2px black); */
|
||||
background: #FFFFFF;
|
||||
padding: 15px 30px;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
width: 30%;
|
||||
height: calc(100% - 25px);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.tooltip-window.lite {
|
||||
width: 30%;
|
||||
}
|
||||
/* .hyperlink.collapseTrigger::before{
|
||||
content: "▼";
|
||||
} */
|
||||
|
||||
.bordered-field {
|
||||
border: 2px solid rgba(93, 99, 96, 0.705);
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
|
||||
}
|
||||
|
||||
.bordered-field:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 5px rgba(81, 203, 238);
|
||||
border: 2px solid #00000070;
|
||||
}
|
||||
|
||||
.bordered-field:disabled {
|
||||
background: #eeeeeed2;
|
||||
}
|
||||
|
||||
.vertically-resizeable {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.container {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
|
||||
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tool {
|
||||
width: 65%;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.tool.extended {
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
.tool .tool-context {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.tool.extended .tool-context {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.tool.extended .tool-extention {
|
||||
width: 20%;
|
||||
padding-top: 2%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool .tool-extention {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-extention {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tool-extention.active {
|
||||
opacity: 100%;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.clickable-text {
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: none;
|
||||
border: none;
|
||||
font-weight: 300;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.clickable-text.highlight:hover {
|
||||
color: #3bc4f1;
|
||||
}
|
||||
|
||||
.modification-button {
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: none;
|
||||
border: none;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.modification-button.btn-add {
|
||||
font-size: 16px;
|
||||
color: #00000030;
|
||||
margin: auto 0 auto 0;
|
||||
}
|
||||
|
||||
.modification-button.btn-add:hover {
|
||||
color:#58ac43;
|
||||
}
|
||||
|
||||
.modification-button.btn-tile:hover {
|
||||
color: #ca1111;
|
||||
}
|
||||
|
||||
.modification-button.btn-hashmap {
|
||||
font-size: 16px;
|
||||
color: #00000030;
|
||||
margin: auto 0 auto 0;
|
||||
}
|
||||
|
||||
.modification-button.btn-hashmap:hover {
|
||||
color: #ca1111;
|
||||
}
|
||||
|
||||
.modification-button.btn-tile {
|
||||
width: 10%;
|
||||
margin: 20% 0 0 0;
|
||||
font-size: 14px;
|
||||
color: #00000020
|
||||
}
|
||||
|
||||
.tile {
|
||||
width: 90%;
|
||||
padding-top: 40%;
|
||||
border: 1px solid gray;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
background: #f0f0f095;
|
||||
margin-bottom: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.tile:hover {
|
||||
filter: brightness(110%);
|
||||
}
|
||||
|
||||
.tile.active {
|
||||
background: #00000070;
|
||||
color: white;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.tile .content {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0 2% 0 7%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.text-aligned-to-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.centered-vertically {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.display-space-between {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.content p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
.float-left {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.version-span {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: rgba(85,85,85,0.555);
|
||||
}
|
||||
|
||||
.block-display {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.block-label {
|
||||
display: block;
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
.tabmenu {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid rgba(185, 185, 185, 0.5);
|
||||
}
|
||||
|
||||
.tabitem {
|
||||
flex-grow: 1;
|
||||
cursor: pointer;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.tabitem:hover {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.tabitem.active {
|
||||
background: rgba(33, 34, 34, 0.705);
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
cursor:default;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.big-font {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.action-button.active {
|
||||
background: #2A93B0;
|
||||
border: 1px solid #7ed0eb;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.action-button.active:hover {
|
||||
filter: brightness(110%);
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
background: rgba(155, 165, 160, 0.507);
|
||||
border:1px solid rgba(186, 197, 191, 0.507);
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
font-weight: 700;
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.quater-width {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.half-width {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.half-width.with-padding {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.max-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.half-width {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.max-width.with-padding {
|
||||
width: 94%;
|
||||
}
|
||||
|
||||
.max-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.height-300 {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.max-height.with-padding {
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
.small-margins {
|
||||
margin: 3%;
|
||||
}
|
||||
|
||||
.small-vertical-margin {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.medium-vertical-margin {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.large-vertical-margin {
|
||||
margin-top: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.textarea-300 {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.textarea-700 {
|
||||
height: 700px;
|
||||
}
|
||||
|
||||
.centered-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.table-map {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.table-map input{
|
||||
font-size: 16px;
|
||||
padding: 7px;
|
||||
border: 1px solid rgba(145, 146, 146, 0.849);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.table-map input.key {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.table-default {
|
||||
width: 80%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.table-default tr {
|
||||
background: #f0f0f02d;
|
||||
}
|
||||
|
||||
.table-default tr.bottom-border {
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
.table-default th {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.table-default tr.even {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.tip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tip.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tabcontent.active {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.section-button {
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
margin: 5px 0px;
|
||||
font-size: 18px;
|
||||
background: #D5D7E6;
|
||||
cursor: pointer;
|
||||
border-bottom: darkgray 2px solid !important;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.section-button:hover {
|
||||
/* border-bottom: #3bc4f1 2px solid; */
|
||||
backdrop-filter: brightness(100%);
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
.section-button .active {
|
||||
background: #00000030;
|
||||
}
|
||||
|
||||
.List .collapsibleContent {
|
||||
/* display: none; */
|
||||
border-left: #bdc5c9 2px solid;
|
||||
|
||||
/* max-height: 0px; */
|
||||
/* border-left: #ededed solid 1px; */
|
||||
overflow: hidden;
|
||||
background: #ffffff50;
|
||||
}
|
||||
|
||||
.section{
|
||||
padding: 10px 0px 20px 0px ;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0px 15px 0px 15px ;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
transition: max-height .2s ease-out;
|
||||
max-height: 0px;
|
||||
border-left: #c0c2c3 2px solid;
|
||||
}
|
||||
|
||||
.collapsibleMini::before{
|
||||
content: "►";
|
||||
}
|
||||
|
||||
.collapsibleMini.active::before{
|
||||
content: "▼";
|
||||
}
|
||||
|
||||
.hiddable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hiddable.active {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
/* In case of collision with classes that use 'active' */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button:hover{
|
||||
filter: brightness(110%);
|
||||
}
|
||||
|
||||
.table-doc td, .table-doc th{
|
||||
border-spacing: 0px;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
.table-doc td {
|
||||
background-color: rgba(155, 165, 160, 0.342);
|
||||
}
|
||||
|
||||
.table-doc th {
|
||||
background-color: #3bc4f1;
|
||||
text-align: left;
|
||||
color: white;
|
||||
}
|
||||
|
||||
textarea {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
code {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.rwd-hideable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.rwd-expandable {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 291 KiB |
@@ -1,14 +0,0 @@
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:b="http://www.release11.com/book" xmlns:p="http://www.release11.com/person"
|
||||
xmlns:l="http://www.release11.com/library">
|
||||
<xsl:template match="/">
|
||||
<Library>
|
||||
<ReaderCount>
|
||||
<xsl:value-of select="count(//p:person)" />
|
||||
</ReaderCount>
|
||||
<BookCount>
|
||||
<xsl:value-of select="count(/l:library/l:bookList/b:book)" />
|
||||
</BookCount>
|
||||
</Library>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<library>
|
||||
<libraryName>City library</libraryName>
|
||||
<libraryID>345123</libraryID>
|
||||
<readerList>
|
||||
<person>
|
||||
<readerID>7321</readerID>
|
||||
<name>Adam</name>
|
||||
<surname>Choke</surname>
|
||||
</person>
|
||||
<person>
|
||||
<readerID>5123</readerID>
|
||||
<name>Lauren</name>
|
||||
<surname>Wong</surname>
|
||||
</person>
|
||||
</readerList>
|
||||
<bookList>
|
||||
<book>
|
||||
<bookID>6422</bookID>
|
||||
<title>Harry Potter</title>
|
||||
<readerID>7542</readerID>
|
||||
</book>
|
||||
<book>
|
||||
<bookID>1234</bookID>
|
||||
<title>Macbeth</title>
|
||||
<readerID>5123</readerID>
|
||||
</book>
|
||||
<book>
|
||||
<bookID>9556</bookID>
|
||||
<title>Romeo and Juliet</title>
|
||||
</book>
|
||||
</bookList>
|
||||
</library>
|
||||
@@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
|
||||
targetNamespace="">
|
||||
<xsd:element name="library">
|
||||
<xsd:complexType mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element minOccurs="0" name="libraryName" type="xsd:string" />
|
||||
<xsd:element minOccurs="0" name="libraryID" type="xsd:int" />
|
||||
<xsd:element minOccurs="0" name="readerList">
|
||||
<xsd:complexType mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element maxOccurs="unbounded" name="person">
|
||||
<xsd:complexType mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element minOccurs="0" name="readerID" type="xsd:int" />
|
||||
<xsd:element minOccurs="0" name="name" type="xsd:normalizedString" />
|
||||
<xsd:element minOccurs="0" name="surname" type="xsd:normalizedString" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element minOccurs="0" name="bookList">
|
||||
<xsd:complexType mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element maxOccurs="unbounded" name="book">
|
||||
<xsd:complexType mixed="true">
|
||||
<xsd:sequence>
|
||||
<xsd:element minOccurs="0" name="bookID" type="xsd:int" />
|
||||
<xsd:element minOccurs="0" name="title" type="xsd:string" />
|
||||
<xsd:element minOccurs="0" name="readerID" type="xsd:int" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
1202
Frontend/assets/scripts/common/hljs.min.js
vendored
1202
Frontend/assets/scripts/common/hljs.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,123 +0,0 @@
|
||||
const tools = new Map();
|
||||
|
||||
/**
|
||||
* Get address of Mock Services
|
||||
*
|
||||
* @function
|
||||
* @name getMockHost
|
||||
* @kind function
|
||||
* @returns {string}
|
||||
*/
|
||||
function getMockHost() {
|
||||
return window.location.protocol + "//" + window.location.hostname + ":8097";
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called after page is loaded
|
||||
*
|
||||
* @function
|
||||
* @name init
|
||||
* @kind function
|
||||
* @returns {void}
|
||||
*/
|
||||
function init() {
|
||||
|
||||
tools.set("xpath", "tools/xpath.html");
|
||||
tools.set("xsd", "tools/xsd.html");
|
||||
tools.set("xslt", "tools/xslt.html");
|
||||
tools.set("xmlform", "tools/xmlFormatter.html");
|
||||
tools.set("jsonform", "tools/jsonFormatter.html");
|
||||
tools.set("mock", "tools/mock.html");
|
||||
|
||||
changeActiveTools('XML');
|
||||
var toolUrl = window.location.search.substring(1);
|
||||
if (tools.has(toolUrl))
|
||||
changeTool(toolUrl, false);
|
||||
else
|
||||
loadLastPage();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that updates list of tools depending on chosen category
|
||||
*
|
||||
* @function
|
||||
* @name changeActiveTools
|
||||
* @kind function
|
||||
* @param {any} activeClass class of elements that have to be shown
|
||||
* @param {any} activeCategoryButton class of category button that has to be active
|
||||
*/
|
||||
function changeActiveTools(activeCategoryButton) {
|
||||
let toolList = document.getElementById("toolList").children;
|
||||
let categoryToClass = new Map([["XML", "xmlTool"],
|
||||
["JSON", "jsonTool"],
|
||||
["REST", "restTool"]]);
|
||||
|
||||
let activeClass = categoryToClass.get(activeCategoryButton.toUpperCase());
|
||||
if(activeClass == null) return;
|
||||
|
||||
for (i = 0; i < toolList.length; i++) {
|
||||
if (toolList[i].classList.contains(activeClass))
|
||||
toolList[i].style.display = "block";
|
||||
else
|
||||
toolList[i].style.display = "none";
|
||||
}
|
||||
|
||||
let categoryList = document.getElementById("menu").children;
|
||||
|
||||
for (i = 0; i < categoryList.length; i++) {
|
||||
if (categoryList[i].innerText == activeCategoryButton)
|
||||
categoryList[i].classList.add("active");
|
||||
else
|
||||
categoryList[i].classList.remove("active");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function changes active tool.
|
||||
* Optional updateURL can be set to false to stop changing URL.
|
||||
* This helps avoiding endless reload loop when loading page.
|
||||
*
|
||||
* @function
|
||||
* @name changeTool
|
||||
* @kind function
|
||||
* @param {any} tool
|
||||
* @param {boolean} updateURL?
|
||||
* @returns {void}
|
||||
*/
|
||||
function changeTool(tool, updateURL = true) {
|
||||
if (! tools.has(tool)) return;
|
||||
const url = tools.get(tool);
|
||||
if (updateURL) document.location.search = tool;
|
||||
|
||||
|
||||
switch (tool) { // XML category is default.
|
||||
case "jsonform":
|
||||
changeActiveTools('JSON');
|
||||
break;
|
||||
case "mock":
|
||||
changeActiveTools('REST');
|
||||
break;
|
||||
}
|
||||
|
||||
localStorage.setItem("lastPage", tool);
|
||||
document.getElementById("iframe").src = url;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that loads last used tool and sets active category accordingly
|
||||
*
|
||||
* @function
|
||||
* @name loadLastPage
|
||||
* @kind function
|
||||
* @returns {void}
|
||||
*/
|
||||
function loadLastPage() {
|
||||
var lastPage = localStorage.getItem("lastPage");
|
||||
if (lastPage == null) {
|
||||
lastPage = "xpath";
|
||||
}
|
||||
changeTool(lastPage);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* This file contains scripts needed for syntax highlight to work.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This functions highlight element with provided ID.
|
||||
*
|
||||
* @function
|
||||
* @name highlightSyntax
|
||||
* @kind function
|
||||
* @param {any} elementId
|
||||
* @returns {void}
|
||||
*/
|
||||
function highlightSyntax(elementId) {
|
||||
const element = document.getElementById(elementId);
|
||||
element.innerHTML = hljs.highlightAuto(element.innerText).value
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pasted data to plain text
|
||||
*
|
||||
* @function
|
||||
* @name configurePastingInElement
|
||||
* @kind function
|
||||
* @param {any} elementId
|
||||
* @returns {void}
|
||||
*/
|
||||
function configurePastingInElement(elementId) {
|
||||
const editorEle = document.getElementById(elementId);
|
||||
|
||||
// Handle the `paste` event
|
||||
editorEle.addEventListener('paste', function (e) {
|
||||
// Prevent the default action
|
||||
e.preventDefault();
|
||||
|
||||
// Get the copied text from the clipboard
|
||||
const text = e.clipboardData
|
||||
? (e.originalEvent || e).clipboardData.getData('text/plain')
|
||||
: // For IE
|
||||
window.clipboardData
|
||||
? window.clipboardData.getData('Text')
|
||||
: '';
|
||||
|
||||
if (document.queryCommandSupported('insertText')) {
|
||||
document.execCommand('insertText', false, text);
|
||||
} else {
|
||||
// Insert text at the current position of caret
|
||||
const range = document.getSelection().getRangeAt(0);
|
||||
range.deleteContents();
|
||||
|
||||
const textNode = document.createTextNode(text);
|
||||
range.insertNode(textNode);
|
||||
range.selectNodeContents(textNode);
|
||||
range.collapse(false);
|
||||
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
highlightSyntax(editorEle.id);
|
||||
|
||||
});
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
|
||||
|
||||
const mergeHTMLPlugin = (function () {
|
||||
'use strict';
|
||||
|
||||
var originalStream;
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @returns {string}
|
||||
*/
|
||||
function escapeHTML(value) {
|
||||
return value
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
|
||||
/* plugin itself */
|
||||
|
||||
/** @type {HLJSPlugin} */
|
||||
const mergeHTMLPlugin = {
|
||||
// preserve the original HTML token stream
|
||||
"before:highlightElement": ({ el }) => {
|
||||
originalStream = nodeStream(el);
|
||||
},
|
||||
// merge it afterwards with the highlighted token stream
|
||||
"after:highlightElement": ({ el, result, text }) => {
|
||||
if (!originalStream.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resultNode = document.createElement('div');
|
||||
resultNode.innerHTML = result.value;
|
||||
result.value = mergeStreams(originalStream, nodeStream(resultNode), text);
|
||||
el.innerHTML = result.value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
function tag(node) {
|
||||
return node.nodeName.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
function nodeStream(node) {
|
||||
/** @type Event[] */
|
||||
const result = [];
|
||||
(function _nodeStream(node, offset) {
|
||||
for (let child = node.firstChild; child; child = child.nextSibling) {
|
||||
if (child.nodeType === 3) {
|
||||
offset += child.nodeValue.length;
|
||||
} else if (child.nodeType === 1) {
|
||||
result.push({
|
||||
event: 'start',
|
||||
offset: offset,
|
||||
node: child
|
||||
});
|
||||
offset = _nodeStream(child, offset);
|
||||
|
||||
if (!tag(child).match(/br|hr|img|input/)) {
|
||||
result.push({
|
||||
event: 'stop',
|
||||
offset: offset,
|
||||
node: child
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
})(node, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} original - the original stream
|
||||
* @param {any} highlighted - stream of the highlighted source
|
||||
* @param {string} value - the original source itself
|
||||
*/
|
||||
function mergeStreams(original, highlighted, value) {
|
||||
let processed = 0;
|
||||
let result = '';
|
||||
const nodeStack = [];
|
||||
|
||||
function selectStream() {
|
||||
if (!original.length || !highlighted.length) {
|
||||
return original.length ? original : highlighted;
|
||||
}
|
||||
if (original[0].offset !== highlighted[0].offset) {
|
||||
return (original[0].offset < highlighted[0].offset) ? original : highlighted;
|
||||
}
|
||||
|
||||
return highlighted[0].event === 'start' ? original : highlighted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
function open(node) {
|
||||
/** @param {Attr} attr */
|
||||
function attributeString(attr) {
|
||||
return ' ' + attr.nodeName + '="' + escapeHTML(attr.value) + '"';
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('')
|
||||
+ '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
function close(node) {
|
||||
result += '</' + tag(node) + '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} event
|
||||
*/
|
||||
function render(event) {
|
||||
(event.event === 'start' ? open : close)(event.node);
|
||||
}
|
||||
|
||||
while (original.length || highlighted.length) {
|
||||
let stream = selectStream();
|
||||
result += escapeHTML(value.substring(processed, stream[0].offset));
|
||||
processed = stream[0].offset;
|
||||
if (stream === original) {
|
||||
/*
|
||||
On any opening or closing tag of the original markup we first close
|
||||
the entire highlighted node stack, then render the original tag along
|
||||
with all the following original tags at the same offset and then
|
||||
reopen all the tags on the highlighted stack.
|
||||
*/
|
||||
nodeStack.reverse().forEach(close);
|
||||
do {
|
||||
render(stream.splice(0, 1)[0]);
|
||||
stream = selectStream();
|
||||
} while (stream === original && stream.length && stream[0].offset === processed);
|
||||
nodeStack.reverse().forEach(open);
|
||||
} else {
|
||||
if (stream[0].event === 'start') {
|
||||
nodeStack.push(stream[0].node);
|
||||
} else {
|
||||
nodeStack.pop();
|
||||
}
|
||||
render(stream.splice(0, 1)[0]);
|
||||
}
|
||||
}
|
||||
return result + escapeHTML(value.substr(processed));
|
||||
}
|
||||
|
||||
return mergeHTMLPlugin;
|
||||
|
||||
}());
|
||||
|
||||
function formatAndValidateJson(errorElement) {
|
||||
const input = document.querySelector('#jsonBlock');
|
||||
const processInfo = document.getElementById(errorElement);
|
||||
|
||||
const address = window.location.protocol + "//" + window.location.hostname + ":" + 8081 + "/json/formatting"
|
||||
|
||||
fetch(address, {
|
||||
method: 'POST',
|
||||
body: input.textContent
|
||||
})
|
||||
.then(async (response) => {
|
||||
const promise = response.json();
|
||||
if (!response.ok) {
|
||||
throw Error(await promise);
|
||||
}
|
||||
|
||||
return promise;
|
||||
})
|
||||
.then((data) => {
|
||||
input.innerText = data.data;
|
||||
processInfo.innerText = "";
|
||||
hljs.highlightElement(input);
|
||||
|
||||
processInfo.innerHTML = "<b style='color: green'>Computed in </b> <span style='color: green'>" + data.time + "ms</span>";
|
||||
})
|
||||
.catch((error) => {
|
||||
processInfo.innerHTML = "<b style='color: red'>" + error.data + "</b>";
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function minimizeJson(errorElement) {
|
||||
const input = document.querySelector('#jsonBlock');
|
||||
const processInfo = document.getElementById(errorElement);
|
||||
|
||||
const address = window.location.protocol + "//" + window.location.hostname + ":" + 8081 + "/json/minimize"
|
||||
|
||||
fetch(address, {
|
||||
method: 'POST',
|
||||
body: input.textContent
|
||||
})
|
||||
.then(async (response) => {
|
||||
const promise = response.json();
|
||||
if (!response.ok) {
|
||||
throw Error(await promise);
|
||||
}
|
||||
|
||||
return promise;
|
||||
})
|
||||
.then((data) => {
|
||||
input.innerText = data.data;
|
||||
processInfo.innerText = "";
|
||||
hljs.highlightElement(input);
|
||||
|
||||
processInfo.innerHTML = "<b style='color: green'>Computed in </b> <span style='color: green'>" + data.time + "ms</span>";
|
||||
})
|
||||
.catch((error) => {
|
||||
processInfo.innerHTML = "<b style='color: red'>" + error.data + "</b>";
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function clearJsonData() {
|
||||
const input = document.querySelector('#jsonBlock');
|
||||
input.textContent = "";
|
||||
}
|
||||
|
||||
function insertDefaultJson() {
|
||||
const input = document.querySelector('#jsonBlock');
|
||||
input.textContent = "{\"enter\": \"your\", \"json\": \"here\"}";
|
||||
hljs.highlightElement(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is executed after the page is loaded.
|
||||
*
|
||||
* @function
|
||||
* @name init
|
||||
* @kind function
|
||||
*/
|
||||
function init() {
|
||||
// Make sure that only plain text is pasted
|
||||
configurePastingInElement("jsonBlock");
|
||||
|
||||
hljs.addPlugin(mergeHTMLPlugin);
|
||||
}
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
var clientUUID = '';
|
||||
var advancedDisplayed = false;
|
||||
var json = {};
|
||||
var jsonIndex = 0;
|
||||
var host = window.location.protocol + "//" + window.location.hostname + "/mock";
|
||||
|
||||
const C_UUID = 'mock-uuid';
|
||||
const C_ADV = 'advanced-mode';
|
||||
|
||||
const color_red = "#ff8f8f";
|
||||
const color_grey = "#6b6b6b";
|
||||
|
||||
const setModified = function(){
|
||||
setDataModified();
|
||||
}
|
||||
|
||||
const getUpdate = function(){
|
||||
updateData();
|
||||
}
|
||||
const dataRefresh = function(){
|
||||
getData();
|
||||
}
|
||||
|
||||
/*
|
||||
Listeners segment
|
||||
*/
|
||||
|
||||
$(document).on('change', '.data-field', setModified);
|
||||
|
||||
$('#btn-save').click(
|
||||
() => {
|
||||
disableSaveButton();
|
||||
}
|
||||
);
|
||||
|
||||
$('#btn-newRow').click(
|
||||
()=> {
|
||||
newRowInput();
|
||||
setDataModified();
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
Functions segment
|
||||
*/
|
||||
|
||||
function disableSaveButton(){
|
||||
$('#btn-save').removeClass('active');
|
||||
$('#btn-save').off();
|
||||
}
|
||||
|
||||
function createLink(uuid){
|
||||
var link = host + '/api/mock/r/'+uuid;
|
||||
return link;
|
||||
}
|
||||
|
||||
|
||||
function onLoad(){
|
||||
loadCookies();
|
||||
getData();
|
||||
}
|
||||
|
||||
function getData(){
|
||||
$.getJSON(host + '/api/mock/'+clientUUID, function(data) {
|
||||
json = data;
|
||||
loadFetchedMessage();
|
||||
initializeUUID();
|
||||
});
|
||||
}
|
||||
|
||||
function loadCookies(){
|
||||
clientUUID = getCookie(C_UUID);
|
||||
advancedDisplayed = getCookie(C_ADV) == 'true';
|
||||
}
|
||||
|
||||
function setCookie(){
|
||||
document.cookie = C_UUID + '=' +clientUUID;
|
||||
document.cookie = C_ADV + '=' + advancedVisibility;
|
||||
}
|
||||
|
||||
function initializeUUID(){
|
||||
if(clientUUID == null || clientUUID == undefined || clientUUID == ''){
|
||||
clientUUID = json.clientUUID;
|
||||
setCookie();
|
||||
}
|
||||
}
|
||||
|
||||
function httpStatusInvalid(){
|
||||
value = $('#httpStatus').val();
|
||||
return value == '';
|
||||
}
|
||||
|
||||
function setDataModified(){
|
||||
if(httpStatusInvalid()){
|
||||
$('#btn-save').removeClass('active');
|
||||
$('#btn-save').off();
|
||||
document.getElementById("httpStatus").style.backgroundColor = color_red;
|
||||
return;
|
||||
}
|
||||
$('#btn-save').addClass('active');
|
||||
$('#btn-save').click(getUpdate);
|
||||
document.getElementById("httpStatus").style.backgroundColor = null;
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
var name = cname + '=';
|
||||
var decodedCookie = decodeURIComponent(document.cookie);
|
||||
var ca = decodedCookie.split(';');
|
||||
for(var i = 0; i <ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function updateData(){
|
||||
var updatedJson = createRequestBody();
|
||||
const dataSaved = function () {
|
||||
loadFetchedMessage();
|
||||
savedModalDisplay();
|
||||
}
|
||||
$.ajax({
|
||||
url: host + '/api/mock',
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(updatedJson, null, 2),
|
||||
contentType: "application/json",
|
||||
}).done(dataSaved);
|
||||
disableSaveButton();
|
||||
}
|
||||
|
||||
function loadFetchedMessage(){
|
||||
fillStaticFields(
|
||||
json.clientUUID,
|
||||
json.contentType,
|
||||
json.messageBody,
|
||||
json.httpStatus);
|
||||
fillHeaderTable(json.httpHeaders);
|
||||
getHistoryData();
|
||||
refreshHeaderTable(document.innerHTML);
|
||||
}
|
||||
|
||||
function fillStaticFields(uuid, contentType, body, httpStatus){
|
||||
let link = createLink(uuid);
|
||||
let linkHtml = '<a class="hyperlink" target="_blank" href="'+link+'">'+link+'</a>';
|
||||
$('#messageLink').html(linkHtml);
|
||||
$('#httpStatus').val(httpStatus);
|
||||
$('#typeSelector').val(contentType);
|
||||
$('#bodyEditor').val(body);
|
||||
}
|
||||
|
||||
function fillHeaderTable(headers){
|
||||
var innerHTML = buildHeaderMapHtml(headers);
|
||||
refreshHeaderTable(innerHTML);
|
||||
}
|
||||
|
||||
function refreshHeaderTable(html){
|
||||
$('#headerMapTable').html(html);
|
||||
$('.btn-hashmap').click(function(){
|
||||
setDataModified();
|
||||
$(this).closest('tr').remove();
|
||||
})
|
||||
}
|
||||
|
||||
function buildHeaderMapHtml(headers){
|
||||
var innerHTML = '';
|
||||
for(var key in headers){
|
||||
innerHTML += buildRowHtml(key, headers[key]);
|
||||
}
|
||||
return innerHTML;
|
||||
}
|
||||
|
||||
function addRow(key, value){
|
||||
var headerMap = $('#headerMapTable');
|
||||
var headersMapHtml = headerMap.html();
|
||||
headersMapHtml += buildRowHtml(key, value);
|
||||
refreshHeaderTable(headersMapHtml);
|
||||
}
|
||||
|
||||
function newRowInput(){
|
||||
const hName = $('#headerKeyInput');
|
||||
const hValue = $('#headerValueInput');
|
||||
if(checkIfInputValid(hName.val()) && checkIfInputValid(hValue.val())){
|
||||
addRow(hName.val(), hValue.val());
|
||||
hName.val(null);
|
||||
hValue.val(null);
|
||||
}
|
||||
}
|
||||
|
||||
function checkIfInputValid(input){
|
||||
return !(input == '' || input == null || input == undefined);
|
||||
}
|
||||
|
||||
function checkIfHeaderEssential(key){
|
||||
|
||||
if( key == "Connection" || key == "Keep-Alive" || key == "Date" ){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function buildRowHtml(key, value){
|
||||
|
||||
if(checkIfHeaderEssential(key)){
|
||||
return '' +
|
||||
'<tr>' +
|
||||
'<td><input class="key data-field" value="' + key + '" readonly></td>' +
|
||||
'<td><input class="data-field" value="' + value + '"></td>' +
|
||||
'</tr>';
|
||||
}
|
||||
return '' +
|
||||
'<tr>' +
|
||||
'<td><input class="key data-field" value="' + key + '"></td>' +
|
||||
'<td><input class="data-field" value="' + value + '"></td>' +
|
||||
'<td><button class="modification-button btn-hashmap"><i class="icon-cancel"></i></button></td>' +
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function createRequestBody(){
|
||||
var newJson =
|
||||
{
|
||||
clientUUID: json.clientUUID,
|
||||
contentType: $('#typeSelector').val(),
|
||||
messageBody: $('#bodyEditor').val(),
|
||||
httpStatus: $('#httpStatus').val(),
|
||||
httpHeaders: {},
|
||||
};
|
||||
newJson['httpHeaders'] = convertTableToJson();
|
||||
|
||||
json = newJson;
|
||||
return newJson;
|
||||
}
|
||||
|
||||
|
||||
function convertTableToJson(){
|
||||
const rows = $('#headerMapTable').children();
|
||||
|
||||
var obj = {};
|
||||
var key;
|
||||
for(let i=0; i<rows.length; i++){
|
||||
key = rows.eq(i).children().eq(0).children().eq(0).val();
|
||||
obj[key] = rows.eq(i).children().eq(1).children().eq(0).val();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
const deleteParent = function(){
|
||||
$(this).closest('div.tile').remove();
|
||||
}
|
||||
|
||||
$('#test1').click(deleteParent);
|
||||
@@ -1,49 +0,0 @@
|
||||
var historyJson = {};
|
||||
const maxIterations = 200;
|
||||
|
||||
function getHistoryData(){
|
||||
$.getJSON(host + '/api/event/' + clientUUID, function(data){
|
||||
historyJson = data;
|
||||
displayHistory();
|
||||
});
|
||||
}
|
||||
|
||||
function historyToHtml(){
|
||||
var innerHTML = '';
|
||||
var iterations = historyJson.length <= maxIterations ? historyJson.length : maxIterations;
|
||||
for(let i=0; i<iterations; i++){
|
||||
let style = i%2==0 ? ' class="even"' : '';
|
||||
innerHTML += '<tr' + style + '>' +
|
||||
'<td>' + parseTimeStamp(historyJson[i].dateTimeStamp) + '</td>' +
|
||||
'<td>' + historyJson[i].httpMethod + '</td>' +
|
||||
'<td>' + parseRequestBody(historyJson[i].requestBody, i) + '</td>' +
|
||||
'<td> <button id="'+i+'" class="showHeaderButton" onClick="showHeadersHistory(this);"> Show headers </button> </td>' +
|
||||
'</tr>';
|
||||
}
|
||||
return innerHTML;
|
||||
}
|
||||
|
||||
function parseRequestBody(requestBody,i){
|
||||
return requestBody.length == 0 ?
|
||||
"No request body" :
|
||||
'<button id="'+i+'" class="showRequestBodyButton" onClick="showRequestBody(this);"> Show request body </button>'
|
||||
}
|
||||
|
||||
function parseTimeStamp(timeStamp){
|
||||
return timeStamp.substring(0,19).replace('T',' ');
|
||||
}
|
||||
|
||||
function parseHeaders(pos){
|
||||
parsedJson = new Map();
|
||||
headers = historyJson[pos].headers
|
||||
Object.keys( headers ).forEach(
|
||||
(jsonKey) => {
|
||||
parsedJson.set( jsonKey , headers[jsonKey] );
|
||||
}
|
||||
)
|
||||
return parsedJson;
|
||||
}
|
||||
|
||||
function displayHistory(){
|
||||
$('#historyTable tbody').html(historyToHtml());
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
var modalDisplayed = false;
|
||||
var methodToCall = {
|
||||
name: null,
|
||||
id: null
|
||||
};
|
||||
|
||||
const overlay = $('#overlay');
|
||||
const savedModal = $('#modal-confirm');
|
||||
const dataLossModal = $('#modal-query');
|
||||
const dataLossModalYes = dataLossModal.children().eq(2).children().eq(0);
|
||||
const dataLossModalNo = dataLossModal.children().eq(2).children().eq(1);
|
||||
const allModals = $('.modal');
|
||||
const btnModalClose = $('.modal button');
|
||||
const closeModals = function() {
|
||||
hideModal(allModals);
|
||||
}
|
||||
const savedModalDisplay = function() {
|
||||
|
||||
showModal(savedModal);
|
||||
setTimeout(closeModals, 2000);
|
||||
}
|
||||
const dataLossModalDisplay = function(){
|
||||
showModal(dataLossModal);
|
||||
}
|
||||
|
||||
btnModalClose.click(closeModals);
|
||||
overlay.click(closeModals);
|
||||
dataLossModalNo.click(closeModals);
|
||||
dataLossModalYes.click(dropChangesAndClose);
|
||||
|
||||
function setMethodToCall(name, id){
|
||||
methodToCall.name = name;
|
||||
methodToCall.id = id;
|
||||
}
|
||||
|
||||
const dropChangesAndClose = function(){
|
||||
callMethodByName(methodToCall)
|
||||
hideModal(dataLossModal);
|
||||
}
|
||||
|
||||
function showModal(jmodal){
|
||||
if(modalDisplayed) return;
|
||||
overlay.addClass('active');
|
||||
jmodal.addClass('active');
|
||||
modalDisplayed = true;
|
||||
}
|
||||
|
||||
function hideModal(jmodal){
|
||||
if(!modalDisplayed) return;
|
||||
overlay.removeClass('active');
|
||||
jmodal.removeClass('active');
|
||||
modalDisplayed = false;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
function switchPopups (neededPopupOption) {
|
||||
$('.hiddable-popup-option').addClass('hidden-popup-type');
|
||||
$('#'+neededPopupOption).removeClass('hidden-popup-type');
|
||||
}
|
||||
|
||||
function showPopup(){
|
||||
$('.popup-flex').removeClass('hiddable-container');
|
||||
}
|
||||
|
||||
function hidePopup(){
|
||||
$('.popup-flex').addClass('hiddable-container');
|
||||
$('.hiddable-popup-option').addClass('hidden-popup-type');
|
||||
}
|
||||
|
||||
/*
|
||||
* Event listener that's close the popup when user clicks out of a popup.
|
||||
*/
|
||||
|
||||
window.addEventListener(
|
||||
'click' ,
|
||||
(clickedElement) => {
|
||||
if(!document.getElementById('popup-body').contains(clickedElement.target) && clickedElement.target.className == 'popup-flex' ) {
|
||||
hidePopup();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('.popup-button-close').click(
|
||||
() => {
|
||||
hidePopup();
|
||||
$('.hiddable-popup-option').addClass('hidden-popup-type')
|
||||
}
|
||||
);
|
||||
@@ -1,165 +0,0 @@
|
||||
var advancedVisibility = false;
|
||||
var focusedField = false;
|
||||
/*
|
||||
Listeners
|
||||
*/
|
||||
$("#optional").click(changeAdvancedVisibility);
|
||||
|
||||
$('#historyTab').click(showHistory);
|
||||
|
||||
$('.tooltipped').on("mouseenter" , (event) => {showTip(event.currentTarget.id+'Tip')})
|
||||
.on( "mouseleave", (event) => {hideTip(event.currentTarget.id+'Tip')});
|
||||
|
||||
/*
|
||||
Functions
|
||||
*/
|
||||
|
||||
function changeAdvancedVisibility(){
|
||||
if(advancedVisibility){
|
||||
$("#advanced").removeClass('active');
|
||||
advancedVisibility = false;
|
||||
}
|
||||
else {
|
||||
$('#advanced').addClass('active');
|
||||
advancedVisibility = true;
|
||||
}
|
||||
setCookie();
|
||||
}
|
||||
|
||||
const tabitem = $('.tabitem');
|
||||
function showHistory(){
|
||||
$('#headersTab').click(showHeaders);
|
||||
tabitem.removeClass('active');
|
||||
$('.tabcontent').removeClass('active');
|
||||
$('#history').addClass('active');
|
||||
$('#historyTab').addClass('active');
|
||||
$('#historyTab').off('click');
|
||||
getHistoryData();
|
||||
}
|
||||
|
||||
function showHeaders(){
|
||||
$('#historyTab').click(showHistory);
|
||||
tabitem.removeClass('active');
|
||||
$('.tabcontent').removeClass('active');
|
||||
$('#headers').addClass('active');
|
||||
$('#headersTab').addClass('active');
|
||||
$('#headersTab').off('click');
|
||||
}
|
||||
|
||||
function showHeadersHistory(record){
|
||||
historyTable = '';
|
||||
headers = parseHeaders(record.id)
|
||||
headers.forEach(
|
||||
(value,key) => {
|
||||
historyTable +=
|
||||
'<tr>' +
|
||||
'<td class="history-header-name">'+ key + '</td>' +
|
||||
'<td class="history-header-value">'+ value + '</td>' +
|
||||
'</tr>'
|
||||
}
|
||||
);
|
||||
document.getElementById('header-history-table-body').innerHTML = historyTable;
|
||||
switchPopups('history-headers-table');
|
||||
showPopup();
|
||||
}
|
||||
|
||||
async function formatJSON(json) {
|
||||
const backend = "java";
|
||||
const address = window.location.protocol + "//" + window.location.hostname + "/" + backend + "/json/formatting";
|
||||
|
||||
var init = {
|
||||
body: json,
|
||||
method: "POST"
|
||||
};
|
||||
var request = new Request(address, init);
|
||||
|
||||
var result = await fetch(request).then(response => {
|
||||
return response.text().then(function (text) {
|
||||
var json = JSON.parse(text);
|
||||
json.status = response.status;
|
||||
return json;
|
||||
});
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
async function formatXML(xml) {
|
||||
const backend = "libxml";
|
||||
const address = window.location.protocol + "//" + window.location.hostname + "/" + backend + "/prettify";
|
||||
var data = {
|
||||
data: xml,
|
||||
process: "",
|
||||
processor: "libxml",
|
||||
version: "1.0"
|
||||
}
|
||||
|
||||
var init = {
|
||||
body: JSON.stringify(data),
|
||||
method: "POST"
|
||||
};
|
||||
var request = new Request(address, init);
|
||||
|
||||
var result = await fetch(request).then(response => {
|
||||
return response.text().then(function (text) {
|
||||
return JSON.parse(text);
|
||||
});
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function showRequestBody(element){
|
||||
var historyRequestBody = historyJson[element.id].requestBody;
|
||||
const popupContent = document.getElementById('code-highlight-content')
|
||||
|
||||
document.getElementById('code-highlight-content').innerText = "Loading...";
|
||||
switch(historyJson[element.id].headers["content-type"]){
|
||||
case "application/json":{
|
||||
formatJSON(historyRequestBody).then(function(result) {
|
||||
|
||||
if (result.status == "200") {
|
||||
popupContent.innerText = result.data;
|
||||
highlightSyntax('code-highlight-content');
|
||||
}
|
||||
else {
|
||||
popupContent.innerText = historyRequestBody;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "application/xml": {
|
||||
formatXML(historyRequestBody).then(function(result) {
|
||||
if (result.status == "OK") {
|
||||
popupContent.innerText = result.result;
|
||||
highlightSyntax('code-highlight-content');
|
||||
}
|
||||
else {
|
||||
popupContent.innerText = historyRequestBody;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
popupContent.innerText = historyRequestBody;
|
||||
highlightSyntax('code-highlight-content');
|
||||
}
|
||||
}
|
||||
switchPopups('history-request-body');
|
||||
showPopup();
|
||||
}
|
||||
|
||||
function refreshHistoryRecords(){
|
||||
getHistoryData();
|
||||
}
|
||||
|
||||
function hideTip(element){
|
||||
$('#'+element).removeClass('active');
|
||||
}
|
||||
|
||||
function showTip(element){
|
||||
$('.tip').removeClass('active');
|
||||
$('#'+element).addClass('active');
|
||||
}
|
||||
@@ -1,414 +0,0 @@
|
||||
var defaultStrings = [];
|
||||
const color_grey = "#6b6b6b";
|
||||
const color_red = "#ff8f8f";
|
||||
|
||||
/**
|
||||
* It clears default content of the element and sets it's color to black.
|
||||
*
|
||||
* @function
|
||||
* @name clearDefaultContent
|
||||
* @kind function
|
||||
* @param {any} element to set
|
||||
* @param {any} text to set
|
||||
* @returns {void}
|
||||
*/
|
||||
function clearDefaultContent(element, text) {
|
||||
if (element.innerText == text) {
|
||||
element.innerText = "";
|
||||
element.style.color = "#000000";
|
||||
element.style.backgroundColor = "#ffffff";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the value of the element with id "processors".
|
||||
*
|
||||
* @function
|
||||
* @name getProcessor
|
||||
* @kind function
|
||||
* @returns {any}
|
||||
*/
|
||||
function getProcessor() {
|
||||
return document.getElementById("processors").value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It returns the value of the element with id "versions".
|
||||
*
|
||||
* @function
|
||||
* @name getVersion
|
||||
* @kind function
|
||||
* @returns {any}
|
||||
*/
|
||||
function getVersion() {
|
||||
return document.getElementById("versions").value;
|
||||
}
|
||||
|
||||
/**
|
||||
* It clears all data fields.
|
||||
*
|
||||
* @function
|
||||
* @name clearDataField
|
||||
* @kind function
|
||||
*/
|
||||
function clearDataField() {
|
||||
document.getElementById("xmlArea").innerHTML = "";
|
||||
document.getElementById("xmlArea").style.color = null;
|
||||
document.getElementById("xmlArea").style.backgroundColor = null;
|
||||
|
||||
document.getElementById("transformArea").innerHTML = "";
|
||||
document.getElementById("transformArea").style.color = null;
|
||||
document.getElementById("transformArea").style.backgroundColor = null;
|
||||
|
||||
document.getElementById("resultArea").innerHTML = "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It fills the XML area with a sample XML.
|
||||
*
|
||||
* @function
|
||||
* @name fillDefaultXML
|
||||
* @kind function
|
||||
* @param {any} element
|
||||
* @returns {void}
|
||||
*/
|
||||
function fillDefaultXML(element) {
|
||||
if (element.classList.contains("active")) {
|
||||
const serverAddress = window.location.protocol + "//" + window.location.hostname;
|
||||
clearDefaultContent(document.getElementById("xmlArea"), "Insert XML here");
|
||||
fetch(serverAddress + "/assets/samples/sampleXml.xml")
|
||||
.then(response => response.text())
|
||||
.then((exampleData) => {
|
||||
document.getElementById("xmlArea").innerText = exampleData;
|
||||
highlightSyntax("xmlArea");
|
||||
document.getElementById("xmlArea").style.backgroundColor = null;
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It fills the XSD area with a sample XSD and XML area with matching XML.
|
||||
*
|
||||
* @function
|
||||
* @name fillDefaultXSD
|
||||
* @kind function
|
||||
* @param {any} element
|
||||
* @returns {void}
|
||||
*/
|
||||
function fillDefaultXSD(){
|
||||
const serverAddress = window.location.protocol + "//" + window.location.hostname;
|
||||
fetch(serverAddress + "/assets/samples/sampleXSD.xsd")
|
||||
.then( response => response.text() )
|
||||
.then( (XSDSchema) => {
|
||||
document.getElementById('transformArea').innerText = XSDSchema;
|
||||
highlightSyntax("transformArea");
|
||||
} )
|
||||
fetch(serverAddress + "/assets/samples/sampleXMLForXSD.xml")
|
||||
.then( response => response.text() )
|
||||
.then( (XMLSample) => {
|
||||
document.getElementById('xmlArea').innerText = XMLSample;
|
||||
highlightSyntax("xmlArea");
|
||||
} )
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The `fillDefaultXSLT()` function fetches a default XSLT template from the server and sets the value of the element with id "transformArea" to the fetched template.
|
||||
*
|
||||
* @function
|
||||
* @name fillDefaultXSLT
|
||||
* @kind function
|
||||
* @returns {void}
|
||||
*/
|
||||
function fillDefaultXSLT() {
|
||||
const serverAddress = window.location.protocol + "//" + window.location.hostname;
|
||||
fetch(serverAddress + "/assets/samples/XSLTTemplate.xslt")
|
||||
.then( response => response.text() )
|
||||
.then( (XSTLTemplate) => {
|
||||
document.getElementById('transformArea').innerText = XSTLTemplate;
|
||||
highlightSyntax("transformArea");
|
||||
} )
|
||||
}
|
||||
|
||||
/**
|
||||
* It sets default content for the element an changes it's color to grey
|
||||
*
|
||||
* @function
|
||||
* @name setDefaultContent
|
||||
* @kind function
|
||||
* @param {any} element to set
|
||||
* @param {any} text to set
|
||||
*/
|
||||
function setDefaultContent(element, text) {
|
||||
if (element.value == "") {
|
||||
var id = element.getAttribute('id');
|
||||
if (!defaultStrings.includes(text)) {
|
||||
defaultStrings.push(text);
|
||||
}
|
||||
if (id == "xmlArea") {
|
||||
element.style.color = color_grey;
|
||||
element.value = text;
|
||||
}
|
||||
if (id == "transformArea") {
|
||||
element.style.color = color_grey;
|
||||
element.value = text;
|
||||
}
|
||||
if (id == "jsonArea") {
|
||||
element.style.color = color_grey;
|
||||
element.value = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It hides list for specified version of XPath
|
||||
*
|
||||
* @function
|
||||
* @name hideList
|
||||
* @kind function
|
||||
* @param {any} collList class name of list to hide
|
||||
* @returns {void}
|
||||
*/
|
||||
function hideList(collList) {
|
||||
for (i = 0; i < collList.length; i++) {
|
||||
if (collList[i].nextElementSibling !== null) {
|
||||
collList[i].nextElementSibling.style.maxHeight = null;
|
||||
collList[i].nextElementSibling.classList.toggle("collapsibleDataExpanded", false);
|
||||
}
|
||||
collList[i].style.display = 'none';
|
||||
collList[i].classList.remove("collapsibleActive");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It checks if the text is a default text.
|
||||
*
|
||||
* @function
|
||||
* @name checkDefault
|
||||
* @kind function
|
||||
* @param {any} text
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function checkDefault(text) {
|
||||
return defaultStrings.includes(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* It show list for specified version of XPath
|
||||
*
|
||||
* @function
|
||||
* @name showList
|
||||
* @kind function
|
||||
* @param {any} collList class name of list to hide
|
||||
* @returns {void}
|
||||
*/
|
||||
function showList(collList) {
|
||||
for (i = 0; i < collList.length; i++) {
|
||||
collList[i].style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that is used to fold/unfold collapsible elements.
|
||||
*
|
||||
* @function
|
||||
* @name smoothFoldElement
|
||||
* @kind function
|
||||
* @param {any} element
|
||||
* @param {any} toogleState
|
||||
* @param {any} toggleParrent
|
||||
* @returns {void}
|
||||
*/
|
||||
function smoothFoldElement(element, toogleState, toggleParrent) {
|
||||
if (toogleState) {
|
||||
if (toggleParrent) {
|
||||
element.parentElement.style.maxHeight = "0px";
|
||||
}
|
||||
|
||||
element.classList.toggle("active", false);
|
||||
var subLists = collapsibleData.getElementsByClassName("collapsibleData");
|
||||
for (j = 0; j < subLists.length; j++) {
|
||||
subLists[j].style.maxHeight = null;
|
||||
}
|
||||
} else {
|
||||
collapsibleData.parentElement.style.maxHeight = (collapsibleData.parentElement.scrollHeight) + "px";
|
||||
collapsibleData.classList.toggle("active", true);
|
||||
if (collapsibleData.parentElement.classList.contains("collapsibleData") && collapsibleData.parentElement.classList.contains("active")) {
|
||||
collapsibleData.parentElement.style.maxHeight = (collapsibleData.parentElement.scrollHeight + collapsibleData.scrollHeight) + "px";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set tooltip info, function is called by onClick handlers
|
||||
*
|
||||
* @function
|
||||
* @name refreshTooltip
|
||||
* @kind function
|
||||
* @returns {void}
|
||||
*/
|
||||
function refreshTooltip() {
|
||||
var resizeList = document.getElementsByClassName("collapsibleData");
|
||||
document.getElementById("processorTooltipInfo").innerText = procInfo;
|
||||
document.getElementById("xsltelementsheader").innerText = XSLTheader;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A function that performs a request to the server.
|
||||
*
|
||||
* @function
|
||||
* @name performRequest
|
||||
* @kind function
|
||||
* @param {any} endpoint of target service
|
||||
* @param {any} checkXML enable checking for empty XML
|
||||
* @param {any} checkTransform enable checking for empty transform data
|
||||
* @returns {false | undefined}
|
||||
*/
|
||||
function performRequest(endpoint, checkXML, checkTransform) {
|
||||
const sourceId = "xmlArea";
|
||||
const transformId = "transformArea";
|
||||
var xmlData = document.getElementById(sourceId).innerText.trim();
|
||||
var transformData = document.getElementById(transformId).innerText.trim();
|
||||
|
||||
var backend = "java";
|
||||
if (getProcessor() == "libxml") {
|
||||
backend = "libxml";
|
||||
}
|
||||
|
||||
var empty = false;
|
||||
if (defaultStrings.includes(xmlData) && checkXML) {
|
||||
document.getElementById(sourceId).style.backgroundColor = color_red;
|
||||
xmlData = "";
|
||||
empty = true;
|
||||
}
|
||||
if (defaultStrings.includes(transformData) && checkTransform) {
|
||||
document.getElementById(transformId).style.backgroundColor = color_red;
|
||||
empty = true;
|
||||
}
|
||||
if (!empty) {
|
||||
restRequest(backend, endpoint, xmlData, transformData).then(function (result) {
|
||||
document.getElementById("resultArea").innerText = result.result;
|
||||
highlightSyntax("resultArea");
|
||||
document.getElementById("procinfo").innerText = ' Computed using ' + result.processor;
|
||||
|
||||
|
||||
if (result.status == "OK") {
|
||||
document.getElementById("procinfo").innerText += " (" + result.time + "ms)";
|
||||
if (result.type)
|
||||
document.getElementById("procinfo").innerText += ". Returned: " + result.type;
|
||||
else
|
||||
document.getElementById("procinfo").innerText += ". Engine doesn't support return of data types.";
|
||||
procinfo.style.color = "#30aa58";
|
||||
} else {
|
||||
procinfo.style.color = "#aa3030";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
document.getElementById("resultArea").innerHTML = "No data provided!";
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that prepares data to send and handles response
|
||||
*
|
||||
* @function
|
||||
* @name performFormatRequest
|
||||
* @kind function
|
||||
* @param {any} endpoint of target service
|
||||
* @param {any} checkXML enable checking for empty XML
|
||||
* @param {any} sourceId ID of element to get XML from
|
||||
* @param {any} targetId ID of element to write formatted XML
|
||||
* @returns {void}
|
||||
*/
|
||||
function performFormatRequest(endpoint, checkXML, sourceId, targetId) {
|
||||
const sourceElement = document.getElementById(sourceId);
|
||||
const targetElement = document.getElementById(targetId);
|
||||
const infoElement = document.getElementById("formatinfo");
|
||||
const backend = "libxml";
|
||||
var xmlData = sourceElement.innerText.trim();
|
||||
|
||||
var empty = false;
|
||||
if (defaultStrings.includes(xmlData) && checkXML) {
|
||||
sourceElement.style.backgroundColor = color_red;
|
||||
xmlData = "";
|
||||
empty = true;
|
||||
}
|
||||
|
||||
if (!empty) {
|
||||
restRequest(backend, endpoint, xmlData, "").then(function (result) {
|
||||
if (result.status == "OK") {
|
||||
targetElement.innerText = result.result.trim();
|
||||
highlightSyntax(targetElement.id);
|
||||
|
||||
targetElement.style.backgroundColor = null;
|
||||
infoElement.innerText = ' Computed'.concat(" in ", result.time, "ms.");
|
||||
infoElement.style.color = "#30aa58";
|
||||
|
||||
}
|
||||
else {
|
||||
targetElement.style.backgroundColor = color_red;
|
||||
infoElement.innerText = result.result;
|
||||
infoElement.style.color = "#aa3030";
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form REST request, send and return received data
|
||||
*
|
||||
* @async
|
||||
* @function
|
||||
* @name restRequest
|
||||
* @kind function
|
||||
* @param {any} backend target backend
|
||||
* @param {any} endpoint of target service
|
||||
* @param {any} xmlData XML that will be sent
|
||||
* @param {any} transformData data used to transform given XML
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
async function restRequest(backend, endpoint, xmlData, transformData) {
|
||||
|
||||
const addr = window.location.protocol + "//" + window.location.hostname + "/" + backend + "/" + endpoint;
|
||||
|
||||
if (defaultStrings.includes(xmlData)) {
|
||||
xmlData = "<empty/>";
|
||||
}
|
||||
|
||||
var jsonData = JSON.stringify({
|
||||
"data": xmlData,
|
||||
"process": transformData,
|
||||
"processor": getProcessor(),
|
||||
"version": getVersion()
|
||||
});
|
||||
var init = {
|
||||
headers: new Headers({
|
||||
}),
|
||||
body: jsonData,
|
||||
// body: data,
|
||||
method: "POST"
|
||||
};
|
||||
var request = new Request(addr, init);
|
||||
|
||||
|
||||
var result = await fetch(request).then(response => {
|
||||
return response.text().then(function (text) {
|
||||
return JSON.parse(text);
|
||||
});
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* This function is executed after the page is loaded.
|
||||
*
|
||||
* @function
|
||||
* @name init
|
||||
* @kind function
|
||||
*/
|
||||
function init() {
|
||||
configurePastingInElement("xmlArea");
|
||||
}
|
||||
|
||||
/**
|
||||
* Function returns processor that will be used to transform XML.
|
||||
* This solution allows to use one function for sending request from every tool
|
||||
*
|
||||
* @function
|
||||
* @name getProcessor
|
||||
* @kind function
|
||||
*/
|
||||
function getProcessor() {
|
||||
return "libxml";
|
||||
}
|
||||
|
||||
/**
|
||||
* Function returns version of XML processor that will be used to transform XML.
|
||||
* This solution allows to use one function for sending request from every tool
|
||||
*
|
||||
* @function
|
||||
* @name getVersion
|
||||
* @kind function
|
||||
*/
|
||||
function getVersion() {
|
||||
return "1.0"
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
|
||||
/**
|
||||
* The `processVersionSelector()` function is responsible for updating the display of the web page
|
||||
* based on the selected processor and version.
|
||||
*
|
||||
* @function
|
||||
* @name processVersionSelector
|
||||
* @kind function
|
||||
* @returns {void}
|
||||
*/
|
||||
function processVersionSelector() {
|
||||
var processor = getProcessor();
|
||||
var hideableOptions = document.getElementsByClassName("hideable");
|
||||
for (let i = 0; i < hideableOptions.length; i++) {
|
||||
hideableOptions[i].style = "display: none;";
|
||||
}
|
||||
if (processor == "xalan" || processor == "libxml") {
|
||||
var xalanOptions = document.getElementsByClassName("xalan");
|
||||
for (let i = 0; i < xalanOptions.length; i++) {
|
||||
xalanOptions[i].style = "";
|
||||
}
|
||||
document.getElementById("versions").selectedIndex = 0;
|
||||
}
|
||||
else {
|
||||
var saxonOptions = document.getElementsByClassName("saxon");
|
||||
for (let i = 0; i < saxonOptions.length; i++) {
|
||||
saxonOptions[i].style = "";
|
||||
}
|
||||
document.getElementById("versions").selectedIndex = 3;
|
||||
|
||||
}
|
||||
processTooltip();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The `processTooltip()` function is responsible for updating the display of the tooltip based on the selected version of the processor.
|
||||
* It shows or hides different sections of the tooltip based on the selected version.
|
||||
* It also handles the click event on the form and updates the tooltip accordingly.
|
||||
*
|
||||
* @function
|
||||
* @name processTooltip
|
||||
* @kind function
|
||||
*/
|
||||
function processTooltip() {
|
||||
var filter = "collapse" + getVersion();
|
||||
var collList;
|
||||
|
||||
|
||||
if (filter == "collapse3.0") {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XPath 3.0 functions";
|
||||
hideList(document.getElementsByName("collapse10"));
|
||||
hideList(document.getElementsByName("collapse20"));
|
||||
showList(document.getElementsByName("collapse30"));
|
||||
hideList(document.getElementsByName("collapse31"));
|
||||
|
||||
} else if (filter == "collapse3.1") {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XPath 3.1 functions";
|
||||
hideList(document.getElementsByName("collapse10"));
|
||||
hideList(document.getElementsByName("collapse20"));
|
||||
hideList(document.getElementsByName("collapse30"));
|
||||
showList(document.getElementsByName("collapse31"));
|
||||
} else if (filter == "collapse2.0") {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XPath 2.0 functions";
|
||||
hideList(document.getElementsByName("collapse10"));
|
||||
showList(document.getElementsByName("collapse20"));
|
||||
hideList(document.getElementsByName("collapse30"));
|
||||
hideList(document.getElementsByName("collapse31"));
|
||||
} else {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XPath 1.0 functions";
|
||||
showList(document.getElementsByName("collapse10"));
|
||||
hideList(document.getElementsByName("collapse20"));
|
||||
hideList(document.getElementsByName("collapse30"));
|
||||
hideList(document.getElementsByName("collapse31"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function is executed after the page is loaded.
|
||||
*
|
||||
* @function
|
||||
* @name init
|
||||
* @kind function
|
||||
*/
|
||||
function init() {
|
||||
|
||||
// Make sure that only plain text is pasted
|
||||
configurePastingInElement("xmlArea");
|
||||
configurePastingInElement("transformArea");
|
||||
|
||||
//Handle clicks in whole form and set info in tooltip
|
||||
setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here');
|
||||
setDefaultContent(document.getElementById("transformArea"), 'Insert XPath expression here');
|
||||
|
||||
processVersionSelector();
|
||||
processTooltip();
|
||||
tool.addEventListener('change', event => {
|
||||
//Check if script was called from textarea or selector
|
||||
var targetID = event.target.getAttribute('id');
|
||||
if (targetID == "processors") {
|
||||
processVersionSelector();
|
||||
processTooltip();
|
||||
}
|
||||
else if (targetID == "versions") {
|
||||
processTooltip();
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
tool.addEventListener('click', event => {
|
||||
//Check if script was called from textarea or selector
|
||||
var targetID = event.target.getAttribute('id');
|
||||
if (targetID !== "xmlArea" && targetID !== "transformArea") {
|
||||
return;
|
||||
}
|
||||
processTooltip();
|
||||
|
||||
})
|
||||
tool.addEventListener('change', event => {
|
||||
//Check if script was called from textarea or selector
|
||||
var targetID = event.target.getAttribute('id');
|
||||
if (targetID !== "xmlArea" && targetID !== "transformArea") {
|
||||
return;
|
||||
}
|
||||
processTooltip();
|
||||
})
|
||||
|
||||
var triggerList = document.getElementsByClassName("collapseTrigger");
|
||||
for (i = 0; i < triggerList.length; i++) {
|
||||
|
||||
triggerList[i].addEventListener("click", function () {
|
||||
var collapsible = this.parentElement;
|
||||
if (this.tagName == "A") {
|
||||
var collapsibleData = this.nextElementSibling;
|
||||
} else {
|
||||
var collapsibleData = this.parentElement.nextElementSibling;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (collapsibleData.style.maxHeight > "0px") {
|
||||
collapsibleData.style.maxHeight = "0px";
|
||||
|
||||
this.classList.toggle("active", false);
|
||||
if (!this.classList.contains("collapsibleMini")) {
|
||||
collapsible.classList.toggle("active", false);
|
||||
}
|
||||
|
||||
var subLists1 = collapsibleData.getElementsByClassName("content");
|
||||
var subLists2 = collapsibleData.getElementsByClassName("active");
|
||||
for (j = 0; j < subLists1.length; j++) {
|
||||
subLists1[j].style.maxHeight = "0px";
|
||||
}
|
||||
for (j = 0; j < subLists2.length; j++) {
|
||||
subLists2[j].classList.toggle("active", false);
|
||||
}
|
||||
} else {
|
||||
collapsibleData.style.maxHeight = (collapsibleData.scrollHeight) + "px";
|
||||
|
||||
this.classList.toggle("active", true);
|
||||
if (!this.classList.contains("collapsibleMini")) {
|
||||
collapsible.classList.toggle("active", true);
|
||||
} else {
|
||||
var parentContent = this.closest(".content");
|
||||
parentContent.style.maxHeight = (parentContent.scrollHeight + collapsibleData.scrollHeight) + "px";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* This function is executed after the page is loaded.
|
||||
*
|
||||
* @function
|
||||
* @name init
|
||||
* @kind function
|
||||
*/
|
||||
function init() {
|
||||
// Make sure that only plain text is pasted
|
||||
configurePastingInElement("xmlArea");
|
||||
configurePastingInElement("transformArea");
|
||||
|
||||
//Handle clicks in whole form and set info in tooltip
|
||||
setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here');
|
||||
setDefaultContent(document.getElementById("transformArea"), 'Insert XSD here');
|
||||
|
||||
// refreshTooltip();
|
||||
processTooltip();
|
||||
tool.addEventListener('click', event => {
|
||||
//Check if script was called from textarea or selector
|
||||
var targetID = event.target.getAttribute('id');
|
||||
if (targetID !== "processors" && targetID !== "xmlArea" && targetID !== "transformArea" && targetID !== "versions") {
|
||||
return;
|
||||
}
|
||||
|
||||
processTooltip();
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The `processTooltip()` function is responsible for updating the display of the tooltip based on the selected version of the processor.
|
||||
* It shows or hides different sections of the tooltip based on the selected version.
|
||||
* It also handles the click event on the form and updates the tooltip accordingly.
|
||||
*
|
||||
* @function
|
||||
* @name processTooltip
|
||||
* @kind function
|
||||
*/
|
||||
function processTooltip() {
|
||||
|
||||
if (getProcessor() == "xalan") {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0 functions";
|
||||
document.getElementById("processorTooltipInfo").innerText = "Supports XSLT 1.0";
|
||||
hideList(document.getElementsByName("collapse30"));
|
||||
} else {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0, 2.0 & 3.0 functions";
|
||||
document.getElementById("processorTooltipInfo").innerText = "Supports XSLT up to 3.0";
|
||||
showList(document.getElementsByName("collapse30"));
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/**
|
||||
* The `processTooltip()` function is responsible for updating the display of the tooltip based on the selected version of the processor.
|
||||
* It shows or hides different sections of the tooltip based on the selected version.
|
||||
* It also handles the click event on the form and updates the tooltip accordingly.
|
||||
*
|
||||
* @function
|
||||
* @name processTooltip
|
||||
* @kind function
|
||||
*/
|
||||
function processTooltip() {
|
||||
|
||||
if (getProcessor() == "xalan" || getProcessor() == "libxml") {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0 functions";
|
||||
document.getElementById("processorTooltipInfo").innerText = "Supports XSLT 1.0";
|
||||
hideList(document.getElementsByName("collapse30"));
|
||||
} else {
|
||||
document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0, 2.0 & 3.0 functions";
|
||||
document.getElementById("processorTooltipInfo").innerText = "Supports XSLT up to 3.0";
|
||||
showList(document.getElementsByName("collapse30"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is executed after the page is loaded.
|
||||
*
|
||||
* @function
|
||||
* @name init
|
||||
* @kind function
|
||||
*/
|
||||
function init() {
|
||||
// Make sure that only plain text is pasted
|
||||
configurePastingInElement("xmlArea");
|
||||
configurePastingInElement("transformArea");
|
||||
|
||||
//Handle clicks in whole form and set info in tooltip
|
||||
setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here');
|
||||
setDefaultContent(document.getElementById("transformArea"), 'Insert XSLT here');
|
||||
|
||||
// refreshTooltip();
|
||||
processTooltip();
|
||||
tool.addEventListener('click', event => {
|
||||
//Check if script was called from textarea or selector
|
||||
var targetID = event.target.getAttribute('id');
|
||||
if (targetID !== "processors" && targetID !== "xmlArea" && targetID !== "transformArea" && targetID !== "versions") {
|
||||
return;
|
||||
}
|
||||
|
||||
processTooltip();
|
||||
})
|
||||
|
||||
tool.addEventListener('change', event => {
|
||||
//Check if script was called from textarea or selector
|
||||
var targetID = event.target.getAttribute('id');
|
||||
if (targetID !== "processors") {
|
||||
return;
|
||||
}
|
||||
|
||||
processTooltip();
|
||||
|
||||
})
|
||||
|
||||
var triggerList = document.getElementsByClassName("collapseTrigger");
|
||||
for (i = 0; i < triggerList.length; i++) {
|
||||
|
||||
triggerList[i].addEventListener("click", function () {
|
||||
|
||||
var collapsible = this.parentElement;
|
||||
var collapsibleData = this.nextElementSibling;
|
||||
if (collapsibleData.style.maxHeight > "0px") {
|
||||
collapsibleData.style.maxHeight = "0px";
|
||||
|
||||
this.classList.toggle("active", false);
|
||||
if (!this.classList.contains("collapsibleMini")) {
|
||||
collapsible.classList.toggle("active", false);
|
||||
}
|
||||
|
||||
var subLists1 = collapsibleData.getElementsByClassName("content");
|
||||
var subLists2 = collapsibleData.getElementsByClassName("active");
|
||||
for (j = 0; j < subLists1.length; j++) {
|
||||
subLists1[j].style.maxHeight = "0px";
|
||||
}
|
||||
for (j = 0; j < subLists2.length; j++) {
|
||||
subLists2[j].classList.toggle("active", false);
|
||||
}
|
||||
} else {
|
||||
collapsibleData.style.maxHeight = (collapsibleData.scrollHeight) + "px";
|
||||
|
||||
this.classList.toggle("active", true);
|
||||
if (!this.classList.contains("collapsibleMini")) {
|
||||
collapsible.classList.toggle("active", true);
|
||||
} else {
|
||||
var parentContent = this.closest(".content");
|
||||
parentContent.style.maxHeight = (parentContent.scrollHeight + collapsibleData.scrollHeight) + "px";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
@import url('https://necolas.github.io/normalize.css/8.0.1/normalize.css');
|
||||
@import url('Frontend/css/r11addons.css');
|
||||
@import url('Frontend/css/r11tables.css');
|
||||
@import url('Frontend/css/r11tool.css');
|
||||
@import url('Frontend/css/r11tooltip.css');
|
||||
@import url('Frontend/css/r11modal.css');
|
||||
1
Frontend/env.d.ts
vendored
Normal file
1
Frontend/env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
@@ -1,57 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="assets/css/frame.css">
|
||||
<script src="assets/scripts/common/jquery-3.6.0.slim.min.js"></script>
|
||||
<script src="assets/scripts/frame.js"></script>
|
||||
<link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon">
|
||||
<!-- Meta tags for SEO and SEM -->
|
||||
<title>Release11 Web Tools</title>
|
||||
<meta name=”robots” content="index, nofollow">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description"
|
||||
content="Unleash the power of Release11's suite of intuitive web tools, including XPath, XSLT, XSD, XML Formatter, JSON Formatter, and REST Mocking services, designed to streamline your development experience and elevate your projects.">
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
<div id="header">
|
||||
<div id="leftElements">
|
||||
<div id="logo"><a href="http://release11.com/"><img src="assets/images/logo_czarne.svg" alt="Release11"></a></div>
|
||||
<div id="menu">
|
||||
<a href="#" onclick="changeActiveTools('XML')" class="active">XML</a>
|
||||
<a href="#" onclick="changeActiveTools('JSON')">JSON</a>
|
||||
<a href="#" onclick="changeActiveTools('REST')">REST</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="titlebar"><p>Internet Tools</p></div>
|
||||
</div>
|
||||
<div id="filler"></div>
|
||||
<div id="content">
|
||||
<div id="leftBar">
|
||||
<ul id="toolList">
|
||||
<li class="toolListRow restTool"><a href="#" onclick="changeTool('mock');">REST Mock</a></li>
|
||||
<li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xpath');">XPath</a></li>
|
||||
<li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xslt');">XSLT</a></li>
|
||||
<li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xsd');">XSD</a></li>
|
||||
<li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xmlform');">XML Formatter</a></li>
|
||||
<li class="toolListRow jsonTool"><a href="#" onclick="changeTool('jsonform');">JSON Formatter</a></li>
|
||||
</ul>
|
||||
<div id="copyright">
|
||||
Build: [:VERSION:]<br>
|
||||
Copyright © 2023<br>
|
||||
<a href="http://release11.com/">Release11 Sp. z. o. o.</a><br>
|
||||
<a href="lawful/terms-of-service.html">Terms of use</a><br>
|
||||
<a href="lawful/privacy-policy.html">Privacy statement</a><bR>
|
||||
<div class="separator"></div>
|
||||
<a href="mailto:bugs@release11.com">Found a bug?</a>
|
||||
</div>
|
||||
</div>
|
||||
<iframe id="iframe" name="iframe" frameborder="0"></iframe>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Release11 Tools</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
input="$(date +'%Y-%m-%d %H:%M')"
|
||||
|
||||
sed -i "s/\[\:VERSION\:\]/$input/g" /usr/share/nginx/html/index.html
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="/assets/css/lawful.css">
|
||||
|
||||
<link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<div id="logo"><a href="http://release11.com/"><img src="/assets/images/logo_czarne.svg" alt="Release11"></a></div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1>Lorem ipsum</h1>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nullam ac tortor vitae purus. Felis imperdiet proin fermentum leo. Donec adipiscing tristique risus nec feugiat in fermentum. Etiam dignissim diam quis enim lobortis. Amet dictum sit amet justo donec. Leo integer malesuada nunc vel risus commodo. Scelerisque purus semper eget duis at tellus. In ornare quam viverra orci sagittis. Ultrices tincidunt arcu non sodales neque sodales.</p>
|
||||
|
||||
<h2>Congue nisi vitae</h2>
|
||||
<p>Congue nisi vitae suscipit tellus mauris a diam. Ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget egestas. Scelerisque eu ultrices vitae auctor eu augue. Sit amet mauris commodo quis imperdiet massa tincidunt nunc pulvinar. Et magnis dis parturient montes nascetur. Imperdiet dui accumsan sit amet nulla facilisi morbi tempus. Quisque non tellus orci ac auctor. Tempor orci eu lobortis elementum nibh tellus molestie nunc. Purus in massa tempor nec feugiat nisl. Ultrices eros in cursus turpis. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam sit amet nisl suscipit adipiscing bibendum est ultricies. Egestas quis ipsum suspendisse ultrices gravida dictum fusce ut placerat. Et molestie ac feugiat sed. Ut tortor pretium viverra suspendisse potenti. Malesuada bibendum arcu vitae elementum curabitur vitae nunc.</p>
|
||||
|
||||
<p>Interdum posuere lorem ipsum dolor sit amet. Amet porttitor eget dolor morbi non. Nulla pellentesque dignissim enim sit amet. Volutpat lacus laoreet non curabitur. Lectus quam id leo in vitae turpis massa. Facilisis sed odio morbi quis commodo odio aenean. Posuere lorem ipsum dolor sit. Tempor commodo ullamcorper a lacus. Metus vulputate eu scelerisque felis imperdiet proin fermentum leo. Aliquam sem fringilla ut morbi tincidunt augue interdum. Tellus mauris a diam maecenas sed enim ut sem. Placerat in egestas erat imperdiet sed euismod nisi porta lorem. Pellentesque id nibh tortor id aliquet lectus proin. A cras semper auctor neque vitae. Non curabitur gravida arcu ac. Netus et malesuada fames ac turpis. Nulla porttitor massa id neque aliquam. Aliquam nulla facilisi cras fermentum odio eu. Cras ornare arcu dui vivamus arcu felis bibendum ut. Non enim praesent elementum facilisis leo.</p>
|
||||
|
||||
<p>Lectus arcu bibendum at varius. Vestibulum lectus mauris ultrices eros in cursus turpis massa tincidunt. Libero nunc consequat interdum varius sit amet mattis vulputate enim. Facilisis leo vel fringilla est. Eros in cursus turpis massa tincidunt dui ut ornare. In mollis nunc sed id semper risus. Morbi tincidunt ornare massa eget egestas purus. Libero volutpat sed cras ornare. Sit amet commodo nulla facilisi nullam vehicula ipsum a. Viverra suspendisse potenti nullam ac tortor. Cursus vitae congue mauris rhoncus aenean vel elit scelerisque mauris. Vitae semper quis lectus nulla. Nunc sed blandit libero volutpat sed cras. Morbi tristique senectus et netus et malesuada fames. Pretium quam vulputate dignissim suspendisse in. A iaculis at erat pellentesque adipiscing commodo elit at imperdiet.</p>
|
||||
|
||||
<p>Nec sagittis aliquam malesuada bibendum. In ante metus dictum at tempor commodo ullamcorper. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Diam phasellus vestibulum lorem sed risus. Diam maecenas ultricies mi eget mauris pharetra et ultrices neque. Amet volutpat consequat mauris nunc congue nisi vitae suscipit tellus. Quam nulla porttitor massa id neque. Dictum non consectetur a erat nam. At consectetur lorem donec massa sapien faucibus. Sagittis nisl rhoncus mattis rhoncus urna neque viverra justo nec. Non enim praesent elementum facilisis leo vel. Rhoncus urna neque viverra justo nec ultrices dui sapien eget.</p>
|
||||
|
||||
<h2>Amet facilisis</h2>
|
||||
<p>Amet facilisis magna etiam tempor. Vestibulum rhoncus est pellentesque elit. Fames ac turpis egestas integer eget. Dapibus ultrices in iaculis nunc. Sed turpis tincidunt id aliquet risus feugiat in. Et netus et malesuada fames ac. Amet massa vitae tortor condimentum lacinia. Felis eget nunc lobortis mattis aliquam faucibus purus. Nibh sed pulvinar proin gravida hendrerit lectus. Varius morbi enim nunc faucibus a pellentesque sit. Aliquam sem fringilla ut morbi. Sed nisi lacus sed viverra tellus in hac. Quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Enim blandit volutpat maecenas volutpat blandit aliquam etiam. Fermentum iaculis eu non diam phasellus vestibulum lorem sed risus. Massa id neque aliquam vestibulum morbi. Enim diam vulputate ut pharetra. Orci sagittis eu volutpat odio facilisis.</p>
|
||||
|
||||
<p>Sit amet cursus sit amet. Odio ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Amet est placerat in egestas erat imperdiet sed euismod nisi. Mattis vulputate enim nulla aliquet porttitor. At risus viverra adipiscing at in tellus integer. Sed viverra ipsum nunc aliquet. Dignissim cras tincidunt lobortis feugiat vivamus at augue eget arcu. Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis. Placerat in egestas erat imperdiet sed. Eleifend donec pretium vulputate sapien nec. Ipsum dolor sit amet consectetur adipiscing.</p>
|
||||
|
||||
<p>Morbi tristique senectus et netus et malesuada fames ac. Feugiat nibh sed pulvinar proin gravida hendrerit lectus. Amet purus gravida quis blandit turpis cursus in hac. Nulla aliquet enim tortor at auctor. Nulla facilisi etiam dignissim diam. Consequat nisl vel pretium lectus quam id leo. Enim neque volutpat ac tincidunt vitae semper. Tristique nulla aliquet enim tortor at. Eu mi bibendum neque egestas congue quisque egestas diam. Est ante in nibh mauris cursus. Felis bibendum ut tristique et. Tristique nulla aliquet enim tortor at. Non curabitur gravida arcu ac tortor dignissim convallis aenean. Eleifend donec pretium vulputate sapien nec. Massa tempor nec feugiat nisl pretium fusce id. Nulla facilisi morbi tempus iaculis urna id. Ornare suspendisse sed nisi lacus sed viverra tellus in.</p>
|
||||
|
||||
<p>Morbi non arcu risus quis varius quam. Rhoncus est pellentesque elit ullamcorper dignissim cras. Gravida rutrum quisque non tellus orci ac auctor augue. Consequat semper viverra nam libero justo laoreet sit amet. Pellentesque habitant morbi tristique senectus et netus et malesuada. Ullamcorper eget nulla facilisi etiam dignissim diam quis enim. Quisque sagittis purus sit amet volutpat consequat mauris nunc congue. Sed tempus urna et pharetra pharetra massa massa ultricies mi. Quis lectus nulla at volutpat diam ut venenatis. Amet porttitor eget dolor morbi non arcu. Massa tincidunt dui ut ornare lectus sit amet est placerat. Odio tempor orci dapibus ultrices in iaculis nunc sed augue. Vitae turpis massa sed elementum tempus egestas sed. Velit egestas dui id ornare arcu odio. Scelerisque felis imperdiet proin fermentum leo vel orci porta non. Arcu bibendum at varius vel pharetra. Sapien eget mi proin sed libero enim. Tempus imperdiet nulla malesuada pellentesque elit eget. Semper auctor neque vitae tempus. Dolor magna eget est lorem ipsum.</p>
|
||||
|
||||
<p>Augue neque gravida in fermentum et sollicitudin ac orci phasellus. Est placerat in egestas erat imperdiet sed euismod nisi. Aliquet risus feugiat in ante metus dictum at tempor commodo. Ultricies integer quis auctor elit sed vulputate. Aliquet risus feugiat in ante metus dictum. Accumsan lacus vel facilisis volutpat est velit. Augue mauris augue neque gravida in fermentum et sollicitudin. Vel quam elementum pulvinar etiam. Amet aliquam id diam maecenas ultricies mi. Elit pellentesque habitant morbi tristique senectus et. Habitant morbi tristique senectus et netus et malesuada fames. Nisl nisi scelerisque eu ultrices. Morbi tristique senectus et netus. Et malesuada fames ac turpis egestas. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus. Dis parturient montes nascetur ridiculus.</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="/assets/css/lawful.css">
|
||||
|
||||
<link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<div id="logo"><a href="http://release11.com/"><img src="/assets/images/logo_czarne.svg" alt="Release11"></a></div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1>Lorem ipsum</h1>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nullam ac tortor vitae purus. Felis imperdiet proin fermentum leo. Donec adipiscing tristique risus nec feugiat in fermentum. Etiam dignissim diam quis enim lobortis. Amet dictum sit amet justo donec. Leo integer malesuada nunc vel risus commodo. Scelerisque purus semper eget duis at tellus. In ornare quam viverra orci sagittis. Ultrices tincidunt arcu non sodales neque sodales.</p>
|
||||
|
||||
<h2>Congue nisi vitae</h2>
|
||||
<p>Congue nisi vitae suscipit tellus mauris a diam. Ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget egestas. Scelerisque eu ultrices vitae auctor eu augue. Sit amet mauris commodo quis imperdiet massa tincidunt nunc pulvinar. Et magnis dis parturient montes nascetur. Imperdiet dui accumsan sit amet nulla facilisi morbi tempus. Quisque non tellus orci ac auctor. Tempor orci eu lobortis elementum nibh tellus molestie nunc. Purus in massa tempor nec feugiat nisl. Ultrices eros in cursus turpis. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam sit amet nisl suscipit adipiscing bibendum est ultricies. Egestas quis ipsum suspendisse ultrices gravida dictum fusce ut placerat. Et molestie ac feugiat sed. Ut tortor pretium viverra suspendisse potenti. Malesuada bibendum arcu vitae elementum curabitur vitae nunc.</p>
|
||||
|
||||
<p>Interdum posuere lorem ipsum dolor sit amet. Amet porttitor eget dolor morbi non. Nulla pellentesque dignissim enim sit amet. Volutpat lacus laoreet non curabitur. Lectus quam id leo in vitae turpis massa. Facilisis sed odio morbi quis commodo odio aenean. Posuere lorem ipsum dolor sit. Tempor commodo ullamcorper a lacus. Metus vulputate eu scelerisque felis imperdiet proin fermentum leo. Aliquam sem fringilla ut morbi tincidunt augue interdum. Tellus mauris a diam maecenas sed enim ut sem. Placerat in egestas erat imperdiet sed euismod nisi porta lorem. Pellentesque id nibh tortor id aliquet lectus proin. A cras semper auctor neque vitae. Non curabitur gravida arcu ac. Netus et malesuada fames ac turpis. Nulla porttitor massa id neque aliquam. Aliquam nulla facilisi cras fermentum odio eu. Cras ornare arcu dui vivamus arcu felis bibendum ut. Non enim praesent elementum facilisis leo.</p>
|
||||
|
||||
<p>Lectus arcu bibendum at varius. Vestibulum lectus mauris ultrices eros in cursus turpis massa tincidunt. Libero nunc consequat interdum varius sit amet mattis vulputate enim. Facilisis leo vel fringilla est. Eros in cursus turpis massa tincidunt dui ut ornare. In mollis nunc sed id semper risus. Morbi tincidunt ornare massa eget egestas purus. Libero volutpat sed cras ornare. Sit amet commodo nulla facilisi nullam vehicula ipsum a. Viverra suspendisse potenti nullam ac tortor. Cursus vitae congue mauris rhoncus aenean vel elit scelerisque mauris. Vitae semper quis lectus nulla. Nunc sed blandit libero volutpat sed cras. Morbi tristique senectus et netus et malesuada fames. Pretium quam vulputate dignissim suspendisse in. A iaculis at erat pellentesque adipiscing commodo elit at imperdiet.</p>
|
||||
|
||||
<p>Nec sagittis aliquam malesuada bibendum. In ante metus dictum at tempor commodo ullamcorper. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Diam phasellus vestibulum lorem sed risus. Diam maecenas ultricies mi eget mauris pharetra et ultrices neque. Amet volutpat consequat mauris nunc congue nisi vitae suscipit tellus. Quam nulla porttitor massa id neque. Dictum non consectetur a erat nam. At consectetur lorem donec massa sapien faucibus. Sagittis nisl rhoncus mattis rhoncus urna neque viverra justo nec. Non enim praesent elementum facilisis leo vel. Rhoncus urna neque viverra justo nec ultrices dui sapien eget.</p>
|
||||
|
||||
<h2>Amet facilisis</h2>
|
||||
<p>Amet facilisis magna etiam tempor. Vestibulum rhoncus est pellentesque elit. Fames ac turpis egestas integer eget. Dapibus ultrices in iaculis nunc. Sed turpis tincidunt id aliquet risus feugiat in. Et netus et malesuada fames ac. Amet massa vitae tortor condimentum lacinia. Felis eget nunc lobortis mattis aliquam faucibus purus. Nibh sed pulvinar proin gravida hendrerit lectus. Varius morbi enim nunc faucibus a pellentesque sit. Aliquam sem fringilla ut morbi. Sed nisi lacus sed viverra tellus in hac. Quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Enim blandit volutpat maecenas volutpat blandit aliquam etiam. Fermentum iaculis eu non diam phasellus vestibulum lorem sed risus. Massa id neque aliquam vestibulum morbi. Enim diam vulputate ut pharetra. Orci sagittis eu volutpat odio facilisis.</p>
|
||||
|
||||
<p>Sit amet cursus sit amet. Odio ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Amet est placerat in egestas erat imperdiet sed euismod nisi. Mattis vulputate enim nulla aliquet porttitor. At risus viverra adipiscing at in tellus integer. Sed viverra ipsum nunc aliquet. Dignissim cras tincidunt lobortis feugiat vivamus at augue eget arcu. Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis. Placerat in egestas erat imperdiet sed. Eleifend donec pretium vulputate sapien nec. Ipsum dolor sit amet consectetur adipiscing.</p>
|
||||
|
||||
<p>Morbi tristique senectus et netus et malesuada fames ac. Feugiat nibh sed pulvinar proin gravida hendrerit lectus. Amet purus gravida quis blandit turpis cursus in hac. Nulla aliquet enim tortor at auctor. Nulla facilisi etiam dignissim diam. Consequat nisl vel pretium lectus quam id leo. Enim neque volutpat ac tincidunt vitae semper. Tristique nulla aliquet enim tortor at. Eu mi bibendum neque egestas congue quisque egestas diam. Est ante in nibh mauris cursus. Felis bibendum ut tristique et. Tristique nulla aliquet enim tortor at. Non curabitur gravida arcu ac tortor dignissim convallis aenean. Eleifend donec pretium vulputate sapien nec. Massa tempor nec feugiat nisl pretium fusce id. Nulla facilisi morbi tempus iaculis urna id. Ornare suspendisse sed nisi lacus sed viverra tellus in.</p>
|
||||
|
||||
<p>Morbi non arcu risus quis varius quam. Rhoncus est pellentesque elit ullamcorper dignissim cras. Gravida rutrum quisque non tellus orci ac auctor augue. Consequat semper viverra nam libero justo laoreet sit amet. Pellentesque habitant morbi tristique senectus et netus et malesuada. Ullamcorper eget nulla facilisi etiam dignissim diam quis enim. Quisque sagittis purus sit amet volutpat consequat mauris nunc congue. Sed tempus urna et pharetra pharetra massa massa ultricies mi. Quis lectus nulla at volutpat diam ut venenatis. Amet porttitor eget dolor morbi non arcu. Massa tincidunt dui ut ornare lectus sit amet est placerat. Odio tempor orci dapibus ultrices in iaculis nunc sed augue. Vitae turpis massa sed elementum tempus egestas sed. Velit egestas dui id ornare arcu odio. Scelerisque felis imperdiet proin fermentum leo vel orci porta non. Arcu bibendum at varius vel pharetra. Sapien eget mi proin sed libero enim. Tempus imperdiet nulla malesuada pellentesque elit eget. Semper auctor neque vitae tempus. Dolor magna eget est lorem ipsum.</p>
|
||||
|
||||
<p>Augue neque gravida in fermentum et sollicitudin ac orci phasellus. Est placerat in egestas erat imperdiet sed euismod nisi. Aliquet risus feugiat in ante metus dictum at tempor commodo. Ultricies integer quis auctor elit sed vulputate. Aliquet risus feugiat in ante metus dictum. Accumsan lacus vel facilisis volutpat est velit. Augue mauris augue neque gravida in fermentum et sollicitudin. Vel quam elementum pulvinar etiam. Amet aliquam id diam maecenas ultricies mi. Elit pellentesque habitant morbi tristique senectus et. Habitant morbi tristique senectus et netus et malesuada fames. Nisl nisi scelerisque eu ultrices. Morbi tristique senectus et netus. Et malesuada fames ac turpis egestas. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus. Dis parturient montes nascetur ridiculus.</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -8,6 +8,7 @@ server {
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
expires -1;
|
||||
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
|
||||
}
|
||||
@@ -17,6 +18,11 @@ server {
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location /api/mock {
|
||||
proxy_pass http://xmltools-mocked-services:8097/api/mock;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location /libxml/ {
|
||||
proxy_pass http://xmltools-libxml-backend/;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
8072
Frontend/package-lock.json
generated
Normal file
8072
Frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
44
Frontend/package.json
Normal file
44
Frontend/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "new-frontend",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "run-p type-check build-only",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.4.5",
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"@codemirror/lang-xml": "^6.0.2",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"codemirror": "^6.0.1",
|
||||
"thememirror": "^2.0.1",
|
||||
"vue": "^3.3.4",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"vue-router": "^4.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.2.0",
|
||||
"@tsconfig/node18": "^2.0.1",
|
||||
"@types/node": "^18.16.17",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vue/eslint-config-prettier": "^7.1.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.3",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-plugin-vue": "^9.11.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.24",
|
||||
"prettier": "^2.8.8",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "~5.0.4",
|
||||
"vite": "^4.3.9",
|
||||
"vue-tsc": "^1.6.5"
|
||||
}
|
||||
}
|
||||
7
Frontend/postcss.config.js
Normal file
7
Frontend/postcss.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
/* eslint-disable no-undef */
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
57
Frontend/src/App.vue
Normal file
57
Frontend/src/App.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<script setup lang="ts">
|
||||
import { RouterView } from 'vue-router';
|
||||
import SidebarComponent from '@components/sidebar/SidebarComponent.vue';
|
||||
import {onMounted, provide, ref } from 'vue';
|
||||
|
||||
const theme = ref( getTheme() );
|
||||
provide('theme', theme );
|
||||
|
||||
onMounted( ()=> {
|
||||
if (localStorage.theme)
|
||||
selectThemeFromLocalStorage();
|
||||
else if (browserPrefersDarkMode()) {
|
||||
setDarkTheme();
|
||||
}
|
||||
})
|
||||
|
||||
function setDarkTheme() {
|
||||
document.documentElement.classList.add('dark');
|
||||
theme.value = "dark";
|
||||
localStorage.setItem("theme", "dark");
|
||||
}
|
||||
|
||||
function selectThemeFromLocalStorage() {
|
||||
if (localStorage.theme == "dark")
|
||||
document.documentElement.classList.add('dark');
|
||||
else
|
||||
document.documentElement.classList.remove('dark');
|
||||
|
||||
theme.value = localStorage.theme;
|
||||
}
|
||||
|
||||
function browserPrefersDarkMode(){
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
function setTheme(newTheme : string){
|
||||
theme.value = newTheme;
|
||||
}
|
||||
|
||||
function getTheme(){
|
||||
return localStorage.theme;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="layout" class="font-sans flex h-screen bg-gradient-to-br from-sky-200 to-indigo-200 dark:from-sky-950 dark:to-indigo-950">
|
||||
<SidebarComponent @theme:changed="setTheme" />
|
||||
<div class="relative p-4 w-full m-4 ml-0 bg-blue-50 dark:bg-gray-700 rounded-2xl overflow-hidden shadow-lg">
|
||||
<RouterView></RouterView>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user