Rebased ref, commits from common ancestor: commit 172cdcafc6c0306740c544dd0841786cd6c55133 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Thu Mar 19 15:54:28 2020 +0000 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Thu Mar 19 15:54:28 2020 +0000
Proxy protocol bits. For now very silly: hex length\r\n + content. Change-Id: I256b834a23cca975a705da2c569887665ac6be02 diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index dd84960d1..cb5bf54e3 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -258,7 +258,7 @@ public: const Poco::URI& uriPublic, const bool isReadOnly, const std::string& hostNoTrust, - const std::shared_ptr<Socket> &moveSocket); + const std::shared_ptr<StreamSocket> &socket); /// Thread safe termination of this broker if it has a lingering thread void joinThread(); diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 683197879..69bf3357e 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2855,7 +2855,7 @@ private: { docBroker->handleProxyRequest( sessionId, id, uriPublic, isReadOnly, - hostNoTrust, moveSocket); + hostNoTrust, streamSocket); return; } catch (const UnauthorizedRequestException& exc) diff --git a/wsd/ProxyProtocol.cpp b/wsd/ProxyProtocol.cpp index 41043a57a..0f875ff72 100644 --- a/wsd/ProxyProtocol.cpp +++ b/wsd/ProxyProtocol.cpp @@ -25,7 +25,7 @@ void DocumentBroker::handleProxyRequest( const Poco::URI& uriPublic, const bool isReadOnly, const std::string& hostNoTrust, - const std::shared_ptr<Socket> &socket) + const std::shared_ptr<StreamSocket> &socket) { std::shared_ptr<ClientSession> clientSession; if (sessionId == "fetchsession") @@ -37,6 +37,22 @@ void DocumentBroker::handleProxyRequest( addSession(clientSession); LOOLWSD::checkDiskSpaceAndWarnClients(true); LOOLWSD::checkSessionLimitsAndWarnClients(); + + LOG_TRC("Returning id " << clientSession->getId()); + + std::ostringstream oss; + oss << "HTTP/1.1 200 OK\r\n" + "Last-Modified: " << Util::getHttpTimeNow() << "\r\n" + "User-Agent: " WOPI_AGENT_STRING "\r\n" + "Content-Length: " << clientSession->getId().size() << "\r\n" + "Content-Type: application/json\r\n" + "X-Content-Type-Options: nosniff\r\n" + "\r\n" + << clientSession->getId(); + + socket->send(oss.str()); + socket->shutdown(); + return; } else { @@ -78,4 +94,60 @@ void ProxyProtocolHandler::handleRequest(const std::string &uriPublic, (void)socket; } +int ProxyProtocolHandler::sendTextMessage(const char *msg, const size_t len, bool flush) const +{ + LOG_TRC("ProxyHack - send text msg " + std::string(msg, len)); + + // FIXME: need some sort of framing [!] + _outQueue.insert(_outQueue.end(), msg, msg + len); + auto sock = popWriteSocket(); + if (sock && flush) + flushQueueTo(sock); + return len; +} + +int ProxyProtocolHandler::sendBinaryMessage(const char *data, const size_t len, bool flush) const +{ + LOG_TRC("ProxyHack - send binary msg len " << len); + _outQueue.insert(_outQueue.end(), data, data + len); + auto sock = popWriteSocket(); + if (sock && flush) + flushQueueTo(sock); + return len; +} + +void ProxyProtocolHandler::shutdown(bool goingAway = false, const std::string &statusMessage = "") +{ + LOG_TRC("ProxyHack - shutdown " << goingAway << ": " << statusMessage); +} + +void ProxyProtocolHandler::getIOStats(uint64_t &sent, uint64_t &recv) +{ + sent = recv = 0; +} + +void ProxyProtocolHandler::dumpState(std::ostream& os) +{ + os << "proxy protocol\n"; +} + +void ProxyProtocolHandler::flushQueueTo(const std::shared_ptr<StreamSocket> &socket) +{ +} + +// LRU-ness ... +std::shared_ptr<StreamSocket> ProxyProtocolHandler::popWriteSocket() +{ + std::weak_ptr<StreamSocket> sock; + while (!_writeSockets.empty()) + { + sock = _writeSockets.front(); + _writeSockets.erase(_writeSockets.begin()); + auto realSock = sock.lock(); + if (realSock) + return realSock; + } + return std::shared_ptr<StreamSocket>(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/ProxyProtocol.hpp b/wsd/ProxyProtocol.hpp index 1f88e1fa7..9278b7536 100644 --- a/wsd/ProxyProtocol.hpp +++ b/wsd/ProxyProtocol.hpp @@ -30,9 +30,9 @@ public: } /// Called after successful socket reads. - void handleIncomingMessage(SocketDisposition &/* disposition */) override + void handleIncomingMessage(SocketDisposition &/* disposition */) override; { - assert("we get our data a different way" && false); + assert("we get our data a different way - in incoming requests" && false); } int getPollEvents(std::chrono::steady_clock::time_point /* now */, @@ -59,40 +59,22 @@ public: /// Clear all external references virtual void dispose() { _msgHandler.reset(); } - int sendTextMessage(const char *msg, const size_t len, bool flush = false) const override - { - LOG_TRC("ProxyHack - send text msg " + std::string(msg, len)); - (void) flush; - return len; - } - - int sendBinaryMessage(const char *data, const size_t len, bool flush = false) const override - { - (void) data; (void) flush; - LOG_TRC("ProxyHack - send binary msg len " << len); - return len; - } - - void shutdown(bool goingAway = false, const std::string &statusMessage = "") override - { - LOG_TRC("ProxyHack - shutdown " << goingAway << ": " << statusMessage); - } - - void getIOStats(uint64_t &sent, uint64_t &recv) override - { - sent = recv = 0; - } - - void dumpState(std::ostream& os) - { - os << "proxy protocol\n"; - } + int sendTextMessage(const char *msg, const size_t len, bool flush = false) const override; + int sendBinaryMessage(const char *data, const size_t len, bool flush = false) const override; + void shutdown(bool goingAway = false, const std::string &statusMessage = "") override; + void getIOStats(uint64_t &sent, uint64_t &recv) override; + void dumpState(std::ostream& os); void handleRequest(const std::string &uriPublic, const std::shared_ptr<Socket> &socket); private: - std::vector<std::weak_ptr<StreamSocket>> _sockets; + std::shared_ptr<StreamSocket> popWriteSocket(); + void flushQueueTo(const std::shared_ptr<StreamSocket> &socket); + + std::vector<std::weak_ptr<StreamSocket>> _writeSockets; + /// queue things when we have no socket to hand. + std::vector<char> _outQueue; }; #endif commit 5e20f38ff40eb66c157f9493334dcc859d9e5449 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Wed Mar 4 13:54:04 2020 +0000 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Thu Mar 19 15:20:59 2020 +0000 Proxy websocket prototype. Try to read/write avoiding a websocket. Change-Id: I382039fa88f1030a63df1e47f687df2ee5a6055b diff --git a/Makefile.am b/Makefile.am index e4e6ed5db..92d87fa50 100644 --- a/Makefile.am +++ b/Makefile.am @@ -112,6 +112,7 @@ loolwsd_sources = common/Crypto.cpp \ wsd/AdminModel.cpp \ wsd/Auth.cpp \ wsd/DocumentBroker.cpp \ + wsd/ProxyProtocol.cpp \ wsd/LOOLWSD.cpp \ wsd/ClientSession.cpp \ wsd/FileServer.cpp \ @@ -203,6 +204,7 @@ wsd_headers = wsd/Admin.hpp \ wsd/Auth.hpp \ wsd/ClientSession.hpp \ wsd/DocumentBroker.hpp \ + wsd/ProxyProtocol.hpp \ wsd/Exceptions.hpp \ wsd/FileServer.hpp \ wsd/LOOLWSD.hpp \ diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js index a08c4cf3b..74e982873 100644 --- a/loleaflet/js/global.js +++ b/loleaflet/js/global.js @@ -166,16 +166,97 @@ }; this.onopen = function() { }; + this.close = function() { + }; }; - - global.FakeWebSocket.prototype.close = function() { - }; - global.FakeWebSocket.prototype.send = function(data) { this.sendCounter++; window.postMobileMessage(data); }; + global.proxySocketCounter = 0; + global.ProxySocket = function (uri) { + this.uri = uri; + this.binaryType = 'arraybuffer'; + this.bufferedAmount = 0; + this.extensions = ''; + this.protocol = ''; + this.connected = true; + this.readyState = 0; // connecting + this.sessionId = 'fetchsession'; + this.id = window.proxySocketCounter++; + this.sendCounter = 0; + this.readWaiting = false; + this.onclose = function() { + }; + this.onerror = function() { + }; + this.onmessage = function() { + }; + this.send = function(msg) { + console.debug('send msg "' + msg + '"'); + var req = new XMLHttpRequest(); + req.open('POST', this.getEndPoint('write')); + req.setRequestHeader('SessionId', this.sessionId); + if (this.sessionId === 'fetchsession') + req.addEventListener('load', function() { + console.debug('got session: ' + this.responseText); + that.sessionId = this.responseText; + that.readyState = 1; + that.onopen(); + }); + req.send(msg); + }, + this.close = function() { + console.debug('close socket'); + this.readyState = 3; + this.onclose(); + }; + this.getEndPoint = function(type) { + var base = this.uri; + return base.replace(/^ws/, 'http') + '/' + type; + }; + console.debug('New proxy socket ' + this.id + ' ' + this.uri); + + // FIXME: perhaps a little risky. + this.send('fetchsession'); + var that = this; + + // horrors ... + this.readInterval = setInterval(function() { + if (this.readWaiting) // one at a time for now + return; + if (this.sessionId == 'fetchsession') + return; // waiting for our session id. + var req = new XMLHttpRequest(); + // fetch session id: + req.addEventListener('load', function() { + console.debug('read: ' + this.responseText); + if (this.status == 200) + { + that.onmessage({ data: this.response }); + } + else + { + console.debug('Handle error ' + this.status); + } + that.readWaiting = false; + }); + req.open('GET', that.getEndPoint('read')); + req.setRequestHeader('SessionId', this.sessionId); + req.send(that.sessionId); + that.readWaiting = true; + }, 250); + }; + + global.createWebSocket = function(uri) { + if (global.socketProxy) { + return new global.ProxySocket(uri); + } else { + return new WebSocket(uri); + } + }; + // If not debug, don't print anything on the console // except in tile debug mode (Ctrl-Shift-Alt-d) console.log2 = console.log; @@ -200,7 +281,8 @@ window.postMobileError(log); } else if (global.socket && (global.socket instanceof WebSocket) && global.socket.readyState === 1) { global.socket.send(log); - } else if (global.socket && (global.socket instanceof global.L.Socket) && global.socket.connected()) { + } else if (global.socket && global.L && global.L.Socket && + (global.socket instanceof global.L.Socket) && global.socket.connected()) { global.socket.sendMessage(log); } else { var req = new XMLHttpRequest(); @@ -275,7 +357,7 @@ var websocketURI = global.host + global.serviceRoot + '/lool/' + encodeURIComponent(global.docURL + (docParams ? '?' + docParams : '')) + '/ws' + wopiSrc; try { - global.socket = new WebSocket(websocketURI); + global.socket = global.createWebSocket(websocketURI); } catch (err) { console.log(err); } diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index b4118479f..f4a44fd06 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -49,7 +49,7 @@ L.Socket = L.Class.extend({ } try { - this.socket = new WebSocket(this.getWebSocketBaseURI(map) + wopiSrc); + this.socket = window.createWebSocket(this.getWebSocketBaseURI(map) + wopiSrc); } catch (e) { // On IE 11 there is a limitation on the number of WebSockets open to a single domain (6 by default and can go to 128). // Detect this and hint the user. diff --git a/net/Socket.hpp b/net/Socket.hpp index a6395b9b4..2290dadd9 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -446,6 +446,11 @@ public: } } + std::shared_ptr<ProtocolHandlerInterface> getProtocol() const + { + return _protocol; + } + /// Do we have something to send ? virtual bool hasQueuedMessages() const = 0; /// Please send them to me then. diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp index b47285dd0..e347dbd74 100644 --- a/wsd/ClientSession.hpp +++ b/wsd/ClientSession.hpp @@ -37,9 +37,6 @@ public: void construct(); virtual ~ClientSession(); - /// Lookup any session by id. - static std::shared_ptr<ClientSession> getById(const std::string &id); - void setReadOnly() override; enum SessionState { @@ -288,7 +285,6 @@ private: std::chrono::steady_clock::time_point _viewLoadStart; }; - #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 68369d274..dd84960d1 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -251,6 +251,15 @@ public: const bool isReadOnly, const std::string& hostNoTrust); + /// Find or create a new client session for the PHP proxy + void handleProxyRequest( + const std::string& sessionId, + const std::string& id, + const Poco::URI& uriPublic, + const bool isReadOnly, + const std::string& hostNoTrust, + const std::shared_ptr<Socket> &moveSocket); + /// Thread safe termination of this broker if it has a lingering thread void joinThread(); diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 177360dbc..683197879 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -238,6 +238,9 @@ namespace #if ENABLE_SUPPORT_KEY inline void shutdownLimitReached(const std::shared_ptr<ProtocolHandlerInterface>& proto) { + if (!proto) + return; + const std::string error = Poco::format(PAYLOAD_UNAVAILABLE_LIMIT_REACHED, LOOLWSD::MaxDocuments, LOOLWSD::MaxConnections); LOG_INF("Sending client 'hardlimitreached' message: " << error); @@ -1764,9 +1767,12 @@ static std::shared_ptr<DocumentBroker> if (docBroker->isMarkedToDestroy()) { LOG_WRN("DocBroker with docKey [" << docKey << "] that is marked to be destroyed. Rejecting client request."); - std::string msg("error: cmd=load kind=docunloading"); - proto->sendTextMessage(msg.data(), msg.size()); - proto->shutdown(true, "error: cmd=load kind=docunloading"); + if (proto) + { + std::string msg("error: cmd=load kind=docunloading"); + proto->sendTextMessage(msg.data(), msg.size()); + proto->shutdown(true, "error: cmd=load kind=docunloading"); + } return nullptr; } } @@ -1782,9 +1788,12 @@ static std::shared_ptr<DocumentBroker> } // Indicate to the client that we're connecting to the docbroker. - const std::string statusConnect = "statusindicator: connect"; - LOG_TRC("Sending to Client [" << statusConnect << "]."); - proto->sendTextMessage(statusConnect.data(), statusConnect.size()); + if (proto) + { + const std::string statusConnect = "statusindicator: connect"; + LOG_TRC("Sending to Client [" << statusConnect << "]."); + proto->sendTextMessage(statusConnect.data(), statusConnect.size()); + } if (!docBroker) { @@ -2242,6 +2251,13 @@ private: // Util::dumpHex(std::cerr, "clipboard:\n", "", socket->getInBuffer()); // lots of data ... handleClipboardRequest(request, message, disposition); } + else if (request.has("ProxyPrefix") && reqPathTokens.count() > 2 && + (reqPathTokens[reqPathTokens.count()-2] == "ws")) + { + std::string decodedUri; // WOPISrc + Poco::URI::decode(reqPathTokens[1], decodedUri); + handleClientProxyRequest(request, decodedUri, message, disposition); + } else if (!(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) && reqPathTokens.count() > 0 && reqPathTokens[0] == "lool") { @@ -2775,6 +2791,99 @@ private: } #endif + void handleClientProxyRequest(const Poco::Net::HTTPRequest& request, + std::string url, + Poco::MemoryInputStream& message, + SocketDisposition &disposition) + { + if (!request.has("SessionId")) + throw BadRequestException("No session id header on proxied request"); + + std::string sessionId = request.get("SessionId"); + + LOG_INF("URL [" << url << "]."); + const auto uriPublic = DocumentBroker::sanitizeURI(url); + LOG_INF("URI [" << uriPublic.getPath() << "]."); + const auto docKey = DocumentBroker::getDocKey(uriPublic); + LOG_INF("DocKey [" << docKey << "]."); + const std::string fileId = Util::getFilenameFromURL(docKey); + Util::mapAnonymized(fileId, fileId); // Identity mapping, since fileId is already obfuscated + + LOG_INF("Starting Proxy request handler for session [" << _id << "] on url [" << LOOLWSD::anonymizeUrl(url) << "]."); + + // Check if readonly session is required + bool isReadOnly = false; + for (const auto& param : uriPublic.getQueryParameters()) + { + LOG_DBG("Query param: " << param.first << ", value: " << param.second); + if (param.first == "permission" && param.second == "readonly") + { + isReadOnly = true; + } + } + + const std::string hostNoTrust = (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName); + + LOG_INF("URL [" << LOOLWSD::anonymizeUrl(url) << "] is " << (isReadOnly ? "readonly" : "writable") << "."); + (void)request; (void)message; (void)disposition; + + std::shared_ptr<ProtocolHandlerInterface> none; + // Request a kit process for this doc. + std::shared_ptr<DocumentBroker> docBroker = findOrCreateDocBroker( + none, url, docKey, _id, uriPublic); + if (docBroker) + { + // need to move into the DocumentBroker context before doing session lookup / creation etc. + std::string id = _id; + disposition.setMove([docBroker, id, uriPublic, isReadOnly, hostNoTrust, sessionId] + (const std::shared_ptr<Socket> &moveSocket) + { + LOG_TRC("Setting up docbroker thread for " << docBroker->getDocKey()); + // Make sure the thread is running before adding callback. + docBroker->startThread(); + + // We no longer own this socket. + moveSocket->setThreadOwner(std::thread::id()); + + docBroker->addCallback([docBroker, id, uriPublic, isReadOnly, hostNoTrust, sessionId, moveSocket]() + { + // Now inside the document broker thread ... + LOG_TRC("In the docbroker thread for " << docBroker->getDocKey()); + + auto streamSocket = std::static_pointer_cast<StreamSocket>(moveSocket); + try + { + docBroker->handleProxyRequest( + sessionId, id, uriPublic, isReadOnly, + hostNoTrust, moveSocket); + return; + } + catch (const UnauthorizedRequestException& exc) + { + LOG_ERR("Unauthorized Request while loading session for " << docBroker->getDocKey() << ": " << exc.what()); + } + catch (const StorageConnectionException& exc) + { + LOG_ERR("Error while loading : " << exc.what()); + } + catch (const std::exception& exc) + { + LOG_ERR("Error while loading : " << exc.what()); + } + // badness occured: + std::ostringstream oss; + oss << "HTTP/1.1 400\r\n" + << "Date: " << Util::getHttpTimeNow() << "\r\n" + << "User-Agent: LOOLWSD WOPI Agent\r\n" + << "Content-Length: 0\r\n" + << "\r\n"; + streamSocket->send(oss.str()); + streamSocket->shutdown(); + }); + }); + } + } + void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request, const std::string& url, SocketDisposition &disposition) { @@ -2837,7 +2946,7 @@ private: // Request a kit process for this doc. std::shared_ptr<DocumentBroker> docBroker = findOrCreateDocBroker( std::static_pointer_cast<ProtocolHandlerInterface>(ws), url, docKey, _id, uriPublic); - if (docBroker) + if (docBroker) { #if MOBILEAPP const std::string hostNoTrust; diff --git a/wsd/ProxyProtocol.cpp b/wsd/ProxyProtocol.cpp new file mode 100644 index 000000000..41043a57a --- /dev/null +++ b/wsd/ProxyProtocol.cpp @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <config.h> + +#include "DocumentBroker.hpp" +#include "ClientSession.hpp" +#include "ProxyProtocol.hpp" +#include "Exceptions.hpp" +#include "LOOLWSD.hpp" +#include <Socket.hpp> + +#include <atomic> +#include <cassert> + +void DocumentBroker::handleProxyRequest( + const std::string& sessionId, + const std::string& id, + const Poco::URI& uriPublic, + const bool isReadOnly, + const std::string& hostNoTrust, + const std::shared_ptr<Socket> &socket) +{ + std::shared_ptr<ClientSession> clientSession; + if (sessionId == "fetchsession") + { + LOG_TRC("Create session for " << _docKey); + clientSession = createNewClientSession( + std::make_shared<ProxyProtocolHandler>(), + id, uriPublic, isReadOnly, hostNoTrust); + addSession(clientSession); + LOOLWSD::checkDiskSpaceAndWarnClients(true); + LOOLWSD::checkSessionLimitsAndWarnClients(); + } + else + { + LOG_TRC("Find session for " << _docKey << " with id " << sessionId); + for (const auto &it : _sessions) + { + if (it.second->getId() == sessionId) + { + clientSession = it.second; + break; + } + } + if (!clientSession) + { + LOG_ERR("Invalid session id used " << sessionId); + throw BadRequestException("invalid session id"); + } + } + + auto protocol = clientSession->getProtocol(); + auto streamSocket = std::static_pointer_cast<StreamSocket>(socket); + streamSocket->setHandler(protocol); + + // this DocumentBroker's poll handles reading & writing + addSocketToPoll(socket); + + auto proxy = std::static_pointer_cast<ProxyProtocolHandler>( + protocol); + + proxy->handleRequest(uriPublic.toString(), socket); +} + +void ProxyProtocolHandler::handleRequest(const std::string &uriPublic, + const std::shared_ptr<Socket> &socket) +{ + bool bRead = uriPublic.find("/write") == std::string::npos; + LOG_INF("Proxy handle request " << uriPublic << " type: " << + (bRead ? "read" : "write")); + (void)socket; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/ProxyProtocol.hpp b/wsd/ProxyProtocol.hpp new file mode 100644 index 000000000..1f88e1fa7 --- /dev/null +++ b/wsd/ProxyProtocol.hpp @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_PROXY_PROTOCOL_HPP +#define INCLUDED_PROXY_PROTOCOL_HPP + +#include <net/Socket.hpp> + +/// Interface for building a websocket from this ... +class ProxyProtocolHandler : public ProtocolHandlerInterface +{ +public: + ProxyProtocolHandler() + { + } + + virtual ~ProxyProtocolHandler() + { + } + + /// Will be called exactly once by setHandler + void onConnect(const std::shared_ptr<StreamSocket>& /* socket */) override + { + } + + /// Called after successful socket reads. + void handleIncomingMessage(SocketDisposition &/* disposition */) override + { + assert("we get our data a different way" && false); + } + + int getPollEvents(std::chrono::steady_clock::time_point /* now */, + int &/* timeoutMaxMs */) override + { + // underlying buffer based polling is fine. + return POLLIN; + } + + void checkTimeout(std::chrono::steady_clock::time_point /* now */) override + { + } + + void performWrites() override + { + } + + void onDisconnect() override + { + // connections & sockets come and go a lot. + } + +public: + /// Clear all external references + virtual void dispose() { _msgHandler.reset(); } + + int sendTextMessage(const char *msg, const size_t len, bool flush = false) const override + { + LOG_TRC("ProxyHack - send text msg " + std::string(msg, len)); + (void) flush; + return len; + } + + int sendBinaryMessage(const char *data, const size_t len, bool flush = false) const override + { + (void) data; (void) flush; + LOG_TRC("ProxyHack - send binary msg len " << len); + return len; + } + + void shutdown(bool goingAway = false, const std::string &statusMessage = "") override + { + LOG_TRC("ProxyHack - shutdown " << goingAway << ": " << statusMessage); + } + + void getIOStats(uint64_t &sent, uint64_t &recv) override + { + sent = recv = 0; + } + + void dumpState(std::ostream& os) + { + os << "proxy protocol\n"; + } + + void handleRequest(const std::string &uriPublic, + const std::shared_ptr<Socket> &socket); + +private: + std::vector<std::weak_ptr<StreamSocket>> _sockets; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 406d3c609574918eaa5fd6f50726008d9e2d1073 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Wed Mar 4 13:52:51 2020 +0000 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Thu Mar 19 14:25:13 2020 +0000 ProxyPrefix: allow the user to specify a custom prefix. This allows us to re-direct web traffic via a proxy quite simply during fetch, instead of changing the service root. Change-Id: I28d348467e48394d581fca4da4c199348a2ca8e0 diff --git a/loleaflet/html/loleaflet.html.m4 b/loleaflet/html/loleaflet.html.m4 index 84fd50b15..86e54249f 100644 --- a/loleaflet/html/loleaflet.html.m4 +++ b/loleaflet/html/loleaflet.html.m4 @@ -235,6 +235,7 @@ m4_ifelse(MOBILEAPP,[true], window.reuseCookies = ''; window.protocolDebug = false; window.frameAncestors = ''; + window.socketProxy = false; window.tileSize = 256;], [window.host = '%HOST%'; window.serviceRoot = '%SERVICE_ROOT%'; @@ -247,6 +248,7 @@ m4_ifelse(MOBILEAPP,[true], window.reuseCookies = '%REUSE_COOKIES%'; window.protocolDebug = %PROTOCOL_DEBUG%; window.frameAncestors = '%FRAME_ANCESTORS%'; + window.socketProxy = %SOCKET_PROXY%; window.tileSize = 256;]) m4_syscmd([cat ]GLOBAL_JS)m4_dnl </script> diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index ce9e12756..2b53999c8 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -595,6 +595,17 @@ constexpr char BRANDING[] = "branding"; constexpr char BRANDING_UNSUPPORTED[] = "branding-unsupported"; #endif +namespace { + // The user can override the ServerRoot with a new prefix. + std::string getResponseRoot(const HTTPRequest &request) + { + if (!request.has("ProxyPrefix")) + return LOOLWSD::ServiceRoot; + std::string proxyPrefix = request.get("ProxyPrefix", ""); + return proxyPrefix; + } +} + void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket) { @@ -641,15 +652,21 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: } } - const auto& config = Application::instance().config(); + std::string socketProxy = "false"; + if (request.has("ProxyPrefix")) + socketProxy = "true"; + Poco::replaceInPlace(preprocess, std::string("%SOCKET_PROXY%"), socketProxy); + + std::string responseRoot = getResponseRoot(request); Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN%"), escapedAccessToken); Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN_TTL%"), std::to_string(tokenTtl)); Poco::replaceInPlace(preprocess, std::string("%ACCESS_HEADER%"), escapedAccessHeader); Poco::replaceInPlace(preprocess, std::string("%HOST%"), host); Poco::replaceInPlace(preprocess, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH)); - Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), LOOLWSD::ServiceRoot); + Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), responseRoot); + const auto& config = Application::instance().config(); std::string protocolDebug = "false"; if (config.getBool("logging.protocol")) protocolDebug = "true"; @@ -658,16 +675,16 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: static const std::string linkCSS("<link rel=\"stylesheet\" href=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.css\">"); static const std::string scriptJS("<script src=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.js\"></script>"); - std::string brandCSS(Poco::format(linkCSS, LOOLWSD::ServiceRoot, std::string(BRANDING))); - std::string brandJS(Poco::format(scriptJS, LOOLWSD::ServiceRoot, std::string(BRANDING))); + std::string brandCSS(Poco::format(linkCSS, responseRoot, std::string(BRANDING))); + std::string brandJS(Poco::format(scriptJS, responseRoot, std::string(BRANDING))); #if ENABLE_SUPPORT_KEY const std::string keyString = config.getString("support_key", ""); SupportKey key(keyString); if (!key.verify() || key.validDaysRemaining() <= 0) { - brandCSS = Poco::format(linkCSS, LOOLWSD::ServiceRoot, std::string(BRANDING_UNSUPPORTED)); - brandJS = Poco::format(scriptJS, LOOLWSD::ServiceRoot, std::string(BRANDING_UNSUPPORTED)); + brandCSS = Poco::format(linkCSS, responseRoot, std::string(BRANDING_UNSUPPORTED)); + brandJS = Poco::format(scriptJS, responseRoot, std::string(BRANDING_UNSUPPORTED)); } #endif @@ -850,13 +867,15 @@ void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,co if (!FileServerRequestHandler::isAdminLoggedIn(request, response)) throw Poco::Net::NotAuthenticatedException("Invalid admin login"); + std::string responseRoot = getResponseRoot(request); + static const std::string scriptJS("<script src=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.js\"></script>"); static const std::string footerPage("<div class=\"footer navbar-fixed-bottom text-info text-center\"><strong>Key:</strong> %s <strong>Expiry Date:</strong> %s</div>"); const std::string relPath = getRequestPathname(request); LOG_DBG("Preprocessing file: " << relPath); std::string adminFile = *getUncompressedFile(relPath); - std::string brandJS(Poco::format(scriptJS, LOOLWSD::ServiceRoot, std::string(BRANDING))); + std::string brandJS(Poco::format(scriptJS, responseRoot, std::string(BRANDING))); std::string brandFooter; #if ENABLE_SUPPORT_KEY @@ -874,7 +893,7 @@ void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,co Poco::replaceInPlace(adminFile, std::string("<!--%BRANDING_JS%-->"), brandJS); Poco::replaceInPlace(adminFile, std::string("<!--%FOOTER%-->"), brandFooter); Poco::replaceInPlace(adminFile, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH)); - Poco::replaceInPlace(adminFile, std::string("%SERVICE_ROOT%"), LOOLWSD::ServiceRoot); + Poco::replaceInPlace(adminFile, std::string("%SERVICE_ROOT%"), responseRoot); // Ask UAs to block if they detect any XSS attempt response.add("X-XSS-Protection", "1; mode=block"); commit d19e85f9482054f8589aedee88df0f04aa76476d Author: Henry Castro <hcas...@collabora.com> AuthorDate: Thu Mar 19 09:51:05 2020 -0400 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Thu Mar 19 15:01:11 2020 +0100 loleaflet: check the cell cursor width to scroll This is an improvement of the commit 569b342c2029876b1c9ef8b54f235138bff9c792, It is better to check the cell cursor width instead of spacing to scroll the view when very large merge cell occurs Change-Id: I049cda34f886738ce9fbd3776113a219c5bd038f Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90751 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index a398ff1bc..61a5b688b 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -2864,12 +2864,13 @@ L.TileLayer = L.GridLayer.extend({ } else if (horizontalDirection !== 0 || verticalDirection != 0) { var mapX = Math.abs(mapBounds.getEast() - mapBounds.getWest()); - var spacingX = Math.abs(this._cellCursor.getEast() - this._cellCursor.getWest()) / 4.0; + var cursorX = Math.abs(this._cellCursor.getEast() - this._cellCursor.getWest()); + var spacingX = cursorX / 4.0; var spacingY = Math.abs((this._cellCursor.getSouth() - this._cellCursor.getNorth())) / 4.0; if (this._cellCursor.getWest() < mapBounds.getWest()) { scrollX = this._cellCursor.getWest() - mapBounds.getWest() - spacingX; - } else if (spacingX < mapX && this._cellCursor.getEast() > mapBounds.getEast()) { + } else if (cursorX < mapX && this._cellCursor.getEast() > mapBounds.getEast()) { scrollX = this._cellCursor.getEast() - mapBounds.getEast() + spacingX; } if (this._cellCursor.getNorth() > mapBounds.getNorth()) { commit b659e8613cb491e3e621d2eac7614d3fb4b691b9 Author: Pedro Pinto Silva <pedro.si...@collabora.com> AuthorDate: Thu Mar 19 14:00:45 2020 +0100 Commit: Pedro Pinto da Silva <pedro.si...@collabora.com> CommitDate: Thu Mar 19 14:50:13 2020 +0100 MobileWizard: fix table design options and chart options by updating css rules according to the latest html structure Change-Id: I373e185a444e8f5db3096cd05c9f47f470ef73c3 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90747 Tested-by: Pedro Pinto da Silva <pedro.si...@collabora.com> Reviewed-by: Pedro Pinto da Silva <pedro.si...@collabora.com> diff --git a/loleaflet/css/mobilewizard.css b/loleaflet/css/mobilewizard.css index 99695142b..bb6addd51 100644 --- a/loleaflet/css/mobilewizard.css +++ b/loleaflet/css/mobilewizard.css @@ -614,10 +614,20 @@ float:left; } #MergeCells > span{ - display: none; + color: #4d82b8; + text-align: end; + vertical-align: bottom; + } + #DeleteTable{ + background-color: #fbf4f5; + border-radius: 6px; + padding-right: 4% !important; } #DeleteTable > span{ - display: none; + font-weight: bold; + color: #e68497; + text-align: end; + vertical-align: bottom; } .colorcontainer { width: 120px; @@ -728,7 +738,7 @@ vertical-align: baseline; padding-left: 24px; } - div[title='Table Design'] div[id^=Use]{ + #SdTableDesignPanel div[id^=Use]{ width: 92%; padding-right: 4% !important; } commit 3b1ca68a212329111938189bc3df90a5c8996c57 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Mar 18 13:18:59 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 14:48:42 2020 +0100 cypress: mobile: add spellchecking tests for impress. Change-Id: I7b3909c79ca1fad27c5e3754a36f38f659e467e1 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90712 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am index 603ec9269..394627af7 100644 --- a/cypress_test/Makefile.am +++ b/cypress_test/Makefile.am @@ -36,6 +36,7 @@ MOBILE_TEST_FILES= \ calc/insertion_wizard_spec.js \ calc/spellchecking_spec.js \ impress/impress_focus_spec.js \ + impress/spellchecking_spec.js \ writer/apply_font_spec.js \ writer/apply_paragraph_properties_spec.js \ writer/bottom_toolbar_spec.js \ diff --git a/cypress_test/data/mobile/impress/spellchecking.odp b/cypress_test/data/mobile/impress/spellchecking.odp new file mode 100644 index 000000000..af6096b7d Binary files /dev/null and b/cypress_test/data/mobile/impress/spellchecking.odp differ diff --git a/cypress_test/integration_tests/common/helper.js b/cypress_test/integration_tests/common/helper.js index dea956fa5..02a4cbdda 100644 --- a/cypress_test/integration_tests/common/helper.js +++ b/cypress_test/integration_tests/common/helper.js @@ -92,8 +92,9 @@ function assertCursorAndFocus() { } // Select all text via CTRL+A shortcut. -function selectAllText() { - assertCursorAndFocus(); +function selectAllText(assertFocus = true) { + if (assertFocus) + assertCursorAndFocus(); cy.log('Select all text'); diff --git a/cypress_test/integration_tests/common/impress.js b/cypress_test/integration_tests/common/impress.js index 6e1e59c55..00064c096 100644 --- a/cypress_test/integration_tests/common/impress.js +++ b/cypress_test/integration_tests/common/impress.js @@ -1,4 +1,4 @@ -/* global cy require */ +/* global cy require expect*/ var helper = require('./helper'); @@ -61,6 +61,39 @@ function typeTextAndVerify(text, expected) { helper.expectTextForClipboard(expected); } +function copyShapeContentToClipboard() { + // TODO: this fails on assertHaveKeyboardInput() + // assertInTextEditMode(); + + helper.selectAllText(false); + + // Open context menu + cy.get('.leaflet-marker-icon') + .then(function(marker) { + expect(marker).to.have.lengthOf(2); + var XPos = (marker[0].getBoundingClientRect().right + marker[1].getBoundingClientRect().left) / 2; + var YPos = marker[0].getBoundingClientRect().top - 5; + helper.longPressOnDocument(XPos, YPos); + }); + + cy.get('#mobile-wizard') + .should('be.visible'); + + // Execute copy + cy.get('.ui-header.level-0.mobile-wizard.ui-widget .context-menu-link .menu-entry-with-icon', {timeout : 10000}) + .contains('Copy') + .click(); + + // Close warning about clipboard operations + cy.get('.vex-dialog-button-primary.vex-dialog-button.vex-first') + .click(); + + // Wait until it's closed + cy.get('.vex-overlay') + .should('not.exist'); +} + module.exports.assertNotInTextEditMode = assertNotInTextEditMode; module.exports.assertInTextEditMode = assertInTextEditMode; module.exports.typeTextAndVerify = typeTextAndVerify; +module.exports.copyShapeContentToClipboard = copyShapeContentToClipboard; diff --git a/cypress_test/integration_tests/mobile/impress/spellchecking_spec.js b/cypress_test/integration_tests/mobile/impress/spellchecking_spec.js new file mode 100644 index 000000000..8831e3555 --- /dev/null +++ b/cypress_test/integration_tests/mobile/impress/spellchecking_spec.js @@ -0,0 +1,118 @@ +/* global describe it cy beforeEach require afterEach expect*/ + +var helper = require('../../common/helper'); +var impress = require('../../common/impress'); + +describe('Spell checking menu.', function() { + beforeEach(function() { + helper.beforeAllMobile('spellchecking.odp', 'impress'); + + // Click on edit button + helper.enableEditingMobile(); + }); + + afterEach(function() { + helper.afterAll('spellchecking.odp'); + }); + + function openContextMenu() { + // Click on the center of the slide to step into text edit mode + cy.get('#document-container') + .then(function(items) { + expect(items).to.have.length(1); + var XPos = (items[0].getBoundingClientRect().left + items[0].getBoundingClientRect().right) / 2; + var YPos = (items[0].getBoundingClientRect().top + items[0].getBoundingClientRect().bottom) / 2; + cy.get('body') + .dblclick(XPos, YPos); + }); + + cy.get('.leaflet-cursor.blinking-cursor') + .should('exist'); + + helper.selectAllText(false); + + // Open context menu + cy.get('.leaflet-marker-icon') + .then(function(markers) { + expect(markers.length).to.have.greaterThan(1); + for (var i = 0; i < markers.length; i++) { + if (markers[i].classList.contains('leaflet-selection-marker-start')) { + var startPos = markers[i].getBoundingClientRect(); + } else if (markers[i].classList.contains('leaflet-selection-marker-end')) { + var endPos = markers[i].getBoundingClientRect(); + } + } + + // Remove selection + cy.get('#document-container') + .type('{leftarrow}'); + cy.get('.leaflet-marker-icon') + .should('not.exist'); + + var XPos = startPos.right + 10; + var YPos = endPos.top - 10; + helper.longPressOnDocument(XPos, YPos); + }); + + cy.get('#mobile-wizard-content') + .should('be.visible'); + } + + it('Apply suggestion.', function() { + openContextMenu(); + + cy.get('.context-menu-link') + .contains('hello') + .click(); + + impress.copyShapeContentToClipboard(); + + cy.get('#copy-paste-container pre') + .then(function(item) { + expect(item).to.have.lengthOf(1); + expect(item[0].innerText).to.have.string('hello'); + }); + }); + + it('Ignore all.', function() { + openContextMenu(); + + cy.get('.context-menu-link') + .contains('Ignore All') + .click(); + + openContextMenu(); + + // We don't get the spell check context menu any more + cy.get('.context-menu-link') + .contains('Paste'); + }); + + it('Apply language for word.', function() { + openContextMenu(); + + cy.get('.context-menu-link') + .contains('Word is Finnish') + .click(); + + openContextMenu(); + + // We don't get the spell check context menu any more + cy.get('.context-menu-link') + .contains('Paste'); + }); + + it('Apply language for paragraph.', function() { + openContextMenu(); + + cy.get('.context-menu-link') + .contains('Paragraph is Finnish') + .click(); + + openContextMenu(); + + // We don't get the spell check context menu any more + cy.get('.context-menu-link') + .contains('Paste'); + }); +}); commit ff92eb07952d07f000d7738c5990d0ac5718ea45 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Thu Mar 19 02:31:52 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 13:47:55 2020 +0100 cypress: better core version detection. To make it work both with release and debug core build. Also disable some tests failing with core/cp-6-2. Change-Id: I5617712e19dc8aaba0c5f9fbdf9c17d9a19fb18b Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90725 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/cypress_test/integration_tests/common/helper.js b/cypress_test/integration_tests/common/helper.js index 5d3c017d9..dea956fa5 100644 --- a/cypress_test/integration_tests/common/helper.js +++ b/cypress_test/integration_tests/common/helper.js @@ -177,7 +177,8 @@ function detectLOCoreVersion() { cy.get('#lokit-version') .then(function(items) { expect(items).have.lengthOf(1); - if (items[0].textContent.includes('Collabora OfficeDev 6.2')) { + if (items[0].textContent.includes('Collabora') && + items[0].textContent.includes('6.2')) { Cypress.env('LO_CORE_VERSION', 'cp-6-2');} else { Cypress.env('LO_CORE_VERSION', 'master'); diff --git a/cypress_test/integration_tests/mobile/impress/impress_focus_spec.js b/cypress_test/integration_tests/mobile/impress/impress_focus_spec.js index a33bede16..fdd33c569 100644 --- a/cypress_test/integration_tests/mobile/impress/impress_focus_spec.js +++ b/cypress_test/integration_tests/mobile/impress/impress_focus_spec.js @@ -80,7 +80,7 @@ describe('Impress focus tests', function() { impress.typeTextAndVerify('Bazinga Impress'); }); - it('Single-click to edit', function() { + it.skip('Single-click to edit', function() { helper.enableEditingMobile(); diff --git a/cypress_test/integration_tests/mobile/writer/apply_font_spec.js b/cypress_test/integration_tests/mobile/writer/apply_font_spec.js index 08e51940c..c6f3b4e23 100644 --- a/cypress_test/integration_tests/mobile/writer/apply_font_spec.js +++ b/cypress_test/integration_tests/mobile/writer/apply_font_spec.js @@ -204,7 +204,7 @@ describe('Apply font changes.', function() { // TODO: Shadowed is not in the clipboard content. }); - it('Apply grow.', function() { + it.skip('Apply grow.', function() { // Push grow cy.get('#Growimg') .click(); diff --git a/cypress_test/integration_tests/mobile/writer/shape_properties_spec.js b/cypress_test/integration_tests/mobile/writer/shape_properties_spec.js index 2fcf6f6cf..1bce30aac 100644 --- a/cypress_test/integration_tests/mobile/writer/shape_properties_spec.js +++ b/cypress_test/integration_tests/mobile/writer/shape_properties_spec.js @@ -98,7 +98,7 @@ describe('Change shape properties via mobile wizard.', function() { .should('have.attr', 'fill', 'rgb(114,159,207)'); }); - it('Change shape width.', function() { + it.skip('Change shape width.', function() { // TODO: Entering a value inside the spinbutton has no effect on the shape. if (Cypress.env('LO_CORE_VERSION') === 'master') return; commit b76352d8e35fe97f2433de83f563d7a967e2408c Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Thu Mar 19 11:23:18 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 12:37:23 2020 +0100 mobile: add a method to generate ID for submenus. Change-Id: I45c2865573eb6b9d070fc6c36f4f1369e2ac3172 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90739 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/loleaflet/src/control/Control.JSDialogBuilder.js b/loleaflet/src/control/Control.JSDialogBuilder.js index f0171fb41..e6c8f5eeb 100644 --- a/loleaflet/src/control/Control.JSDialogBuilder.js +++ b/loleaflet/src/control/Control.JSDialogBuilder.js @@ -1658,6 +1658,11 @@ L.Control.JSDialogBuilder = L.Control.extend({ } }); +L.Control.JSDialogBuilder.generateIDForSubMenu = function(menuStructure) { + if (menuStructure['text'] === 'Anchor') + menuStructure['id'] = 'submenu_anchor'; +}; + L.Control.JSDialogBuilder.getMenuStructureForMobileWizard = function(menu, mainMenu, itemCommand) { if (itemCommand.includes('sep')) return null; @@ -1706,6 +1711,7 @@ L.Control.JSDialogBuilder.getMenuStructureForMobileWizard = function(menu, mainM element = this.getMenuStructureForMobileWizard(menu.items[menuItem], false, menuItem); if (element) menuStructure['children'].push(element); + this.generateIDForSubMenu(menuStructure); } } commit 45886322e72cfce1ba21641cf9211497240e37b8 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Mar 18 19:26:40 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 12:32:52 2020 +0100 cypress: mobile: move focus related tests to focus_spec.js. Change-Id: Ib8719f6d14e578ffc0125077942c063f4b5f3f37 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90718 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/cypress_test/integration_tests/mobile/writer/bottom_toolbar_spec.js b/cypress_test/integration_tests/mobile/writer/bottom_toolbar_spec.js index fd23fd030..a0c484eba 100644 --- a/cypress_test/integration_tests/mobile/writer/bottom_toolbar_spec.js +++ b/cypress_test/integration_tests/mobile/writer/bottom_toolbar_spec.js @@ -34,30 +34,6 @@ describe('Pushing bottom toolbar items.', function() { .should('exist'); }); - it('Apply bold, check keyboard.', function() { - cy.get('#document-container') - .type('{downarrow}'); - helper.selectAllText(); - - cy.get('#tb_editbar_item_bold div table') - .should('not.have.class', 'checked'); - - cy.window().then(win => { - win.lastInputState = win.map._textInput.shouldAcceptInput(); - }); - - cy.get('#tb_editbar_item_bold') - .click(); - - cy.get('#tb_editbar_item_bold div table') - .should('have.class', 'checked'); - - cy.window().then(win => { - var acceptInput = win.map._textInput.shouldAcceptInput(); - expect(acceptInput, 'Should accept input').to.equal(win.lastInputState); - }); - }); - it('Apply italic.', function() { cy.get('#tb_editbar_item_italic div table') .should('not.have.class', 'checked'); @@ -73,31 +49,6 @@ describe('Pushing bottom toolbar items.', function() { cy.get('#copy-paste-container p i') .should('exist'); }); - - it('Apply italic, check keyboard.', function() { - cy.get('#document-container') - .type('{downarrow}'); - helper.selectAllText(); - - cy.get('#tb_editbar_item_italic div table') - .should('not.have.class', 'checked'); - - cy.window().then(win => { - win.lastInputState = win.map._textInput.shouldAcceptInput(); - }); - - cy.get('#tb_editbar_item_italic') - .click(); - - cy.get('#tb_editbar_item_italic div table') - .should('have.class', 'checked'); - - cy.window().then(win => { - var acceptInput = win.map._textInput.shouldAcceptInput(); - expect(acceptInput, 'Should accept input').to.equal(win.lastInputState); - }); - }); - it('Apply underline.', function() { cy.get('#tb_editbar_item_underline div table') .should('not.have.class', 'checked'); @@ -114,30 +65,6 @@ describe('Pushing bottom toolbar items.', function() { .should('exist'); }); - it('Apply underline, check keyboard.', function() { - cy.get('#document-container') - .type('{downarrow}'); - helper.selectAllText(); - - cy.get('#tb_editbar_item_underline div table') - .should('not.have.class', 'checked'); - - cy.window().then(win => { - win.lastInputState = win.map._textInput.shouldAcceptInput(); - }); - - cy.get('#tb_editbar_item_underline') - .click(); - - cy.get('#tb_editbar_item_underline div table') - .should('have.class', 'checked'); - - cy.window().then(win => { - var acceptInput = win.map._textInput.shouldAcceptInput(); - expect(acceptInput, 'Should accept input').to.equal(win.lastInputState); - }); - }); - it('Apply strikeout.', function() { cy.get('#tb_editbar_item_strikeout div table') .should('not.have.class', 'checked'); diff --git a/cypress_test/integration_tests/mobile/writer/focus_spec.js b/cypress_test/integration_tests/mobile/writer/focus_spec.js index f1efae3ee..268324c58 100644 --- a/cypress_test/integration_tests/mobile/writer/focus_spec.js +++ b/cypress_test/integration_tests/mobile/writer/focus_spec.js @@ -274,4 +274,91 @@ describe('Focus tests', function() { cy.document().its('activeElement.tagName') .should('be.eq', 'BODY'); }); + + it('Apply bold, check keyboard.', function() { + // Click on edit button + helper.enableEditingMobile(); + + // Grab focus to the document + cy.get('#document-container') + .type('x'); + + helper.selectAllText(); + + cy.get('#tb_editbar_item_bold div table') + .should('not.have.class', 'checked'); + + cy.window().then(win => { + win.lastInputState = win.map._textInput.shouldAcceptInput(); + }); + + cy.get('#tb_editbar_item_bold') + .click(); + + cy.get('#tb_editbar_item_bold div table') + .should('have.class', 'checked'); + + cy.window().then(win => { + var acceptInput = win.map._textInput.shouldAcceptInput(); + expect(acceptInput, 'Should accept input').to.equal(win.lastInputState); + }); + }); + + it('Apply italic, check keyboard.', function() { + // Click on edit button + helper.enableEditingMobile(); + + // Grab focus to the document + cy.get('#document-container') + .type('x'); + + helper.selectAllText(); + + cy.get('#tb_editbar_item_italic div table') + .should('not.have.class', 'checked'); + + cy.window().then(win => { + win.lastInputState = win.map._textInput.shouldAcceptInput(); + }); + + cy.get('#tb_editbar_item_italic') + .click(); + + cy.get('#tb_editbar_item_italic div table') + .should('have.class', 'checked'); + + cy.window().then(win => { + var acceptInput = win.map._textInput.shouldAcceptInput(); + expect(acceptInput, 'Should accept input').to.equal(win.lastInputState); + }); + }); + + it('Apply underline, check keyboard.', function() { + // Click on edit button + helper.enableEditingMobile(); + + // Grab focus to the document + cy.get('#document-container') + .type('x'); + + helper.selectAllText(); + + cy.get('#tb_editbar_item_underline div table') + .should('not.have.class', 'checked'); + + cy.window().then(win => { + win.lastInputState = win.map._textInput.shouldAcceptInput(); + }); + + cy.get('#tb_editbar_item_underline') + .click(); + + cy.get('#tb_editbar_item_underline div table') + .should('have.class', 'checked'); + + cy.window().then(win => { + var acceptInput = win.map._textInput.shouldAcceptInput(); + expect(acceptInput, 'Should accept input').to.equal(win.lastInputState); + }); + }); }); commit 6e96d4f6dfb8bafd38c846394ce545224164df3b Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Mar 18 22:05:36 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 12:30:54 2020 +0100 cypress: catch "Uncaught TypeError" error in the log. During parallel build. Change-Id: I18d78250650e5d16ff9a4ff8588a2e955a934f44 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90721 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am index d712c5296..603ec9269 100644 --- a/cypress_test/Makefile.am +++ b/cypress_test/Makefile.am @@ -198,7 +198,7 @@ endef define execute_run_parallel @mkdir -p $(dir $(2)) && touch $(2) && \ echo "`echo $(1) && $(1)`" > $(2) 2>&1 && \ - if [ -z `grep -o -m 1 "CypressError\|AssertionError" $(2)` ];\ + if [ -z `grep -o -m 1 "CypressError\|AssertionError\|Uncaught TypeError" $(2)` ];\ then cat $(2);\ else cat $(2) >> $(ERROR_LOG);\ fi; commit c1b56a357cf7642d37b7f01fefd1bcaf8217e903 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Thu Mar 19 01:46:45 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 12:20:03 2020 +0100 cypress: mobile: don't wait too long during long press. In some use cases this time was too long and hammerjs recognized a pan end by 'pointerup' event. We have 500 ms time set for long press in loleaflet code, so use the exact value here. Change-Id: Iab47c668ffa591ccfd7d2eeed10f2c3ec5664b89 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90723 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/cypress_test/integration_tests/common/helper.js b/cypress_test/integration_tests/common/helper.js index d1789530d..5d3c017d9 100644 --- a/cypress_test/integration_tests/common/helper.js +++ b/cypress_test/integration_tests/common/helper.js @@ -210,7 +210,8 @@ function longPressOnDocument(posX, posY) { .trigger('pointerdown', eventOptions) .trigger('pointermove', eventOptions); - cy.wait(600); + // This value is set in Map.TouchGesture.js. + cy.wait(500); cy.get('.leaflet-pane.leaflet-map-pane') .trigger('pointerup', eventOptions); commit 3418701eccb1933e90f1bb4c5c77efbcb3e7a916 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Mar 18 19:28:57 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 12:01:18 2020 +0100 Revert "cypress: calc assert we are in text edit mode in focus test" There is no assertInTextEditMode() in calc_helper.js. This reverts commit bc5bf2eb2ad355f342f158bcefcb968bb7e78318. Change-Id: I97526eb8ea0297a2ea28080f09c85e4284d70932 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90719 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/cypress_test/integration_tests/mobile/calc/focus_spec.js b/cypress_test/integration_tests/mobile/calc/focus_spec.js index 0ea2b3b77..9b375db34 100644 --- a/cypress_test/integration_tests/mobile/calc/focus_spec.js +++ b/cypress_test/integration_tests/mobile/calc/focus_spec.js @@ -69,7 +69,5 @@ describe('Calc focus tests', function() { // Document has the focus cy.document().its('activeElement.className') .should('be.eq', 'clipboard'); - - calcHelper.assertInTextEditMode(); }); }); commit b33e97e623c41e3de0f58017249d7be476fd305d Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Thu Mar 19 02:05:18 2020 +0100 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Thu Mar 19 12:00:42 2020 +0100 mobile: fix type error hit by cypress test. The issue comes up when we get a drag-end event without a drag-start event. Not sure wether this error can happen in real life or it's just the cypress test framework mobile emulation which can lead to this issue, but an additional check won't hurt. Change-Id: I352a5b523e8400ffc5e77ebefd91166e40517019 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90724 Tested-by: Tamás Zolnai <tamas.zol...@collabora.com> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> diff --git a/loleaflet/src/layer/vector/Path.Drag.js b/loleaflet/src/layer/vector/Path.Drag.js index 47fd8e0e2..c85a9ac32 100644 --- a/loleaflet/src/layer/vector/Path.Drag.js +++ b/loleaflet/src/layer/vector/Path.Drag.js @@ -269,7 +269,7 @@ L.Handler.PathDrag = L.Handler.extend(/** @lends L.Path.Drag.prototype */ { this._path._map.dragging.enable(); } - if (!this._path.options.manualDrag && !moved) { + if (!this._path.options.manualDrag && !moved && this._mouseDown) { this._path._map._handleDOMEvent(this._mouseDown); this._path._map._handleDOMEvent(evt); } commit d6fe0979b71ecc864257ff4595d2ffd27cc449d0 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Mar 19 09:12:33 2020 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Thu Mar 19 11:50:54 2020 +0100 common: handle missing protocol in Session::getIOStats() This sometimes causes unit-integration to fail and now is consistent with other member functions of Session that handle missing protocol. Change-Id: I43c7fcae964cfcb5911ff57d63bd4cb569e6b97c Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90732 Tested-by: Michael Meeks <michael.me...@collabora.com> Reviewed-by: Michael Meeks <michael.me...@collabora.com> diff --git a/common/Session.cpp b/common/Session.cpp index d24b615a9..859cd011e 100644 --- a/common/Session.cpp +++ b/common/Session.cpp @@ -257,6 +257,12 @@ void Session::handleMessage(const std::vector<char> &data) void Session::getIOStats(uint64_t &sent, uint64_t &recv) { + if (!_protocol) + { + LOG_TRC("ERR - missing protocol " << getName() << ": Get IO stats."); + return; + } + _protocol->getIOStats(sent, recv); } commit 08e18799f0a194f30e1a99641c4277a4ab4bcd73 Author: Pedro Pinto Silva <pedro.si...@collabora.com> AuthorDate: Thu Mar 19 10:55:21 2020 +0100 Commit: Pedro Pinto da Silva <pedro.si...@collabora.com> CommitDate: Thu Mar 19 11:09:38 2020 +0100 Mobile: Hamburger and mobileWizard: Add missing icons Change-Id: Id479cb6f1623630b84583c6d2ddd89c9779db7dd Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90737 Tested-by: Pedro Pinto da Silva <pedro.si...@collabora.com> Reviewed-by: Pedro Pinto da Silva <pedro.si...@collabora.com> diff --git a/loleaflet/images/lc_changesmenu.svg b/loleaflet/images/lc_changesmenu.svg new file mode 100644 index 000000000..088300cc5 --- /dev/null +++ b/loleaflet/images/lc_changesmenu.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m5 3v18h6.267578c-.795872-1.135833-1.267578-2.513707-1.267578-4 0-3.854149 3.145851-7 7-7 .694626 0 1.365658.106777 2 .296875v-3.5683594l-4-3.7285156z" fill="#fff"/><path d="m5 2c-.554 0-1 .446-1 1v18c0 .554.446 1 1 1h7.115234c-.312835-.305717-.595999-.640846-.847656-1h-6.267578v-18h9v4c0 .554.446 1 1 1h4v2.296875c.346387.103805.678167.236716 1 .390625v-3.4375-.2089844c0-.4506799.098038-.4254121-.605469-1.0664062l-3.30664-3.2382813c-.709525-.7368575-.710169-.7363281-1.09375-.7363281h-.332032-.662109z" fill="#808080"/><path d="m15 7h4l-4-4z" fill="#fff" fill-rule="evenodd"/><rect fill="#808080" height="1" ry=".5" width="5" x="7" y="5"/><rect fill="#808080" height="1" ry=".5" width="3" x="7" y="9"/><rect fill="#d65532" height="1" ry=".5" width="5" x="12" y="9"/><path d="m7.5 12c-.277 0-.5.223-.5.5s.223.5.5.5h3.767578c.251657-.359154.534821-.694283.847656-1z" fill="#d65532"/><path d="m7.5 15c-.277 0-.5.223-.5.5s.223.5 .5.5h2.580078c.049324-.341059.119834-.676443.216797-1z" fill="#808080"/><path d="m12.474609 15c-.262915 0-.474609.211694-.474609.474609v.05078c0 .262917.211694.474611.474609.474611h1.050782c.06573 0 .128731-.01316.185547-.03711.000848-.000358.0011-.0016.002-.002l.248047-.248047c.000362-.000847.0016-.0011.002-.002.023857-.056721.037015-.119724.037015-.185452v-.05078c0-.262917-.211694-.474611-.474609-.474611z" fill="#808080"/><rect fill="#d65532" height="1" ry=".474576" width="2" x="7" y="18"/><path d="m17 11a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 1a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5z" fill="#808080"/><circle cx="17" cy="17" fill="#fff" r="5"/><circle cx="17" cy="17" fill="#d65532" r="2"/></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_datamenu.svg b/loleaflet/images/lc_datamenu.svg new file mode 100644 index 000000000..06251b16f --- /dev/null +++ b/loleaflet/images/lc_datamenu.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m4.71875 2.5058594-1.2128906 1.1855468v1.1875.3613282l5.9941406 8.3828126v4.310547.046875l2.878906 2.02539 1.003906-2.005859h-.382812a1.0001 1.0001 0 0 1 -.78125-1.625l2.964844-3.699219 5.310547-7.4355466v-1.5488282l-1.212891-1.1855468z" fill="#fff"/><path d="m17.004237 12h5.995763l-4 4h2l-9 7 3-6h-2z" fill="#eac282" fill-rule="evenodd"/><path d="m4.71875 2a.50535904.50535904 0 0 0 -.3535156.1445312l-1.2128906 1.1855469a.50535904.50535904 0 0 0 -.1523438.3613281v1.1875.3613282a.50535904.50535904 0 0 0 .09375.2949218l5.9003906 8.2499998v4.148438.046875a.50535904.50535904 0 0 0 .2148438.414062l2.9414066 2.070313.457031-.916016-2.601563-1.830078v-4.095703a.50535904.50535904 0 0 0 -.0957028-.294922l-5.9003906-8.25v-.1992188-.9746093l.9160156-.8945313h14.1484378l.916015.8945313v1.1738281l-5.894531 8.25a.50535904.50535904 0 0 0 -.095703.294922v.529297l2.224609-2.777344a1.0001 1.0001 0 0 1 .777344-.375l3.904297-5.4648438a .50535904.50535904 0 0 0 .09375-.2949218v-1.5488282a.50535904.50535904 0 0 0 -.152344-.3613281l-1.21289-1.1855469a.50535904.50535904 0 0 0 -.353516-.1445312zm10.292969 17.212891-.146485.292968.146485-.113281z" fill="#808080"/></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_diagramtype.svg b/loleaflet/images/lc_diagramtype.svg new file mode 100644 index 000000000..ee97da3a6 --- /dev/null +++ b/loleaflet/images/lc_diagramtype.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><rect fill="#4d82b8" height="15" ry="1" width="5" x="2" y="7"/><path d="m17 10c-.554 0-1 .446-1 1v5.585938l5-5v-.585938c0-.554-.446-1-1-1z" fill="#808080"/><path d="m10 2c-.554 0-1 .446-1 1v18c0 .554.446 1 1 1h.585938l3.414062-3.414062v-15.585938c0-.554-.446-1-1-1z" fill="#eac282"/><path d="m23 11-12 12h12zm-2 5v5h-5z" fill="#4d82b8" fill-rule="evenodd"/></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_downloadas.svg b/loleaflet/images/lc_downloadas.svg new file mode 100644 index 000000000..462f994fe --- /dev/null +++ b/loleaflet/images/lc_downloadas.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m5 4v17h12.076172c.08822-.229036.224537-.442298.402344-.601562l.40625-.408204h-6.363282c-.420168.005943-.867654-.182805-1.138672-.484375-.271015-.30157-.382812-.666177-.382812-1.015625 0-.349447.111796-.714055.382812-1.015625.271018-.30157.718504-.490275 1.138672-.484375h6.351563l-.421875-.421875c-.452852-.438274-.556085-1.125408-.347656-1.640625.207997-.514149.758145-.9356 1.386718-.9375h.001954c.175227-.000445.345797.035698.507812.09375v-6.3554684l-4-3.7285156z" fill="#fff"/><path d="m5 3c-.554 0-1 .446-1 1v17c0 .554.446 1 1 1h12.060547c-.047908-.135592-.083757-.278117-.089844-.435547-.007198-.186166.034536-.380297.105469-.564453h-12.076172v-17h9v4c0 .554.446 1 1 1h4v5.083984c.211956.075948.408045.193521.568359.357422l.431641.431641v-6.623047-.2089844c0-.4506799.098038-.4254121-.605469-1.0664062l-3.30664-3.2382813c-.709525-.7368575-.710169-.7363281-1.09375-.7363281h-.332032-.662109z" fill="#808080"/><g fill-rule= "evenodd"><path d="m15 8h4l-4-4z" fill="#fff"/><path d="m18.494141 14.990234a.50005.50005 0 0 0 -.347657.859375l2.144532 2.140625h-8.783204a.50005.50005 0 1 0 0 1h8.78711l-2.148438 2.152344a.50005.50005 0 1 0 .707032.705078l2.957031-2.960937a.50005.50005 0 0 0 -.003906-.796875l-2.953125-2.949219a.50005.50005 0 0 0 -.359375-.150391z" fill="#4d82b8"/></g></svg> diff --git a/loleaflet/images/lc_editmenu.svg b/loleaflet/images/lc_editmenu.svg new file mode 100644 index 000000000..cf0c07abc --- /dev/null +++ b/loleaflet/images/lc_editmenu.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m5 3v18h5.462891l.517578-2.103516c.04344-.177395.134629-.339507.263672-.46875l5.529297-5.523437.0078-.0078.738281-.720703 1.480481-1.476575v-3.9707034l-4-3.7285156zm14 16.1875-1.802734 1.8125h1.802734z" fill="#fff"/><path d="m5 2c-.554 0-1 .446-1 1v18c0 .554.446 1 1 1h5.216797l.246094-1h-5.462891v-18h9v4c0 .554.446 1 1 1h4v2.699219l.189453-.189453c.10637-.106241.227363-.190073.353516-.263672.022042-.012592.043911-.023576.066406-.035156.123752-.06524.251663-.116414.384766-.150391.00198-.000505.003877-.001455.005859-.001953v-2.808594-.2089844c0-.4506799.098038-.4254121-.605469-1.0664062l-3.30664-3.2382813c-.709525-.7368575-.710169-.7363281-1.09375-.7363281h-.332032-.662109zm15 16.179688-1 1.005859v.001953 1.8125h-1.802734l-.992188 1h2.794922c.554 0 1-.446 1-1z" fill="#808080"/><path d="m15 7h4l-4-4z" fill="#fff" fill-rule="evenodd"/><g fill="#eac282" transform="translate(-1 -1)"><path d="m18.480469 14.611328-5.529297 5.523438-.951172 3.865234 3.806641-1.011719 5.509765-5.544922z"/><path d="m21.419922 12c-.189562 0-.378184.07172-.523438.216797l-1.673828 1.669922 2.847656 2.849609 1.710938-1.638672c.290506-.290127.290506-.756747 0-1.046875l-1.835938-1.833984c-.145254-.145064-.335828-.216797-.52539-.216797z"/></g></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_file.svg b/loleaflet/images/lc_file.svg new file mode 100644 index 000000000..0e617d96f --- /dev/null +++ b/loleaflet/images/lc_file.svg @@ -0,0 +1,7 @@ +<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <path d="m5 4v17s14-0.92018 14-13.271l-4-3.7285z" fill="#fff"/> + <path d="m5 3c-0.554 0-1 0.446-1 1v17c0 0.554 0.446 1 1 1h2.6074 9.4531 1.9434c0.554 0 1-0.446 1-1v-12.479l-0.003906 0.0039062v-0.27539-0.20898c0-0.45068 0.098038-0.42541-0.60547-1.0664l-3.3066-3.2383c-0.70952-0.73686-0.71017-0.73633-1.0938-0.73633h-0.33203-0.66211-9zm0 1h9v4c0 0.554 0.446 1 1 1h4v5.084c0.001376 4.93e-4 0.002531 0.001457 0.003906 0.001954v6.9141h-1.9277-8.5508-3.5254v-17z" fill="#808080"/> + <g fill-rule="evenodd"> + <path d="m15 8h4l-4-4z" fill="#fff"/> + </g> +</svg> diff --git a/loleaflet/images/lc_pagesetup.svg b/loleaflet/images/lc_pagesetup.svg new file mode 100644 index 000000000..e0d41c5d6 --- /dev/null +++ b/loleaflet/images/lc_pagesetup.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m9 4.9980469v3.0019531c0 .554-.446 1-1 1h-4.9980469v9.998047h14.2714849l3.728515-4v-10.0000001z" fill="#fff"/><path d="m9 3.9980469v1h12.001953v9.0000001h-4c-.554 0-1 .446-1 1v4h-12.9999999v-9.998047h-1v9.998047c0 .554.446 1 1 1h10.1093749 3.642578.207032c.450679 0 .427365.098038 1.068359-.605469l3.236328-3.30664c.736858-.709525.736328-.712123.736328-1.095704v-.330078-.662109-9.0000001c0-.554-.446-1-1-1z" fill="#808080"/><path d="m17.00238 14.99762v4l4-4z" fill="#fff" fill-rule="evenodd"/><g fill="#eac282"><rect height="1" ry=".5" width="6" x="1" y="1"/><rect height="6" ry=".5" width="1" x="1" y="1"/><path d="m2.4999352 7.4999941 5.0000589-5.0000589v5.0000589z" fill-rule="evenodd" stroke="#eac282" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.000012"/></g></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_sheetmenu.svg b/loleaflet/images/lc_sheetmenu.svg new file mode 100644 index 000000000..f19ef8747 --- /dev/null +++ b/loleaflet/images/lc_sheetmenu.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 3h18v18h-18z" fill="#fff"/><path d="m3 2c-.554 0-1 .446-1 1v18c0 .554.446 1 1 1h18c.554 0 1-.446 1-1v-18c0-.554-.446-1-1-1zm0 1h5v6h-5zm6 0h6v6h-6zm7 0h5v6h-5zm-13 7h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5zm-13 4h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5zm-13 4h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5z" fill="#808080"/><path d="m2 2h20v4h-20z" fill="#4d82b8"/></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_slidemenu.svg b/loleaflet/images/lc_slidemenu.svg new file mode 100644 index 000000000..03c7196fb --- /dev/null +++ b/loleaflet/images/lc_slidemenu.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 7h18v13h-18z" fill="#fff"/><path d="m2 6v15h1 8.585938 9.414062 1v-10.414062-3.585938-1zm1 1h18v4.585938 8.414062h-8.414062-9.585938z" fill="#808080"/><path d="m1 3h22v2h-22z" fill="#4d82b8"/><path d="m5 9h14v2h-14z" fill="#eac282"/><g fill="#808080"><path d="m5 12h6v1h-6z"/><path d="m5 16h6v1h-6z"/><path d="m5 14h6v1h-6z"/><path d="m5 18h6v1h-6z"/><path d="m13 12h6v1h-6z"/><path d="m13 16h6v1h-6z"/><path d="m13 14h6v1h-6z"/><path d="m13 18h6v1h-6z"/></g></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_tabledesign.svg b/loleaflet/images/lc_tabledesign.svg new file mode 100644 index 000000000..c3c697518 --- /dev/null +++ b/loleaflet/images/lc_tabledesign.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 3v18h8.585938l9.414062-9.414062v-8.585938zm17 15.414062-1.585938 1.585938h1.585938z" fill="#fff"/><path d="m21 2c.554 0 1 .446 1 1v7.585938l-1 1v-1.585938h-5v3h3.585937l-1 1h-2.585937v2.585938l-1.414062 1.414062h-5.585938v3h2.585938l-1 1h-7.585938c-.554 0-1-.446-1-1v-18c0-.554.446-1 1-1zm0 1h-5v6h5zm-6 0h-6v6h6zm-7 0h-5v6h5zm7 7h-6v3h6zm-7 0h-5v3h5zm7 4h-6v3h6zm-7 0h-5v3h5zm0 4h-5v3h5z" fill="#808080"/><path d="m-22 2h20v4h-20z" fill="#808080" transform="scale(-1 1)"/><path d="m23 11-12 12h12zm-2 5v5h-5z" fill="#4d82b8" fill-rule="evenodd"/></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_tablemenu.svg b/loleaflet/images/lc_tablemenu.svg new file mode 100644 index 000000000..f19ef8747 --- /dev/null +++ b/loleaflet/images/lc_tablemenu.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 3h18v18h-18z" fill="#fff"/><path d="m3 2c-.554 0-1 .446-1 1v18c0 .554.446 1 1 1h18c.554 0 1-.446 1-1v-18c0-.554-.446-1-1-1zm0 1h5v6h-5zm6 0h6v6h-6zm7 0h5v6h-5zm-13 7h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5zm-13 4h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5zm-13 4h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5z" fill="#808080"/><path d="m2 2h20v4h-20z" fill="#4d82b8"/></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_view.svg b/loleaflet/images/lc_view.svg new file mode 100644 index 000000000..69e710261 --- /dev/null +++ b/loleaflet/images/lc_view.svg @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + viewBox="0 0 24 24" + version="1.1" + id="svg16" + sodipodi:docname="lc_morecontrols.svg" + inkscape:version="0.92.4 (unknown)"> + <metadata + id="metadata22"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs20" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1017" + id="namedview18" + showgrid="false" + inkscape:zoom="11.313708" + inkscape:cx="13.521499" + inkscape:cy="7.2888914" + inkscape:window-x="0" + inkscape:window-y="30" + inkscape:window-maximized="1" + inkscape:current-layer="svg16" /> + <path + d="M 21,6 H 3 v 15 h 18" + id="path2" + inkscape:connector-curvature="0" + style="fill:#fcfcfc" + sodipodi:nodetypes="cccc" /> + <g + id="g12" + style="fill:#808080"> + <path + d="M 22,3 C 22,2.446 21.554,2 21,2 H 3 C 2.446,2 2,2.446 2,3 v 18 c 0,0.554 0.446,1 1,1 h 18 c 0.554,0 1,-0.446 1,-1 z M 21,21 H 3 V 6 h 18 z" + id="path4" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cssssccccccccc" /> + <path + d="m 5,8 v 4 H 9 V 8 Z m 1,1 h 2 v 2 H 6 Z" + id="path6" + inkscape:connector-curvature="0" /> + <path + d="m 5,14 v 4 h 4 v -4 z m 1,1 h 2 v 2 H 6 Z" + id="path8" + inkscape:connector-curvature="0" /> + <path + d="m 11,9 h 7 v 1 h -7 z" + id="path10" + inkscape:connector-curvature="0" /> + </g> + <ellipse + cy="18.325001" + cx="17.704151" + id="circle833" + style="fill:#fcfcfc;fill-opacity:1;stroke:#4d82b8;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" + rx="5" + ry="3.5" /> + <circle + style="fill:#4d82b8;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" + id="path831" + cx="17.704151" + cy="18.325001" + r="2" /> +</svg> commit 8ab2f4f01a1b0e01cbd9627238d3c89919df28f7 Author: Pedro Pinto Silva <pedro.si...@collabora.com> AuthorDate: Thu Mar 19 10:11:21 2020 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Thu Mar 19 10:34:25 2020 +0100 Mobile: mobilewizard: context menu: wrap; rotate; anchor: add missing icons and - adjust lc_wrapthrough.svg so it's visible the diference between that and the new icon option lc_wrapthroughtransparencytoggle.svg - create and add first paragraph option Change-Id: I224284e973340a15d60fa705117dd33ebb7b1450 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90734 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/images/lc_anchormenu.svg b/loleaflet/images/lc_anchormenu.svg new file mode 100644 index 000000000..66bcde439 --- /dev/null +++ b/loleaflet/images/lc_anchormenu.svg @@ -0,0 +1,4 @@ +<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <path d="m8.0488 2-7.0488 20h2.9863c0.32039 0 0.58719-0.09076 0.80078-0.27148 0.2233-0.19076 0.3735-0.3963 0.45117-0.61719l1.209-3.916h5.8047l0.044922-0.03125c0.25925-0.18599 0.57769-0.29488 0.90625-0.29687 0.73878-0.003821 1.2821 0.55054 1.4883 1.123v-1.6133h-0.24414c-0.87923 0-1.623-0.73808-1.623-1.6211 0-0.71181 0.53066-1.2243 1.1797-1.4375-0.34798-0.47875-0.55598-1.0542-0.55664-1.6719v-0.001953c-2.55e-4 -0.90942 0.44146-1.7171 1.1113-2.2441l-2.6074-7.4004h-3.9023zm1.9375 3.6445c0.12621 0.49197 0.25074 0.94941 0.37695 1.3711 0.12621 0.41165 0.24873 0.77274 0.36524 1.084l1.9648 6.3242h-5.3867l1.9648-6.3086c0.1068-0.31124 0.2234-0.67792 0.34961-1.0996 0.12621-0.42169 0.24873-0.87913 0.36523-1.3711z" fill="#696969"/> + <path d="m16.314 9.7778a1.8667 1.8667 0 0 0-1.8667 1.8667 1.8667 1.8667 0 0 0 1.2444 1.7585v0.73036h-1.2444c-0.34471 0-0.62222 0.27751-0.62222 0.62222s0.27751 0.62222 0.62222 0.62222h1.2444v5.5563c-1.0596-0.13504-2.0494-0.60481-2.8207-1.3466l0.66111-0.46302a0.61243 0.67872 0 0 0-0.32326-1.2578 0.61243 0.67872 0 0 0-0.33056 0.11059l-2.4876 1.7379a0.61265 0.67896 0 1 0 0.65383 1.1484l0.79476-0.55538c1.1666 1.213 2.7771 1.9128 4.4746 1.9141 1.698-9.33e-4 3.309-0.70087 4.4759-1.9141l0.79358 0.55538a0.61265 0.67896 0 1 0 0.65383-1.1484l-2.4876-1.7379a0.61243 0.67872 0 0 0-0.33056-0.11059 0.61243 0.67872 0 0 0-0.32326 1.2578l0.66478 0.46545c-0.7723 0.74169-1.7638 1.2114-2.8243 1.3453v-5.5574h1.2444c0.34471 0 0.62222-0.27751 0.62222-0.62222 0-0.34471-0.27751-0.62222-0.62222-0.62222h-1.2444v-0.73161a1.8667 1.8667 0 0 0 1.2444-1.7573 1.8667 1.8667 0 0 0-1.8667-1.8667zm0 1.2444a0.62222 0.62222 0 0 1 0.62222 0.62222 0.62222 0.62222 0 0 1-0.62222 0.62222 0.62222 0.62222 0 0 1-0.62222-0.62222 0 .62222 0.62222 0 0 1 0.62222-0.62222z" fill="#4d82b8" stroke-width=".62222"/> +</svg> diff --git a/loleaflet/images/lc_rotateleft.svg b/loleaflet/images/lc_rotateleft.svg new file mode 100644 index 000000000..1f33cc671 --- /dev/null +++ b/loleaflet/images/lc_rotateleft.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m1.499971 21.5h7.000029v-15z" fill="#4d82b8" fill-rule="evenodd" stroke="#4d82b8" stroke-linecap="round" stroke-linejoin="round"/><path d="m10.5 14.5v7.000008h12z" fill="#fff" fill-rule="evenodd" stroke="#808080" stroke-linecap="round" stroke-linejoin="round"/><g transform="matrix(0 -1 -1 0 30.992858 27)"><path d="m21.5 16.5-2.995 2.992879-3.005-2.992879" fill="none" stroke="#4d82b8" stroke-linecap="round" stroke-linejoin="round"/><path d="m13.5 11.007943c-.276142 0-.5.223858-.5.5s.223858.5.5.5h2c1.380712 0 2.5 1.119287 2.5 2.5h.0059v.423829 4.068228h1v-4.068228-.5c-.0059-2.154663-1.88341-3.373799-3.5059-3.423829z" fill="#4d82b8" fill-rule="evenodd"/></g></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_rotateright.svg b/loleaflet/images/lc_rotateright.svg new file mode 100644 index 000000000..40e86d9b3 --- /dev/null +++ b/loleaflet/images/lc_rotateright.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(-1 0 0 1 23.999864 0)"><path d="m1.499971 21.5h7.000029v-15.0000002z" fill="#4d82b8" fill-rule="evenodd" stroke="#4d82b8" stroke-linecap="round" stroke-linejoin="round"/><path d="m10.5 14.5v7.000008h11.999999z" fill="#fff" fill-rule="evenodd" stroke="#808080" stroke-linecap="round" stroke-linejoin="round"/><g transform="matrix(0 -1 -1 0 30.992857 27)"><path d="m21.5 16.5-2.995 2.992879-3.005-2.992879" fill="none" stroke="#4d82b8" stroke-linecap="round" stroke-linejoin="round"/><path d="m13.5 11.007943c-.276142 0-.5.223858-.5.5s.223858.5.5.5h2c1.380712 0 2.5 1.119287 2.5 2.5h.0059v.423829 4.068228h1v-4.068228-.5c-.0059-2.154663-1.88341-3.373799-3.5059-3.423829z" fill="#4d82b8" fill-rule="evenodd"/></g></g></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_wrapanchoronly.svg b/loleaflet/images/lc_wrapanchoronly.svg new file mode 100644 index 000000000..dcd117fde --- /dev/null +++ b/loleaflet/images/lc_wrapanchoronly.svg @@ -0,0 +1,8 @@ +<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <rect x="14.153" y="3" width="7.8474" height="1" ry=".44607" fill="#4d82b8" stroke-width=".62639"/> + <g fill="#808080"> + <rect x="2" y="21" width="20" height="1" ry=".44607"/> + <rect x="2" y="18" width="20" height="1" ry=".44607"/> + </g> + <path d="m6.0201 3c-0.025732 0-0.049852 0.00598-0.075458 0.00653a3.9823 3.9823 0 0 0-0.59847 0.052052c-0.00473 7.997e-4 -0.00956 0.00177-0.014308 0.00255a3.9823 3.9823 0 0 0-3.3319 3.9265 3.9823 3.9823 0 0 0 1.906 3.3917c0.047967 0.03013 0.095101 0.06035 0.14441 0.08847a3.9823 3.9823 0 0 0 0.42153 0.20166c0.10916 0.04623 0.22048 0.08577 0.33436 0.1223 0.38422 0.12322 0.78845 0.20166 1.2138 0.20166v5.329h1.3322v-11.99h1.3322v11.99h1.3322v-11.99l2.6645-0.66612v-0.66612z" fill="#4d82b8" stroke-width=".66612"/> +</svg> diff --git a/loleaflet/images/lc_wrapcontour.svg b/loleaflet/images/lc_wrapcontour.svg new file mode 100644 index 000000000..8a6981c36 --- /dev/null +++ b/loleaflet/images/lc_wrapcontour.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><rect fill="#808080" height="1" ry=".446068" transform="scale(-1 1)" width="20" x="-22" y="3"/><rect fill="#4d82b8" height="8.919747" ry=".743312" transform="matrix(.70710679 .70710677 -.70710679 .70710677 0 0)" width="8.919747" x="16.75333" y="-5.874086"/><g fill="#808080" transform="scale(-1 1)"><rect height="1" ry=".446068" width="20" x="-22" y="6"/><rect height="1" ry=".446068" width="20" x="-22" y="21"/><rect height="1" ry=".410114" width="5.999999" x="-8" y="15"/><rect height="1" ry=".423729" width="6.000001" x="-8" y="12"/><rect height="1" ry=".419102" width="9" x="-11" y="9"/><rect height="1" ry=".410114" width="9" x="-11" y="18"/></g></svg> \ No newline at end of file diff --git a/loleaflet/images/lc_wrapthrough.svg b/loleaflet/images/lc_wrapthrough.svg index f6010d01e..b34b507e0 100644 --- a/loleaflet/images/lc_wrapthrough.svg +++ b/loleaflet/images/lc_wrapthrough.svg @@ -1 +1,12 @@ -<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><rect fill="#808080" height="1" ry=".446068" width="20" x="2" y="3"/><rect fill="#4d82b8" height="9" ry="1" width="10" x="7" y="8"/><g fill="#808080"><rect height="1" ry=".446068" width="20" x="2" y="6"/><rect height="1" ry=".446068" width="20" x="2" y="21"/><rect height="1" ry=".446068" width="20" x="2" y="12"/><rect height="1" ry=".446068" width="20" x="2" y="18"/><rect height="1" ry=".446068" width="20" x="2" y="9"/><rect height="1" ry=".446068" width="20" x="2" y="15"/></g></svg> \ No newline at end of file +<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <rect x="2" y="3" width="20" height="1" ry=".44607" fill="#808080"/> + <g fill="#808080"> + <rect x="2" y="6" width="20" height="1" ry=".44607"/> + <rect x="2" y="21" width="20" height="1" ry=".44607"/> + <rect x="2" y="12" width="20" height="1" ry=".44607"/> + <rect x="2" y="18" width="20" height="1" ry=".44607"/> + <rect x="2" y="9" width="20" height="1" ry=".44607"/> + <rect x="2" y="15" width="20" height="1" ry=".44607"/> + </g> + <rect x="7" y="8" width="10" height="9" ry="1" fill="#4d82b8"/> +</svg> diff --git a/loleaflet/images/lc_wrapthroughtransparencytoggle.svg b/loleaflet/images/lc_wrapthroughtransparencytoggle.svg new file mode 100644 index 000000000..37f749f89 --- /dev/null +++ b/loleaflet/images/lc_wrapthroughtransparencytoggle.svg @@ -0,0 +1,12 @@ +<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <rect x="7" y="8" width="10" height="9" ry="1" fill="#4d82b8"/> + <rect x="2" y="3" width="20" height="1" ry=".44607" fill="#808080"/> + <g fill="#808080"> + <rect x="2" y="6" width="20" height="1" ry=".44607"/> + <rect x="2" y="21" width="20" height="1" ry=".44607"/> + <rect x="2" y="12" width="20" height="1" ry=".44607"/> + <rect x="2" y="18" width="20" height="1" ry=".44607"/> + <rect x="2" y="9" width="20" height="1" ry=".44607"/> + <rect x="2" y="15" width="20" height="1" ry=".44607"/> + </g> +</svg> commit 583547926e5f47cbcbc96ade04df4d5766f46692 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Thu Mar 19 08:58:46 2020 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Thu Mar 19 09:03:55 2020 +0100 android: Breaking the build on extra translation is a nonsense. The next translation update will kill the extra string anyway. Change-Id: Ieda2ea51837e12fe40d2c85ff2d99afc65a2989b Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90731 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/android/app/build.gradle b/android/app/build.gradle index 6ca998f58..0ac10b9f6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -13,7 +13,7 @@ android { } lintOptions { - disable 'MissingTranslation' + disable 'MissingTranslation', 'ExtraTranslation' } buildTypes { diff --git a/android/lib/build.gradle b/android/lib/build.gradle index 812a8a7aa..0fa72b561 100644 --- a/android/lib/build.gradle +++ b/android/lib/build.gradle @@ -19,7 +19,7 @@ android { } lintOptions { - disable 'MissingTranslation' + disable 'MissingTranslation', 'ExtraTranslation' } buildTypes { commit 8f86c5929568fcbba9cc36c428744cbc58dc2dd4 Author: Weblate <nore...@documentfoundation.org> AuthorDate: Wed Mar 18 22:35:26 2020 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Thu Mar 19 09:01:45 2020 +0100 update translations LibreOffice Online/android-app (Ukrainian) Currently translated at 100.0% (100 of 100 strings) Change-Id: I1e0750a6d3fecb7736cc2df4c1e4b600187fd858 update translations LibreOffice Online/android-lib (Czech) Currently translated at 100.0% (12 of 12 strings) Change-Id: I35f5302c62e6950459b2fdb0b169f9445f8b8034 update translations LibreOffice Online/android-lib (Ukrainian) Currently translated at 100.0% (12 of 12 strings) Change-Id: Ide65bc2675a820111f150b13519ae2c1ec8b57c2 update translations LibreOffice Online/android-lib (Polish) Currently translated at 100.0% (12 of 12 strings) Change-Id: I2917662b4663d3e13f5564e822f9f3652c1bcc7a update translations LibreOffice Online/android-app (Hungarian) Currently translated at 100.0% (100 of 100 strings) Change-Id: I82425b31fff35f1a00767d1497dc0123af9d4321 update translations LibreOffice Online/android-lib (Hungarian) Currently translated at 100.0% (12 of 12 strings) Change-Id: I4ca0eb2624bbb7c90742bd42811c8c9be301e423 update translations LibreOffice Online/android-lib (Portuguese (Brazil)) Currently translated at 100.0% (12 of 12 strings) Change-Id: Ia25abe8feca105d849ca35a4f8e02e7b0aa8fab1 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90714 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/android/app/src/main/res/values-hu/strings.xml b/android/app/src/main/res/values-hu/strings.xml index d18f6bd2b..4cac2534b 100644 --- a/android/app/src/main/res/values-hu/strings.xml +++ b/android/app/src/main/res/values-hu/strings.xml @@ -99,4 +99,5 @@ <string name="share_document">Dokumentum megosztása</string> <string name="pref_enable_chrome_debugger_info">A Chrome hibakereső eszközének engedélyezése a dokumentumban</string> <string name="pref_enable_chrome_debugger">Hibakeresés Chrome-mal</string> + <string name="pref_category_editor">A szerkesztő beállításai</string> </resources> \ No newline at end of file diff --git a/android/app/src/main/res/values-uk/strings.xml b/android/app/src/main/res/values-uk/strings.xml index f10ad51f2..a18ec71bd 100644 --- a/android/app/src/main/res/values-uk/strings.xml +++ b/android/app/src/main/res/values-uk/strings.xml @@ -99,4 +99,5 @@ <string name="server_url_and_port">URL і порт хмарного сервера.</string> <string name="server_url">URL сервера</string> <string name="otg_warning">Експериментальна можливість: Використовувати, тільки якщо OTG пристрій доступний для запису.</string> + <string name="pref_category_editor">Налаштування Редактора</string> </resources> \ No newline at end of file diff --git a/android/lib/src/main/res/values-cs/strings.xml b/android/lib/src/main/res/values-cs/strings.xml index 4bb7bf8eb..72170a53e 100644 --- a/android/lib/src/main/res/values-cs/strings.xml +++ b/android/lib/src/main/res/values-cs/strings.xml @@ -10,4 +10,7 @@ <string name="saving">Ukládání...</string> <string name="rate_our_app_title">Děkujeme, že používáte %1$s!</string> <string name="later">Později</string> + <string name="exiting">Ukončování...</string> + <string name="rate_our_app_text">Pokud se vám tato aplikace líbí, dejte jí na Google Play 5 hvězdiček. Příznivé recenze jsou pro nás tou nejlepší motivací.</string> + <string name="rate_now">Ohodnotit nyní</string> </resources> \ No newline at end of file diff --git a/android/lib/src/main/res/values-hu/strings.xml b/android/lib/src/main/res/values-hu/strings.xml index 8749b1a2f..bb910d83e 100644 --- a/android/lib/src/main/res/values-hu/strings.xml +++ b/android/lib/src/main/res/values-hu/strings.xml @@ -8,4 +8,9 @@ <string name="temp_file_saving_disabled">Ez a fájl írásvédett, a mentés le van tiltva.</string> <string name="preparing_for_the_first_start_after_an_update">Előkészülés a frissítés utáni első indításhoz.</string> <string name="saving">Mentés...</string> + <string name="exiting">Kilépés...</string> + <string name="rate_our_app_text">Ha tetszik az alkalmazás, kérjük, adjon 5 csillagot a Google Play-en. A pozitív visszajelzések motiválnak minket a legjobban.</string> + <string name="rate_our_app_title">Köszönjük, hogy a %1$s-t használja!</string> + <string name="later">Később</string> + <string name="rate_now">Értékelés most</string> </resources> \ No newline at end of file diff --git a/android/lib/src/main/res/values-pl/strings.xml b/android/lib/src/main/res/values-pl/strings.xml index 7bdb9e4ed..952a016f0 100644 --- a/android/lib/src/main/res/values-pl/strings.xml +++ b/android/lib/src/main/res/values-pl/strings.xml @@ -8,4 +8,9 @@ <string name="failed_to_load_file">Nie udało się określić pliku do załadowania</string> <string name="storage_permission_required">Wymagane jest pozwolenie na przechowywanie</string> <string name="temp_file_saving_disabled">Ten plik jest tylko do odczytu, zapisywanie jest wyłączone.</string> + <string name="exiting">Wychodzenie...</string> + <string name="rate_our_app_text">Jeśli Ci się spodoba, daj nam 5 gwiazdek w Google Play. Twoja pozytywna recenzja jest naszą największą motywacją.</string> + <string name="rate_our_app_title">Dziękujemy za używanie %1$s!</string> + <string name="later">Później</string> + <string name="rate_now">Oceń teraz</string> </resources> \ No newline at end of file diff --git a/android/lib/src/main/res/values-pt-rBR/strings.xml b/android/lib/src/main/res/values-pt-rBR/strings.xml index c93ace1da..98b088211 100644 --- a/android/lib/src/main/res/values-pt-rBR/strings.xml +++ b/android/lib/src/main/res/values-pt-rBR/strings.xml @@ -13,4 +13,5 @@ <string name="rate_our_app_text">Se gostou dele, marque 5 estrelas no Google Play. Sua avaliação positiva é nossa melhor motivação.</string> <string name="rate_our_app_title">Obrigado por usar %1$s!</string> <string name="later">Mais tarde</string> + <string name="exiting">Saindo...</string> </resources> \ No newline at end of file diff --git a/android/lib/src/main/res/values-uk/strings.xml b/android/lib/src/main/res/values-uk/strings.xml index 6d8e030ba..66c7a3d4b 100644 --- a/android/lib/src/main/res/values-uk/strings.xml +++ b/android/lib/src/main/res/values-uk/strings.xml @@ -8,4 +8,9 @@ <string name="failed_to_load_file">Помилка визначення файлу для завантаження</string> <string name="storage_permission_required">Необхідний дозвіл на збереження</string> <string name="temp_file_saving_disabled">Цей файл тільки для читання, збереження неможливе.</string> + <string name="exiting">Виходимо...</string> + <string name="rate_our_app_text">Якщо Вам це подобається, будь ласка, поставте нам 5 зірочок в Google Play. Ваші гарні відгуки - наша найкраща мотивація.</string> + <string name="rate_our_app_title">Дякуємо за використання %1$s!</string> + <string name="later">Пізніше</string> + <string name="rate_now">Оцінити зараз</string> </resources> \ No newline at end of file commit a09a0877d17ccee383403c4c4d6bd4427e6fcdde Author: Henry Castro <hcas...@collabora.com> AuthorDate: Thu Mar 12 23:29:39 2020 -0400 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Thu Mar 19 08:56:09 2020 +0100 loleaflet: ensure forward message if early websocket is connected This should never happen, since the _onMessage is re-assigned when loadDocument is called, but it is better to ensure to forward all messages. Change-Id: I9a792bc077b26f2f92c30c4e7851c9d2b2637bfb Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90449 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js index f98450fb0..a08c4cf3b 100644 --- a/loleaflet/js/global.js +++ b/loleaflet/js/global.js @@ -320,6 +320,7 @@ global.socket.onmessage = function (event) { if (typeof global.socket._onMessage === 'function') { + global.socket._emptyQueue(); global.socket._onMessage(event); } else { global.queueMsg.push(event.data); diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index a173ef784..b4118479f 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -76,8 +76,11 @@ L.Socket = L.Class.extend({ } // process messages for early socket connection - if (socket && ((socket.readyState === 1 || socket.readyState === 0)) && - window.queueMsg && window.queueMsg.length > 0) { + this._emptyQueue(); + }, + + _emptyQueue: function () { + if (window.queueMsg && window.queueMsg.length > 0) { for (var it = 0; it < window.queueMsg.length; it++) { this._onMessage({data: window.queueMsg[it]}); } commit 1c4a66e736d73ab372745972a3bfcbb611e2de8a Author: Henry Castro <hcas...@collabora.com> AuthorDate: Thu Mar 12 23:43:15 2020 -0400 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Wed Mar 18 23:20:27 2020 +0100 lolealet: fill the font list when data is received The changes only populate the font list when the data is received by the client, the other approach iterates all toolbar items to refresh each one. Change-Id: I837b52275b49e025fa353dcf088f97c19779bc79 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/90450 Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/src/control/Control.Toolbar.js b/loleaflet/src/control/Control.Toolbar.js index ea80836a4..d6e8ce67d 100644 --- a/loleaflet/src/control/Control.Toolbar.js +++ b/loleaflet/src/control/Control.Toolbar.js @@ -2090,6 +2090,39 @@ function onCommandValues(e) { } } +function updateToolbarCommandValues(e) { + if (e.commandName === '.uno:CharFontName') { + // 2) For .uno:CharFontName + var commandValues = map.getToolbarCommandValues(e.commandName); + if (typeof commandValues === 'undefined') { + return; + } + + var data = []; // reset data in order to avoid that the font select box is populated with styles, too. + // Old browsers like IE11 et al don't like Object.keys with + // empty arguments + if (typeof commandValues === 'object') { + data = data.concat(Object.keys(commandValues)); + } + + /* debug messages it will be removed later */ + if (data.length < 3) { + console.log('ALERT!, the server is sending a small font list'); + } + /* debug end*/ + + $('.fonts-select').select2({ + data: data.sort(function (a, b) { // also sort(localely) + return a.localeCompare(b); + }), + placeholder: _('Font') + }); + $('.fonts-select').on('select2:select', onFontSelect); + $('.fonts-select').val(fontsSelectValue).trigger('change'); + w2ui['editbar'].resize(); + } +} + function updateCommandValues(targetName) { var data = []; // 1) For .uno:StyleApply @@ -2162,29 +2195,6 @@ function updateCommandValues(targetName) { $('.styles-select').on('select2:select', onStyleSelect); w2ui['editbar'].resize(); } - - if (targetName === 'fonts' && $('.fonts-select option').length === 1) { - // 2) For .uno:CharFontName - commandValues = map.getToolbarCommandValues('.uno:CharFontName'); - if (typeof commandValues === 'undefined') { - return; - } - data = []; // reset data in order to avoid that the font select box is populated with styles, too. - // Old browsers like IE11 et al don't like Object.keys with - // empty arguments - if (typeof commandValues === 'object') { - data = data.concat(Object.keys(commandValues)); - } - $('.fonts-select').select2({ - data: data.sort(function (a, b) { // also sort(localely) - return a.localeCompare(b); - }), - placeholder: _('Font') ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits