From fc884b360e01c0560777aefc63a25df0fb0c8e22 Mon Sep 17 00:00:00 2001 From: Kai Engert Date: Sat, 7 Mar 2015 14:49:00 +0100 Subject: [PATCH 01/42] Bug 1137470, landing NSS_3_18_RC0 minus bug 1132496, r=nss-confcall --- security/nss/TAG-INFO | 2 +- security/nss/coreconf/coreconf.dep | 1 + .../nss/external_tests/ssl_gtest/databuffer.h | 123 +- .../nss/external_tests/ssl_gtest/manifest.mn | 5 +- .../ssl_gtest/ssl_loopback_unittest.cc | 605 +------ .../nss/external_tests/ssl_gtest/test_io.cc | 96 +- .../nss/external_tests/ssl_gtest/test_io.h | 31 +- .../nss/external_tests/ssl_gtest/tls_agent.cc | 208 +++ .../nss/external_tests/ssl_gtest/tls_agent.h | 170 ++ .../external_tests/ssl_gtest/tls_connect.cc | 170 ++ .../external_tests/ssl_gtest/tls_connect.h | 79 + .../external_tests/ssl_gtest/tls_filter.cc | 226 +++ .../nss/external_tests/ssl_gtest/tls_filter.h | 113 ++ .../external_tests/ssl_gtest/tls_parser.cc | 72 +- .../nss/external_tests/ssl_gtest/tls_parser.h | 88 +- security/nss/lib/nss/nss.def | 1 + security/nss/lib/nss/nss.h | 4 +- security/nss/lib/pk11wrap/pk11cert.c | 22 + security/nss/lib/pk11wrap/pk11pub.h | 15 + security/nss/lib/pkcs12/p12local.c | 3 +- security/nss/lib/pki/tdcache.c | 6 +- security/nss/lib/softoken/softkver.h | 4 +- security/nss/lib/ssl/sslsock.c | 4 +- security/nss/lib/util/nssutil.h | 4 +- security/patches/reverted-bug-1132496.patch | 1384 +++++++++++++++++ 25 files changed, 2730 insertions(+), 706 deletions(-) create mode 100644 security/nss/external_tests/ssl_gtest/tls_agent.cc create mode 100644 security/nss/external_tests/ssl_gtest/tls_agent.h create mode 100644 security/nss/external_tests/ssl_gtest/tls_connect.cc create mode 100644 security/nss/external_tests/ssl_gtest/tls_connect.h create mode 100644 security/nss/external_tests/ssl_gtest/tls_filter.cc create mode 100644 security/nss/external_tests/ssl_gtest/tls_filter.h create mode 100644 security/patches/reverted-bug-1132496.patch diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index 665e74121f09..bd6b016fe0d9 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_18_BETA7 +NSS_3_18_RC0 diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 5182f75552c8..590d1bfaeee3 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,3 +10,4 @@ */ #error "Do not include this header file." + diff --git a/security/nss/external_tests/ssl_gtest/databuffer.h b/security/nss/external_tests/ssl_gtest/databuffer.h index 316aeb2a24de..c3d3bb9be949 100644 --- a/security/nss/external_tests/ssl_gtest/databuffer.h +++ b/security/nss/external_tests/ssl_gtest/databuffer.h @@ -7,33 +7,142 @@ #ifndef databuffer_h__ #define databuffer_h__ +#include +#include +#include +#include +#include + +namespace nss_test { + class DataBuffer { public: DataBuffer() : data_(nullptr), len_(0) {} DataBuffer(const uint8_t *data, size_t len) : data_(nullptr), len_(0) { Assign(data, len); } + explicit DataBuffer(const DataBuffer& other) : data_(nullptr), len_(0) { + Assign(other.data(), other.len()); + } ~DataBuffer() { delete[] data_; } - void Assign(const uint8_t *data, size_t len) { - Allocate(len); - memcpy(static_cast(data_), static_cast(data), len); + DataBuffer& operator=(const DataBuffer& other) { + if (&other != this) { + Assign(other.data(), other.len()); + } + return *this; } void Allocate(size_t len) { delete[] data_; - data_ = new unsigned char[len ? len : 1]; // Don't depend on new [0]. + data_ = new uint8_t[len ? len : 1]; // Don't depend on new [0]. len_ = len; } + void Truncate(size_t len) { + len_ = std::min(len_, len); + } + + void Assign(const uint8_t* data, size_t len) { + Allocate(len); + memcpy(static_cast(data_), static_cast(data), len); + } + + // Write will do a new allocation and expand the size of the buffer if needed. + void Write(size_t index, const uint8_t* val, size_t count) { + if (index + count > len_) { + size_t newlen = index + count; + uint8_t* tmp = new uint8_t[newlen]; // Always > 0. + memcpy(static_cast(tmp), + static_cast(data_), len_); + if (index > len_) { + memset(static_cast(tmp + len_), 0, index - len_); + } + delete[] data_; + data_ = tmp; + len_ = newlen; + } + memcpy(static_cast(data_ + index), + static_cast(val), count); + } + + void Write(size_t index, const DataBuffer& buf) { + Write(index, buf.data(), buf.len()); + } + + // Write an integer, also performing host-to-network order conversion. + void Write(size_t index, uint32_t val, size_t count) { + assert(count <= sizeof(uint32_t)); + uint32_t nvalue = htonl(val); + auto* addr = reinterpret_cast(&nvalue); + Write(index, addr + sizeof(uint32_t) - count, count); + } + + // Starting at |index|, remove |remove| bytes and replace them with the + // contents of |buf|. + void Splice(const DataBuffer& buf, size_t index, size_t remove = 0) { + Splice(buf.data(), buf.len(), index, remove); + } + + void Splice(const uint8_t* ins, size_t ins_len, size_t index, size_t remove = 0) { + uint8_t* old_value = data_; + size_t old_len = len_; + + // The amount of stuff remaining from the tail of the old. + size_t tail_len = old_len - std::min(old_len, index + remove); + // The new length: the head of the old, the new, and the tail of the old. + len_ = index + ins_len + tail_len; + data_ = new uint8_t[len_ ? len_ : 1]; + + // The head of the old. + Write(0, old_value, std::min(old_len, index)); + // Maybe a gap. + if (index > old_len) { + memset(old_value + index, 0, index - old_len); + } + // The new. + Write(index, ins, ins_len); + // The tail of the old. + if (tail_len > 0) { + Write(index + ins_len, + old_value + index + remove, tail_len); + } + + delete[] old_value; + } + + void Append(const DataBuffer& buf) { Splice(buf, len_); } + const uint8_t *data() const { return data_; } - uint8_t *data() { return data_; } + uint8_t* data() { return data_; } size_t len() const { return len_; } - const bool empty() const { return len_ != 0; } + bool empty() const { return len_ == 0; } private: - uint8_t *data_; + uint8_t* data_; size_t len_; }; +#ifdef DEBUG +static const size_t kMaxBufferPrint = 10000; +#else +static const size_t kMaxBufferPrint = 32; +#endif + +inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) { + stream << "[" << buf.len() << "] "; + for (size_t i = 0; i < buf.len(); ++i) { + if (i >= kMaxBufferPrint) { + stream << "..."; + break; + } + stream << std::hex << std::setfill('0') << std::setw(2) + << static_cast(buf.data()[i]); + } + stream << std::dec; + return stream; +} + +} // namespace nss_test + #endif diff --git a/security/nss/external_tests/ssl_gtest/manifest.mn b/security/nss/external_tests/ssl_gtest/manifest.mn index e66f532b4665..ee883e9ac15e 100644 --- a/security/nss/external_tests/ssl_gtest/manifest.mn +++ b/security/nss/external_tests/ssl_gtest/manifest.mn @@ -1,4 +1,4 @@ -# +# # 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/. @@ -10,6 +10,9 @@ CPPSRCS = \ ssl_loopback_unittest.cc \ ssl_gtest.cc \ test_io.cc \ + tls_agent.cc \ + tls_connect.cc \ + tls_filter.cc \ tls_parser.cc \ $(NULL) diff --git a/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc b/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc index 6c01887a7d67..d70e2ceebb4b 100644 --- a/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc +++ b/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc @@ -1,182 +1,24 @@ -#include "prio.h" -#include "prerror.h" -#include "prlog.h" -#include "pk11func.h" +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 "ssl.h" -#include "sslerr.h" #include "sslproto.h" -#include "keyhi.h" #include -#include "test_io.h" #include "tls_parser.h" - -#define GTEST_HAS_RTTI 0 -#include "gtest/gtest.h" -#include "gtest_utils.h" - -extern std::string g_working_dir_path; +#include "tls_filter.h" +#include "tls_connect.h" namespace nss_test { -enum SessionResumptionMode { - RESUME_NONE = 0, - RESUME_SESSIONID = 1, - RESUME_TICKET = 2, - RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET -}; - -#define LOG(a) std::cerr << name_ << ": " << a << std::endl; - -// Inspector that parses out DTLS records and passes -// them on. -class TlsRecordInspector : public Inspector { - public: - virtual void Inspect(DummyPrSocket* adapter, const void* data, size_t len) { - TlsRecordParser parser(static_cast(data), len); - - uint8_t content_type; - std::auto_ptr buf; - while (parser.NextRecord(&content_type, &buf)) { - OnRecord(adapter, content_type, buf->data(), buf->len()); - } - } - - virtual void OnRecord(DummyPrSocket* adapter, uint8_t content_type, - const unsigned char* record, size_t len) = 0; -}; - -// Inspector that injects arbitrary packets based on -// DTLS records of various types. -class TlsInspectorInjector : public TlsRecordInspector { - public: - TlsInspectorInjector(uint8_t packet_type, uint8_t handshake_type, - const unsigned char* data, size_t len) - : packet_type_(packet_type), - handshake_type_(handshake_type), - injected_(false), - data_(data, len) {} - - virtual void OnRecord(DummyPrSocket* adapter, uint8_t content_type, - const unsigned char* data, size_t len) { - // Only inject once. - if (injected_) { - return; - } - - // Check that the first byte is as requested. - if (content_type != packet_type_) { - return; - } - - if (handshake_type_ != 0xff) { - // Check that the packet is plausibly long enough. - if (len < 1) { - return; - } - - // Check that the handshake type is as requested. - if (data[0] != handshake_type_) { - return; - } - } - - adapter->WriteDirect(data_.data(), data_.len()); - } - - private: - uint8_t packet_type_; - uint8_t handshake_type_; - bool injected_; - DataBuffer data_; -}; - -// Make a copy of the first instance of a message. -class TlsInspectorRecordHandshakeMessage : public TlsRecordInspector { - public: - TlsInspectorRecordHandshakeMessage(uint8_t handshake_type) - : handshake_type_(handshake_type), buffer_() {} - - virtual void OnRecord(DummyPrSocket* adapter, uint8_t content_type, - const unsigned char* data, size_t len) { - // Only do this once. - if (buffer_.len()) { - return; - } - - // Check that the first byte is as requested. - if (content_type != kTlsHandshakeType) { - return; - } - - TlsParser parser(data, len); - while (parser.remaining()) { - unsigned char message_type; - // Read the content type. - if (!parser.Read(&message_type)) { - // Malformed. - return; - } - - // Read the record length. - uint32_t length; - if (!parser.Read(&length, 3)) { - // Malformed. - return; - } - - if (adapter->mode() == DGRAM) { - // DTLS - uint32_t message_seq; - if (!parser.Read(&message_seq, 2)) { - return; - } - - uint32_t fragment_offset; - if (!parser.Read(&fragment_offset, 3)) { - return; - } - - uint32_t fragment_length; - if (!parser.Read(&fragment_length, 3)) { - return; - } - - if ((fragment_offset != 0) || (fragment_length != length)) { - // This shouldn't happen because all current tests where we - // are using this code don't fragment. - return; - } - } - - unsigned char* dest = nullptr; - - if (message_type == handshake_type_) { - buffer_.Allocate(length); - dest = buffer_.data(); - } - - if (!parser.Read(dest, length)) { - // Malformed - return; - } - - if (dest) return; - } - } - - const DataBuffer& buffer() { return buffer_; } - - private: - uint8_t handshake_type_; - DataBuffer buffer_; -}; - class TlsServerKeyExchangeECDHE { public: - bool Parse(const unsigned char* data, size_t len) { - TlsParser parser(data, len); + bool Parse(const DataBuffer& buffer) { + TlsParser parser(buffer); uint8_t curve_type; if (!parser.Read(&curve_type)) { @@ -192,408 +34,12 @@ class TlsServerKeyExchangeECDHE { return false; } - uint32_t point_length; - if (!parser.Read(&point_length, 1)) { - return false; - } - - public_key_.Allocate(point_length); - if (!parser.Read(public_key_.data(), point_length)) { - return false; - } - - return true; + return parser.ReadVariable(&public_key_, 1); } DataBuffer public_key_; }; -class TlsAgent : public PollTarget { - public: - enum Role { CLIENT, SERVER }; - enum State { INIT, CONNECTING, CONNECTED, ERROR }; - - TlsAgent(const std::string& name, Role role, Mode mode) - : name_(name), - mode_(mode), - pr_fd_(nullptr), - adapter_(nullptr), - ssl_fd_(nullptr), - role_(role), - state_(INIT) { - memset(&info_, 0, sizeof(info_)); - memset(&csinfo_, 0, sizeof(csinfo_)); - } - - ~TlsAgent() { - if (pr_fd_) { - PR_Close(pr_fd_); - } - - if (ssl_fd_) { - PR_Close(ssl_fd_); - } - } - - bool Init() { - pr_fd_ = DummyPrSocket::CreateFD(name_, mode_); - if (!pr_fd_) return false; - - adapter_ = DummyPrSocket::GetAdapter(pr_fd_); - if (!adapter_) return false; - - return true; - } - - void SetPeer(TlsAgent* peer) { adapter_->SetPeer(peer->adapter_); } - - void SetInspector(Inspector* inspector) { adapter_->SetInspector(inspector); } - - void StartConnect() { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv; - rv = SSL_ResetHandshake(ssl_fd_, role_ == SERVER ? PR_TRUE : PR_FALSE); - ASSERT_EQ(SECSuccess, rv); - SetState(CONNECTING); - } - - void EnableSomeECDHECiphers() { - ASSERT_TRUE(EnsureTlsSetup()); - - const uint32_t EnabledCiphers[] = {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}; - - for (size_t i = 0; i < PR_ARRAY_SIZE(EnabledCiphers); ++i) { - SECStatus rv = SSL_CipherPrefSet(ssl_fd_, EnabledCiphers[i], PR_TRUE); - ASSERT_EQ(SECSuccess, rv); - } - } - - bool EnsureTlsSetup() { - // Don't set up twice - if (ssl_fd_) return true; - - if (adapter_->mode() == STREAM) { - ssl_fd_ = SSL_ImportFD(nullptr, pr_fd_); - } else { - ssl_fd_ = DTLS_ImportFD(nullptr, pr_fd_); - } - - EXPECT_NE(nullptr, ssl_fd_); - if (!ssl_fd_) return false; - pr_fd_ = nullptr; - - if (role_ == SERVER) { - CERTCertificate* cert = PK11_FindCertFromNickname(name_.c_str(), nullptr); - EXPECT_NE(nullptr, cert); - if (!cert) return false; - - SECKEYPrivateKey* priv = PK11_FindKeyByAnyCert(cert, nullptr); - EXPECT_NE(nullptr, priv); - if (!priv) return false; // Leak cert. - - SECStatus rv = SSL_ConfigSecureServer(ssl_fd_, cert, priv, kt_rsa); - EXPECT_EQ(SECSuccess, rv); - if (rv != SECSuccess) return false; // Leak cert and key. - - SECKEY_DestroyPrivateKey(priv); - CERT_DestroyCertificate(cert); - } else { - SECStatus rv = SSL_SetURL(ssl_fd_, "server"); - EXPECT_EQ(SECSuccess, rv); - if (rv != SECSuccess) return false; - } - - SECStatus rv = SSL_AuthCertificateHook(ssl_fd_, AuthCertificateHook, - reinterpret_cast(this)); - EXPECT_EQ(SECSuccess, rv); - if (rv != SECSuccess) return false; - - return true; - } - - void SetVersionRange(uint16_t minver, uint16_t maxver) { - SSLVersionRange range = {minver, maxver}; - ASSERT_EQ(SECSuccess, SSL_VersionRangeSet(ssl_fd_, &range)); - } - - State state() const { return state_; } - - const char* state_str() const { return state_str(state()); } - - const char* state_str(State state) const { return states[state]; } - - PRFileDesc* ssl_fd() { return ssl_fd_; } - - bool version(uint16_t* version) const { - if (state_ != CONNECTED) return false; - - *version = info_.protocolVersion; - - return true; - } - - bool cipher_suite(int16_t* cipher_suite) const { - if (state_ != CONNECTED) return false; - - *cipher_suite = info_.cipherSuite; - return true; - } - - std::string cipher_suite_name() const { - if (state_ != CONNECTED) return "UNKNOWN"; - - return csinfo_.cipherSuiteName; - } - - void CheckKEAType(SSLKEAType type) const { - ASSERT_EQ(CONNECTED, state_); - ASSERT_EQ(type, csinfo_.keaType); - } - - void CheckVersion(uint16_t version) const { - ASSERT_EQ(CONNECTED, state_); - ASSERT_EQ(version, info_.protocolVersion); - } - - - void Handshake() { - SECStatus rv = SSL_ForceHandshake(ssl_fd_); - if (rv == SECSuccess) { - LOG("Handshake success"); - SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &info_, sizeof(info_)); - ASSERT_EQ(SECSuccess, rv); - - rv = SSL_GetCipherSuiteInfo(info_.cipherSuite, &csinfo_, sizeof(csinfo_)); - ASSERT_EQ(SECSuccess, rv); - - SetState(CONNECTED); - return; - } - - int32_t err = PR_GetError(); - switch (err) { - case PR_WOULD_BLOCK_ERROR: - LOG("Would have blocked"); - // TODO(ekr@rtfm.com): set DTLS timeouts - Poller::Instance()->Wait(READABLE_EVENT, adapter_, this, - &TlsAgent::ReadableCallback); - return; - break; - - // TODO(ekr@rtfm.com): needs special case for DTLS - case SSL_ERROR_RX_MALFORMED_HANDSHAKE: - default: - LOG("Handshake failed with error " << err); - SetState(ERROR); - return; - } - } - - std::vector GetSessionId() { - return std::vector(info_.sessionID, - info_.sessionID + info_.sessionIDLength); - } - - void ConfigureSessionCache(SessionResumptionMode mode) { - ASSERT_TRUE(EnsureTlsSetup()); - - SECStatus rv = SSL_OptionSet(ssl_fd_, - SSL_NO_CACHE, - mode & RESUME_SESSIONID ? - PR_FALSE : PR_TRUE); - ASSERT_EQ(SECSuccess, rv); - - rv = SSL_OptionSet(ssl_fd_, - SSL_ENABLE_SESSION_TICKETS, - mode & RESUME_TICKET ? - PR_TRUE : PR_FALSE); - ASSERT_EQ(SECSuccess, rv); - } - - private: - const static char* states[]; - - void SetState(State state) { - if (state_ == state) return; - - LOG("Changing state from " << state_str(state_) << " to " - << state_str(state)); - state_ = state; - } - - // Dummy auth certificate hook. - static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, - PRBool checksig, PRBool isServer) { - return SECSuccess; - } - - static void ReadableCallback(PollTarget* self, Event event) { - TlsAgent* agent = static_cast(self); - agent->ReadableCallback_int(event); - } - - void ReadableCallback_int(Event event) { - LOG("Readable"); - Handshake(); - } - - const std::string name_; - Mode mode_; - PRFileDesc* pr_fd_; - DummyPrSocket* adapter_; - PRFileDesc* ssl_fd_; - Role role_; - State state_; - SSLChannelInfo info_; - SSLCipherSuiteInfo csinfo_; -}; - -const char* TlsAgent::states[] = {"INIT", "CONNECTING", "CONNECTED", "ERROR"}; - -class TlsConnectTestBase : public ::testing::Test { - public: - TlsConnectTestBase(Mode mode) - : mode_(mode), - client_(new TlsAgent("client", TlsAgent::CLIENT, mode_)), - server_(new TlsAgent("server", TlsAgent::SERVER, mode_)) {} - - ~TlsConnectTestBase() { - delete client_; - delete server_; - } - - void SetUp() { - // Configure a fresh session cache. - SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str()); - - // Clear statistics. - SSL3Statistics* stats = SSL_GetStatistics(); - memset(stats, 0, sizeof(*stats)); - - Init(); - } - - void TearDown() { - client_ = nullptr; - server_ = nullptr; - - SSL_ClearSessionCache(); - SSL_ShutdownServerSessionIDCache(); - } - - void Init() { - ASSERT_TRUE(client_->Init()); - ASSERT_TRUE(server_->Init()); - - client_->SetPeer(server_); - server_->SetPeer(client_); - } - - void Reset() { - delete client_; - delete server_; - - client_ = new TlsAgent("client", TlsAgent::CLIENT, mode_); - server_ = new TlsAgent("server", TlsAgent::SERVER, mode_); - - Init(); - } - - void EnsureTlsSetup() { - ASSERT_TRUE(client_->EnsureTlsSetup()); - ASSERT_TRUE(server_->EnsureTlsSetup()); - } - - void Connect() { - server_->StartConnect(); // Server - client_->StartConnect(); // Client - client_->Handshake(); - server_->Handshake(); - - ASSERT_TRUE_WAIT(client_->state() != TlsAgent::CONNECTING && - server_->state() != TlsAgent::CONNECTING, - 5000); - ASSERT_EQ(TlsAgent::CONNECTED, server_->state()); - - int16_t cipher_suite1, cipher_suite2; - bool ret = client_->cipher_suite(&cipher_suite1); - ASSERT_TRUE(ret); - ret = server_->cipher_suite(&cipher_suite2); - ASSERT_TRUE(ret); - ASSERT_EQ(cipher_suite1, cipher_suite2); - - std::cerr << "Connected with cipher suite " << client_->cipher_suite_name() - << std::endl; - - // Check and store session ids. - std::vector sid_c1 = client_->GetSessionId(); - ASSERT_EQ(32, sid_c1.size()); - std::vector sid_s1 = server_->GetSessionId(); - ASSERT_EQ(32, sid_s1.size()); - ASSERT_EQ(sid_c1, sid_s1); - session_ids_.push_back(sid_c1); - } - - void EnableSomeECDHECiphers() { - client_->EnableSomeECDHECiphers(); - server_->EnableSomeECDHECiphers(); - } - - void ConfigureSessionCache(SessionResumptionMode client, - SessionResumptionMode server) { - client_->ConfigureSessionCache(client); - server_->ConfigureSessionCache(server); - } - - void CheckResumption(SessionResumptionMode expected) { - ASSERT_NE(RESUME_BOTH, expected); - - int resume_ct = expected != 0; - int stateless_ct = (expected & RESUME_TICKET) ? 1 : 0; - - SSL3Statistics* stats = SSL_GetStatistics(); - ASSERT_EQ(resume_ct, stats->hch_sid_cache_hits); - ASSERT_EQ(resume_ct, stats->hsh_sid_cache_hits); - - ASSERT_EQ(stateless_ct, stats->hch_sid_stateless_resumes); - ASSERT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes); - - if (resume_ct) { - // Check that the last two session ids match. - ASSERT_GE(2, session_ids_.size()); - ASSERT_EQ(session_ids_[session_ids_.size()-1], - session_ids_[session_ids_.size()-2]); - } - } - - protected: - Mode mode_; - TlsAgent* client_; - TlsAgent* server_; - std::vector> session_ids_; -}; - -class TlsConnectTest : public TlsConnectTestBase { - public: - TlsConnectTest() : TlsConnectTestBase(STREAM) {} -}; - -class DtlsConnectTest : public TlsConnectTestBase { - public: - DtlsConnectTest() : TlsConnectTestBase(DGRAM) {} -}; - -class TlsConnectGeneric : public TlsConnectTestBase, - public ::testing::WithParamInterface { - public: - TlsConnectGeneric() - : TlsConnectTestBase((GetParam() == "TLS") ? STREAM : DGRAM) { - std::cerr << "Variant: " << GetParam() << std::endl; - } -}; - TEST_P(TlsConnectGeneric, SetupOnly) {} TEST_P(TlsConnectGeneric, Connect) { @@ -729,6 +175,19 @@ TEST_P(TlsConnectGeneric, ConnectTLS_1_2_Only) { client_->CheckVersion(SSL_LIBRARY_VERSION_TLS_1_2); } +TEST_P(TlsConnectGeneric, ConnectAlpn) { + EnableAlpn(); + Connect(); + client_->CheckAlpn(SSL_NEXT_PROTO_SELECTED, "a"); + server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, "a"); +} + +TEST_F(DtlsConnectTest, ConnectSrtp) { + EnableSrtp(); + Connect(); + CheckSrtp(); +} + TEST_F(TlsConnectTest, ConnectECDHE) { EnableSomeECDHECiphers(); Connect(); @@ -739,24 +198,24 @@ TEST_F(TlsConnectTest, ConnectECDHETwiceReuseKey) { EnableSomeECDHECiphers(); TlsInspectorRecordHandshakeMessage* i1 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); - server_->SetInspector(i1); + server_->SetPacketFilter(i1); Connect(); client_->CheckKEAType(ssl_kea_ecdh); TlsServerKeyExchangeECDHE dhe1; - ASSERT_TRUE(dhe1.Parse(i1->buffer().data(), i1->buffer().len())); + ASSERT_TRUE(dhe1.Parse(i1->buffer())); // Restart Reset(); TlsInspectorRecordHandshakeMessage* i2 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); - server_->SetInspector(i2); + server_->SetPacketFilter(i2); EnableSomeECDHECiphers(); ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); client_->CheckKEAType(ssl_kea_ecdh); TlsServerKeyExchangeECDHE dhe2; - ASSERT_TRUE(dhe2.Parse(i2->buffer().data(), i2->buffer().len())); + ASSERT_TRUE(dhe2.Parse(i2->buffer())); // Make sure they are the same. ASSERT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len()); @@ -771,11 +230,11 @@ TEST_F(TlsConnectTest, ConnectECDHETwiceNewKey) { ASSERT_EQ(SECSuccess, rv); TlsInspectorRecordHandshakeMessage* i1 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); - server_->SetInspector(i1); + server_->SetPacketFilter(i1); Connect(); client_->CheckKEAType(ssl_kea_ecdh); TlsServerKeyExchangeECDHE dhe1; - ASSERT_TRUE(dhe1.Parse(i1->buffer().data(), i1->buffer().len())); + ASSERT_TRUE(dhe1.Parse(i1->buffer())); // Restart Reset(); @@ -784,13 +243,13 @@ TEST_F(TlsConnectTest, ConnectECDHETwiceNewKey) { ASSERT_EQ(SECSuccess, rv); TlsInspectorRecordHandshakeMessage* i2 = new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange); - server_->SetInspector(i2); + server_->SetPacketFilter(i2); ConfigureSessionCache(RESUME_NONE, RESUME_NONE); Connect(); client_->CheckKEAType(ssl_kea_ecdh); TlsServerKeyExchangeECDHE dhe2; - ASSERT_TRUE(dhe2.Parse(i2->buffer().data(), i2->buffer().len())); + ASSERT_TRUE(dhe2.Parse(i2->buffer())); // Make sure they are different. ASSERT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) && diff --git a/security/nss/external_tests/ssl_gtest/test_io.cc b/security/nss/external_tests/ssl_gtest/test_io.cc index 701647831f98..2bfd091789ce 100644 --- a/security/nss/external_tests/ssl_gtest/test_io.cc +++ b/security/nss/external_tests/ssl_gtest/test_io.cc @@ -4,42 +4,45 @@ * 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 +#include "test_io.h" +#include +#include #include #include #include "prerror.h" -#include "prio.h" #include "prlog.h" #include "prthread.h" -#include "test_io.h" +#include "databuffer.h" namespace nss_test { static PRDescIdentity test_fd_identity = PR_INVALID_IO_LAYER; -#define UNIMPLEMENTED() \ - fprintf(stderr, "Call to unimplemented function %s\n", __FUNCTION__); \ - PR_ASSERT(PR_FALSE); \ +#define UNIMPLEMENTED() \ + std::cerr << "Call to unimplemented function " \ + << __FUNCTION__ << std::endl; \ + PR_ASSERT(PR_FALSE); \ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0) #define LOG(a) std::cerr << name_ << ": " << a << std::endl; -struct Packet { - Packet() : data_(nullptr), len_(0), offset_(0) {} +class Packet : public DataBuffer { + public: + Packet(const DataBuffer& buf) : DataBuffer(buf), offset_(0) {} - void Assign(const void *data, int32_t len) { - data_ = new uint8_t[len]; - memcpy(data_, data, len); - len_ = len; + void Advance(size_t delta) { + PR_ASSERT(offset_ + delta <= len()); + offset_ = std::min(len(), offset_ + delta); } - ~Packet() { delete data_; } - uint8_t *data_; - int32_t len_; - int32_t offset_; + size_t offset() const { return offset_; } + size_t remaining() const { return len() - offset_; } + + private: + size_t offset_; }; // Implementation of NSPR methods @@ -246,6 +249,16 @@ static int32_t DummyReserved(PRFileDesc *f) { return -1; } +DummyPrSocket::~DummyPrSocket() { + delete filter_; + while (!input_.empty()) + { + Packet* front = input_.front(); + input_.pop(); + delete front; + } +} + static const struct PRIOMethods DummyMethods = { PR_DESC_LAYERED, DummyClose, DummyRead, DummyWrite, DummyAvailable, DummyAvailable64, @@ -275,9 +288,8 @@ DummyPrSocket *DummyPrSocket::GetAdapter(PRFileDesc *fd) { return reinterpret_cast(fd->secret); } -void DummyPrSocket::PacketReceived(const void *data, int32_t len) { - input_.push(new Packet()); - input_.back()->Assign(data, len); +void DummyPrSocket::PacketReceived(const DataBuffer& packet) { + input_.push(new Packet(packet)); } int32_t DummyPrSocket::Read(void *data, int32_t len) { @@ -295,16 +307,18 @@ int32_t DummyPrSocket::Read(void *data, int32_t len) { } Packet *front = input_.front(); - int32_t to_read = std::min(len, front->len_ - front->offset_); - memcpy(data, front->data_ + front->offset_, to_read); - front->offset_ += to_read; + size_t to_read = std::min(static_cast(len), + front->len() - front->offset()); + memcpy(data, static_cast(front->data() + front->offset()), + to_read); + front->Advance(to_read); - if (front->offset_ == front->len_) { + if (!front->remaining()) { input_.pop(); delete front; } - return to_read; + return static_cast(to_read); } int32_t DummyPrSocket::Recv(void *buf, int32_t buflen) { @@ -314,39 +328,49 @@ int32_t DummyPrSocket::Recv(void *buf, int32_t buflen) { } Packet *front = input_.front(); - if (buflen < front->len_) { + if (buflen < front->len()) { PR_ASSERT(false); PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); return -1; } - int32_t count = front->len_; - memcpy(buf, front->data_, count); + size_t count = front->len(); + memcpy(buf, front->data(), count); input_.pop(); delete front; - return count; + return static_cast(count); } int32_t DummyPrSocket::Write(const void *buf, int32_t length) { - if (inspector_) { - inspector_->Inspect(this, buf, length); + DataBuffer packet(static_cast(buf), + static_cast(length)); + if (filter_) { + DataBuffer filtered; + if (filter_->Filter(packet, &filtered)) { + if (WriteDirect(filtered) != filtered.len()) { + PR_SetError(PR_IO_ERROR, 0); + return -1; + } + LOG("Wrote: " << packet); + // libssl can't handle if this reports something other than the length of + // what was passed in (or less, but we're not doing partial writes). + return packet.len(); + } } - return WriteDirect(buf, length); + return WriteDirect(packet); } -int32_t DummyPrSocket::WriteDirect(const void *buf, int32_t length) { +int32_t DummyPrSocket::WriteDirect(const DataBuffer& packet) { if (!peer_) { PR_SetError(PR_IO_ERROR, 0); return -1; } - LOG("Wrote " << length); - - peer_->PacketReceived(buf, length); - return length; + peer_->PacketReceived(packet); + return static_cast(packet.len()); // ignore truncation } Poller *Poller::instance; diff --git a/security/nss/external_tests/ssl_gtest/test_io.h b/security/nss/external_tests/ssl_gtest/test_io.h index 64cc4fd5a62a..d2424c60ce25 100644 --- a/security/nss/external_tests/ssl_gtest/test_io.h +++ b/security/nss/external_tests/ssl_gtest/test_io.h @@ -13,25 +13,32 @@ #include #include +#include "prio.h" + namespace nss_test { -struct Packet; +class DataBuffer; +class Packet; class DummyPrSocket; // Fwd decl. // Allow us to inspect a packet before it is written. -class Inspector { +class PacketFilter { public: - virtual ~Inspector() {} + virtual ~PacketFilter() {} - virtual void Inspect(DummyPrSocket* adapter, const void* data, - size_t len) = 0; + // The packet filter takes input and has the option of mutating it. + // + // A filter that modifies the data places the modified data in *output and + // returns true. A filter that does not modify data returns false, in which + // case the value in *output is ignored. + virtual bool Filter(const DataBuffer& input, DataBuffer* output) = 0; }; enum Mode { STREAM, DGRAM }; class DummyPrSocket { public: - ~DummyPrSocket() { delete inspector_; } + ~DummyPrSocket(); static PRFileDesc* CreateFD(const std::string& name, Mode mode); // Returns an FD. @@ -39,16 +46,16 @@ class DummyPrSocket { void SetPeer(DummyPrSocket* peer) { peer_ = peer; } - void SetInspector(Inspector* inspector) { inspector_ = inspector; } + void SetPacketFilter(PacketFilter* filter) { filter_ = filter; } - void PacketReceived(const void* data, int32_t len); + void PacketReceived(const DataBuffer& data); int32_t Read(void* data, int32_t len); int32_t Recv(void* buf, int32_t buflen); int32_t Write(const void* buf, int32_t length); - int32_t WriteDirect(const void* buf, int32_t length); + int32_t WriteDirect(const DataBuffer& data); Mode mode() const { return mode_; } - bool readable() { return !input_.empty(); } + bool readable() const { return !input_.empty(); } bool writable() { return true; } private: @@ -57,13 +64,13 @@ class DummyPrSocket { mode_(mode), peer_(nullptr), input_(), - inspector_(nullptr) {} + filter_(nullptr) {} const std::string name_; Mode mode_; DummyPrSocket* peer_; std::queue input_; - Inspector* inspector_; + PacketFilter* filter_; }; // Marker interface. diff --git a/security/nss/external_tests/ssl_gtest/tls_agent.cc b/security/nss/external_tests/ssl_gtest/tls_agent.cc new file mode 100644 index 000000000000..6eeb651f5248 --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/tls_agent.cc @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 "tls_agent.h" + +#include "pk11func.h" +#include "ssl.h" +#include "sslerr.h" +#include "sslproto.h" +#include "keyhi.h" + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" + +namespace nss_test { + +const char* TlsAgent::states[] = {"INIT", "CONNECTING", "CONNECTED", "ERROR"}; + +bool TlsAgent::EnsureTlsSetup() { + // Don't set up twice + if (ssl_fd_) return true; + + if (adapter_->mode() == STREAM) { + ssl_fd_ = SSL_ImportFD(nullptr, pr_fd_); + } else { + ssl_fd_ = DTLS_ImportFD(nullptr, pr_fd_); + } + + EXPECT_NE(nullptr, ssl_fd_); + if (!ssl_fd_) return false; + pr_fd_ = nullptr; + + if (role_ == SERVER) { + CERTCertificate* cert = PK11_FindCertFromNickname(name_.c_str(), nullptr); + EXPECT_NE(nullptr, cert); + if (!cert) return false; + + SECKEYPrivateKey* priv = PK11_FindKeyByAnyCert(cert, nullptr); + EXPECT_NE(nullptr, priv); + if (!priv) return false; // Leak cert. + + SECStatus rv = SSL_ConfigSecureServer(ssl_fd_, cert, priv, kt_rsa); + EXPECT_EQ(SECSuccess, rv); + if (rv != SECSuccess) return false; // Leak cert and key. + + SECKEY_DestroyPrivateKey(priv); + CERT_DestroyCertificate(cert); + + rv = SSL_SNISocketConfigHook(ssl_fd_, SniHook, + reinterpret_cast(this)); + EXPECT_EQ(SECSuccess, rv); // don't abort, just fail + } else { + SECStatus rv = SSL_SetURL(ssl_fd_, "server"); + EXPECT_EQ(SECSuccess, rv); + if (rv != SECSuccess) return false; + } + + SECStatus rv = SSL_AuthCertificateHook(ssl_fd_, AuthCertificateHook, + reinterpret_cast(this)); + EXPECT_EQ(SECSuccess, rv); + if (rv != SECSuccess) return false; + + return true; +} + +void TlsAgent::StartConnect() { + ASSERT_TRUE(EnsureTlsSetup()); + + SECStatus rv; + rv = SSL_ResetHandshake(ssl_fd_, role_ == SERVER ? PR_TRUE : PR_FALSE); + ASSERT_EQ(SECSuccess, rv); + SetState(CONNECTING); +} + +void TlsAgent::EnableSomeECDHECiphers() { + ASSERT_TRUE(EnsureTlsSetup()); + + const uint32_t EnabledCiphers[] = {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}; + + for (size_t i = 0; i < PR_ARRAY_SIZE(EnabledCiphers); ++i) { + SECStatus rv = SSL_CipherPrefSet(ssl_fd_, EnabledCiphers[i], PR_TRUE); + ASSERT_EQ(SECSuccess, rv); + } +} + +void TlsAgent::SetSessionTicketsEnabled(bool en) { + ASSERT_TRUE(EnsureTlsSetup()); + + SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, + en ? PR_TRUE : PR_FALSE); + ASSERT_EQ(SECSuccess, rv); +} + +void TlsAgent::SetSessionCacheEnabled(bool en) { + ASSERT_TRUE(EnsureTlsSetup()); + + SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, + en ? PR_FALSE : PR_TRUE); + ASSERT_EQ(SECSuccess, rv); +} + +void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) { + SSLVersionRange range = {minver, maxver}; + ASSERT_EQ(SECSuccess, SSL_VersionRangeSet(ssl_fd_, &range)); +} + +void TlsAgent::CheckKEAType(SSLKEAType type) const { + ASSERT_EQ(CONNECTED, state_); + ASSERT_EQ(type, csinfo_.keaType); +} + +void TlsAgent::CheckVersion(uint16_t version) const { + ASSERT_EQ(CONNECTED, state_); + ASSERT_EQ(version, info_.protocolVersion); +} + +void TlsAgent::EnableAlpn(const uint8_t* val, size_t len) { + ASSERT_TRUE(EnsureTlsSetup()); + + ASSERT_EQ(SECSuccess, SSL_OptionSet(ssl_fd_, SSL_ENABLE_ALPN, PR_TRUE)); + ASSERT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd_, val, len)); +} + +void TlsAgent::CheckAlpn(SSLNextProtoState expected_state, + const std::string& expected) { + SSLNextProtoState state; + char chosen[10]; + unsigned int chosen_len; + SECStatus rv = SSL_GetNextProto(ssl_fd_, &state, + reinterpret_cast(chosen), + &chosen_len, sizeof(chosen)); + ASSERT_EQ(SECSuccess, rv); + ASSERT_EQ(expected_state, state); + ASSERT_EQ(expected, std::string(chosen, chosen_len)); +} + +void TlsAgent::EnableSrtp() { + ASSERT_TRUE(EnsureTlsSetup()); + const uint16_t ciphers[] = { + SRTP_AES128_CM_HMAC_SHA1_80, SRTP_AES128_CM_HMAC_SHA1_32 + }; + ASSERT_EQ(SECSuccess, SSL_SetSRTPCiphers(ssl_fd_, ciphers, + PR_ARRAY_SIZE(ciphers))); + +} + +void TlsAgent::CheckSrtp() { + uint16_t actual; + ASSERT_EQ(SECSuccess, SSL_GetSRTPCipher(ssl_fd_, &actual)); + ASSERT_EQ(SRTP_AES128_CM_HMAC_SHA1_80, actual); +} + + +void TlsAgent::Handshake() { + SECStatus rv = SSL_ForceHandshake(ssl_fd_); + if (rv == SECSuccess) { + LOG("Handshake success"); + SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &info_, sizeof(info_)); + ASSERT_EQ(SECSuccess, rv); + + rv = SSL_GetCipherSuiteInfo(info_.cipherSuite, &csinfo_, sizeof(csinfo_)); + ASSERT_EQ(SECSuccess, rv); + + SetState(CONNECTED); + return; + } + + int32_t err = PR_GetError(); + switch (err) { + case PR_WOULD_BLOCK_ERROR: + LOG("Would have blocked"); + // TODO(ekr@rtfm.com): set DTLS timeouts + Poller::Instance()->Wait(READABLE_EVENT, adapter_, this, + &TlsAgent::ReadableCallback); + return; + break; + + // TODO(ekr@rtfm.com): needs special case for DTLS + case SSL_ERROR_RX_MALFORMED_HANDSHAKE: + default: + LOG("Handshake failed with error " << err); + SetState(ERROR); + return; + } +} + +void TlsAgent::ConfigureSessionCache(SessionResumptionMode mode) { + ASSERT_TRUE(EnsureTlsSetup()); + + SECStatus rv = SSL_OptionSet(ssl_fd_, + SSL_NO_CACHE, + mode & RESUME_SESSIONID ? + PR_FALSE : PR_TRUE); + ASSERT_EQ(SECSuccess, rv); + + rv = SSL_OptionSet(ssl_fd_, + SSL_ENABLE_SESSION_TICKETS, + mode & RESUME_TICKET ? + PR_TRUE : PR_FALSE); + ASSERT_EQ(SECSuccess, rv); +} + + +} // namespace nss_test diff --git a/security/nss/external_tests/ssl_gtest/tls_agent.h b/security/nss/external_tests/ssl_gtest/tls_agent.h new file mode 100644 index 000000000000..aee835ea7334 --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/tls_agent.h @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 tls_agent_h_ +#define tls_agent_h_ + +#include "prio.h" +#include "ssl.h" + +#include + +#include "test_io.h" + +namespace nss_test { + +#define LOG(msg) std::cerr << name_ << ": " << msg << std::endl + +enum SessionResumptionMode { + RESUME_NONE = 0, + RESUME_SESSIONID = 1, + RESUME_TICKET = 2, + RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET +}; + +class TlsAgent : public PollTarget { + public: + enum Role { CLIENT, SERVER }; + enum State { INIT, CONNECTING, CONNECTED, ERROR }; + + TlsAgent(const std::string& name, Role role, Mode mode) + : name_(name), + mode_(mode), + pr_fd_(nullptr), + adapter_(nullptr), + ssl_fd_(nullptr), + role_(role), + state_(INIT) { + memset(&info_, 0, sizeof(info_)); + memset(&csinfo_, 0, sizeof(csinfo_)); + } + + ~TlsAgent() { + if (pr_fd_) { + PR_Close(pr_fd_); + } + + if (ssl_fd_) { + PR_Close(ssl_fd_); + } + } + + bool Init() { + pr_fd_ = DummyPrSocket::CreateFD(name_, mode_); + if (!pr_fd_) return false; + + adapter_ = DummyPrSocket::GetAdapter(pr_fd_); + if (!adapter_) return false; + + return true; + } + + void SetPeer(TlsAgent* peer) { adapter_->SetPeer(peer->adapter_); } + + void SetPacketFilter(PacketFilter* filter) { + adapter_->SetPacketFilter(filter); + } + + + void StartConnect(); + void CheckKEAType(SSLKEAType type) const; + void CheckVersion(uint16_t version) const; + + void Handshake(); + void EnableSomeECDHECiphers(); + bool EnsureTlsSetup(); + + void ConfigureSessionCache(SessionResumptionMode mode); + void SetSessionTicketsEnabled(bool en); + void SetSessionCacheEnabled(bool en); + void SetVersionRange(uint16_t minver, uint16_t maxver); + void EnableAlpn(const uint8_t* val, size_t len); + void CheckAlpn(SSLNextProtoState expected_state, + const std::string& expected); + void EnableSrtp(); + void CheckSrtp(); + + State state() const { return state_; } + + const char* state_str() const { return state_str(state()); } + + const char* state_str(State state) const { return states[state]; } + + PRFileDesc* ssl_fd() { return ssl_fd_; } + + bool version(uint16_t* version) const { + if (state_ != CONNECTED) return false; + + *version = info_.protocolVersion; + + return true; + } + + bool cipher_suite(int16_t* cipher_suite) const { + if (state_ != CONNECTED) return false; + + *cipher_suite = info_.cipherSuite; + return true; + } + + std::string cipher_suite_name() const { + if (state_ != CONNECTED) return "UNKNOWN"; + + return csinfo_.cipherSuiteName; + } + + std::vector session_id() const { + return std::vector(info_.sessionID, + info_.sessionID + info_.sessionIDLength); + } + + private: + const static char* states[]; + + void SetState(State state) { + if (state_ == state) return; + + LOG("Changing state from " << state_str(state_) << " to " + << state_str(state)); + state_ = state; + } + + // Dummy auth certificate hook. + static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, + PRBool checksig, PRBool isServer) { + return SECSuccess; + } + + static void ReadableCallback(PollTarget* self, Event event) { + TlsAgent* agent = static_cast(self); + agent->ReadableCallback_int(); + } + + void ReadableCallback_int() { + LOG("Readable"); + Handshake(); + } + + static PRInt32 SniHook(PRFileDesc *fd, const SECItem *srvNameArr, + PRUint32 srvNameArrSize, + void *arg) { + return SSL_SNI_CURRENT_CONFIG_IS_USED; + } + + const std::string name_; + Mode mode_; + PRFileDesc* pr_fd_; + DummyPrSocket* adapter_; + PRFileDesc* ssl_fd_; + Role role_; + State state_; + SSLChannelInfo info_; + SSLCipherSuiteInfo csinfo_; +}; + +} // namespace nss_test + +#endif diff --git a/security/nss/external_tests/ssl_gtest/tls_connect.cc b/security/nss/external_tests/ssl_gtest/tls_connect.cc new file mode 100644 index 000000000000..6c6fd1a53d02 --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/tls_connect.cc @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 "tls_connect.h" + +#include + +#include "gtest_utils.h" + +extern std::string g_working_dir_path; + +namespace nss_test { + +TlsConnectTestBase::TlsConnectTestBase(Mode mode) + : mode_(mode), + client_(new TlsAgent("client", TlsAgent::CLIENT, mode_)), + server_(new TlsAgent("server", TlsAgent::SERVER, mode_)) {} + +TlsConnectTestBase::~TlsConnectTestBase() { + delete client_; + delete server_; +} + +void TlsConnectTestBase::SetUp() { + // Configure a fresh session cache. + SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str()); + + // Clear statistics. + SSL3Statistics* stats = SSL_GetStatistics(); + memset(stats, 0, sizeof(*stats)); + + Init(); +} + +void TlsConnectTestBase::TearDown() { + client_ = nullptr; + server_ = nullptr; + + SSL_ClearSessionCache(); + SSL_ShutdownServerSessionIDCache(); +} + +void TlsConnectTestBase::Init() { + ASSERT_TRUE(client_->Init()); + ASSERT_TRUE(server_->Init()); + + client_->SetPeer(server_); + server_->SetPeer(client_); +} + +void TlsConnectTestBase::Reset() { + delete client_; + delete server_; + + client_ = new TlsAgent("client", TlsAgent::CLIENT, mode_); + server_ = new TlsAgent("server", TlsAgent::SERVER, mode_); + + Init(); +} + +void TlsConnectTestBase::EnsureTlsSetup() { + ASSERT_TRUE(client_->EnsureTlsSetup()); + ASSERT_TRUE(server_->EnsureTlsSetup()); +} + +void TlsConnectTestBase::Handshake() { + server_->StartConnect(); + client_->StartConnect(); + client_->Handshake(); + server_->Handshake(); + + ASSERT_TRUE_WAIT(client_->state() != TlsAgent::CONNECTING && + server_->state() != TlsAgent::CONNECTING, + 5000); +} + +void TlsConnectTestBase::Connect() { + Handshake(); + + ASSERT_EQ(TlsAgent::CONNECTED, client_->state()); + ASSERT_EQ(TlsAgent::CONNECTED, server_->state()); + + int16_t cipher_suite1, cipher_suite2; + bool ret = client_->cipher_suite(&cipher_suite1); + ASSERT_TRUE(ret); + ret = server_->cipher_suite(&cipher_suite2); + ASSERT_TRUE(ret); + ASSERT_EQ(cipher_suite1, cipher_suite2); + + std::cerr << "Connected with cipher suite " << client_->cipher_suite_name() + << std::endl; + + // Check and store session ids. + std::vector sid_c1 = client_->session_id(); + ASSERT_EQ(32, sid_c1.size()); + std::vector sid_s1 = server_->session_id(); + ASSERT_EQ(32, sid_s1.size()); + ASSERT_EQ(sid_c1, sid_s1); + session_ids_.push_back(sid_c1); +} + +void TlsConnectTestBase::ConnectExpectFail() { + Handshake(); + + ASSERT_EQ(TlsAgent::ERROR, client_->state()); + ASSERT_EQ(TlsAgent::ERROR, server_->state()); +} + +void TlsConnectTestBase::EnableSomeECDHECiphers() { + client_->EnableSomeECDHECiphers(); + server_->EnableSomeECDHECiphers(); +} + + +void TlsConnectTestBase::ConfigureSessionCache(SessionResumptionMode client, + SessionResumptionMode server) { + client_->ConfigureSessionCache(client); + server_->ConfigureSessionCache(server); +} + +void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) { + ASSERT_NE(RESUME_BOTH, expected); + + int resume_ct = expected ? 1 : 0; + int stateless_ct = (expected & RESUME_TICKET) ? 1 : 0; + + SSL3Statistics* stats = SSL_GetStatistics(); + ASSERT_EQ(resume_ct, stats->hch_sid_cache_hits); + ASSERT_EQ(resume_ct, stats->hsh_sid_cache_hits); + + ASSERT_EQ(stateless_ct, stats->hch_sid_stateless_resumes); + ASSERT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes); + + if (resume_ct) { + // Check that the last two session ids match. + ASSERT_GE(2, session_ids_.size()); + ASSERT_EQ(session_ids_[session_ids_.size()-1], + session_ids_[session_ids_.size()-2]); + } +} + +void TlsConnectTestBase::EnableAlpn() { + // A simple value of "a", "b". Note that the preferred value of "a" is placed + // at the end, because the NSS API follows the now defunct NPN specification, + // which places the preferred (and default) entry at the end of the list. + // NSS will move this final entry to the front when used with ALPN. + static const uint8_t val[] = { 0x01, 0x62, 0x01, 0x61 }; + client_->EnableAlpn(val, sizeof(val)); + server_->EnableAlpn(val, sizeof(val)); +} + +void TlsConnectTestBase::EnableSrtp() { + client_->EnableSrtp(); + server_->EnableSrtp(); +} + +void TlsConnectTestBase::CheckSrtp() { + client_->CheckSrtp(); + server_->CheckSrtp(); +} + +TlsConnectGeneric::TlsConnectGeneric() + : TlsConnectTestBase((GetParam() == "TLS") ? STREAM : DGRAM) { + std::cerr << "Variant: " << GetParam() << std::endl; +} + +} // namespace nss_test diff --git a/security/nss/external_tests/ssl_gtest/tls_connect.h b/security/nss/external_tests/ssl_gtest/tls_connect.h new file mode 100644 index 000000000000..c263fe83f01e --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/tls_connect.h @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 tls_connect_h_ +#define tls_connect_h_ + +#include "sslt.h" + +#include "tls_agent.h" + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" + +namespace nss_test { + +// A generic TLS connection test base. +class TlsConnectTestBase : public ::testing::Test { + public: + TlsConnectTestBase(Mode mode); + virtual ~TlsConnectTestBase(); + + void SetUp(); + void TearDown(); + + // Initialize client and server. + void Init(); + // Re-initialize client and server. + void Reset(); + // Make sure TLS is configured for a connection. + void EnsureTlsSetup(); + + // Run the handshake. + void Handshake(); + // Connect and check that it works. + void Connect(); + // Connect and expect it to fail. + void ConnectExpectFail(); + + void EnableSomeECDHECiphers(); + void ConfigureSessionCache(SessionResumptionMode client, + SessionResumptionMode server); + void CheckResumption(SessionResumptionMode expected); + void EnableAlpn(); + void EnableSrtp(); + void CheckSrtp(); + + protected: + Mode mode_; + TlsAgent* client_; + TlsAgent* server_; + std::vector> session_ids_; +}; + +// A TLS-only test base. +class TlsConnectTest : public TlsConnectTestBase { + public: + TlsConnectTest() : TlsConnectTestBase(STREAM) {} +}; + +// A DTLS-only test base. +class DtlsConnectTest : public TlsConnectTestBase { + public: + DtlsConnectTest() : TlsConnectTestBase(DGRAM) {} +}; + +// A generic test class that can be either STREAM or DGRAM. This is configured +// in ssl_loopback_unittest.cc. All uses of this should use TEST_P(). +class TlsConnectGeneric : public TlsConnectTestBase, + public ::testing::WithParamInterface { + public: + TlsConnectGeneric(); +}; + +} // namespace nss_test + +#endif diff --git a/security/nss/external_tests/ssl_gtest/tls_filter.cc b/security/nss/external_tests/ssl_gtest/tls_filter.cc new file mode 100644 index 000000000000..3cbe9e5ac0e8 --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/tls_filter.cc @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 "tls_filter.h" + +#include + +namespace nss_test { + +bool TlsRecordFilter::Filter(const DataBuffer& input, DataBuffer* output) { + bool changed = false; + size_t output_offset = 0U; + output->Allocate(input.len()); + + TlsParser parser(input); + while (parser.remaining()) { + size_t start = parser.consumed(); + uint8_t content_type; + if (!parser.Read(&content_type)) { + return false; + } + uint32_t version; + if (!parser.Read(&version, 2)) { + return false; + } + + if (IsDtls(version)) { + if (!parser.Skip(8)) { + return false; + } + } + size_t header_len = parser.consumed() - start; + output->Write(output_offset, input.data() + start, header_len); + + DataBuffer record; + if (!parser.ReadVariable(&record, 2)) { + return false; + } + + // Move the offset in the output forward. ApplyFilter() returns the index + // of the end of the record it wrote to the output, so we need to skip + // over the content type and version for the value passed to it. + output_offset = ApplyFilter(content_type, version, record, output, + output_offset + header_len, + &changed); + } + output->Truncate(output_offset); + + // Record how many packets we actually touched. + if (changed) { + ++count_; + } + + return changed; +} + +size_t TlsRecordFilter::ApplyFilter(uint8_t content_type, uint16_t version, + const DataBuffer& record, + DataBuffer* output, + size_t offset, bool* changed) { + const DataBuffer* source = &record; + DataBuffer filtered; + if (FilterRecord(content_type, version, record, &filtered) && + filtered.len() < 0x10000) { + *changed = true; + std::cerr << "record old: " << record << std::endl; + std::cerr << "record old: " << filtered << std::endl; + source = &filtered; + } + + output->Write(offset, source->len(), 2); + output->Write(offset + 2, *source); + return offset + 2 + source->len(); +} + +bool TlsHandshakeFilter::FilterRecord(uint8_t content_type, uint16_t version, + const DataBuffer& input, + DataBuffer* output) { + // Check that the first byte is as requested. + if (content_type != kTlsHandshakeType) { + return false; + } + + bool changed = false; + size_t output_offset = 0U; + output->Allocate(input.len()); // Preallocate a little. + + TlsParser parser(input); + while (parser.remaining()) { + size_t start = parser.consumed(); + uint8_t handshake_type; + if (!parser.Read(&handshake_type)) { + return false; // malformed + } + uint32_t length; + if (!parser.Read(&length, 3)) { + return false; // malformed + } + + if (IsDtls(version) && !CheckDtls(parser, length)) { + return false; + } + + size_t header_len = parser.consumed() - start; + output->Write(output_offset, input.data() + start, header_len); + + DataBuffer handshake; + if (!parser.Read(&handshake, length)) { + return false; + } + + // Move the offset in the output forward. ApplyFilter() returns the index + // of the end of the message it wrote to the output, so we need to identify + // offsets from the start of the message for length and the handshake + // message. + output_offset = ApplyFilter(version, handshake_type, handshake, + output, output_offset + 1, + output_offset + header_len, + &changed); + } + output->Truncate(output_offset); + return changed; +} + +bool TlsHandshakeFilter::CheckDtls(TlsParser& parser, size_t length) { + // Read and check DTLS parameters + if (!parser.Skip(2)) { // sequence number + return false; + } + + uint32_t fragment_offset; + if (!parser.Read(&fragment_offset, 3)) { + return false; + } + + uint32_t fragment_length; + if (!parser.Read(&fragment_length, 3)) { + return false; + } + + // All current tests where we are using this code don't fragment. + return (fragment_offset == 0 && fragment_length == length); +} + +size_t TlsHandshakeFilter::ApplyFilter( + uint16_t version, uint8_t handshake_type, const DataBuffer& handshake, + DataBuffer* output, size_t length_offset, size_t value_offset, + bool* changed) { + const DataBuffer* source = &handshake; + DataBuffer filtered; + if (FilterHandshake(version, handshake_type, handshake, &filtered) && + filtered.len() < 0x1000000) { + *changed = true; + std::cerr << "handshake old: " << handshake << std::endl; + std::cerr << "handshake new: " << filtered << std::endl; + source = &filtered; + } + + // Back up and overwrite the (two) length field(s): the handshake message + // length and the DTLS fragment length. + output->Write(length_offset, source->len(), 3); + if (IsDtls(version)) { + output->Write(length_offset + 8, source->len(), 3); + } + output->Write(value_offset, *source); + return value_offset + source->len(); +} + +bool TlsInspectorRecordHandshakeMessage::FilterHandshake( + uint16_t version, uint8_t handshake_type, + const DataBuffer& input, DataBuffer* output) { + // Only do this once. + if (buffer_.len()) { + return false; + } + + if (handshake_type == handshake_type_) { + buffer_ = input; + } + return false; +} + +bool TlsAlertRecorder::FilterRecord(uint8_t content_type, uint16_t version, + const DataBuffer& input, DataBuffer* output) { + if (level_ == kTlsAlertFatal) { // already fatal + return false; + } + if (content_type != kTlsAlertType) { + return false; + } + + TlsParser parser(input); + uint8_t lvl; + if (!parser.Read(&lvl)) { + return false; + } + if (lvl == kTlsAlertWarning) { // not strong enough + return false; + } + level_ = lvl; + (void)parser.Read(&description_); + return false; +} + +ChainedPacketFilter::~ChainedPacketFilter() { + for (auto it = filters_.begin(); it != filters_.end(); ++it) { + delete *it; + } +} + +bool ChainedPacketFilter::Filter(const DataBuffer& input, DataBuffer* output) { + DataBuffer in(input); + bool changed = false; + for (auto it = filters_.begin(); it != filters_.end(); ++it) { + if ((*it)->Filter(in, output)) { + in = *output; + changed = true; + } + } + return changed; +} + +} // namespace nss_test diff --git a/security/nss/external_tests/ssl_gtest/tls_filter.h b/security/nss/external_tests/ssl_gtest/tls_filter.h new file mode 100644 index 000000000000..7ebd2c48220d --- /dev/null +++ b/security/nss/external_tests/ssl_gtest/tls_filter.h @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 tls_filter_h_ +#define tls_filter_h_ + +#include +#include + +#include "test_io.h" +#include "tls_parser.h" + +namespace nss_test { + +// Abstract filter that operates on entire (D)TLS records. +class TlsRecordFilter : public PacketFilter { + public: + TlsRecordFilter() : count_(0) {} + + virtual bool Filter(const DataBuffer& input, DataBuffer* output); + + // Report how many packets were altered by the filter. + size_t filtered_packets() const { return count_; } + + protected: + virtual bool FilterRecord(uint8_t content_type, uint16_t version, + const DataBuffer& data, DataBuffer* changed) = 0; + private: + size_t ApplyFilter(uint8_t content_type, uint16_t version, + const DataBuffer& record, DataBuffer* output, + size_t offset, bool* changed); + + size_t count_; +}; + +// Abstract filter that operates on handshake messages rather than records. +// This assumes that the handshake messages are written in a block as entire +// records and that they don't span records or anything crazy like that. +class TlsHandshakeFilter : public TlsRecordFilter { + public: + TlsHandshakeFilter() {} + + protected: + virtual bool FilterRecord(uint8_t content_type, uint16_t version, + const DataBuffer& input, DataBuffer* output); + virtual bool FilterHandshake(uint16_t version, uint8_t handshake_type, + const DataBuffer& input, DataBuffer* output) = 0; + + private: + bool CheckDtls(TlsParser& parser, size_t length); + size_t ApplyFilter(uint16_t version, uint8_t handshake_type, + const DataBuffer& record, DataBuffer* output, + size_t length_offset, size_t value_offset, bool* changed); +}; + +// Make a copy of the first instance of a handshake message. +class TlsInspectorRecordHandshakeMessage : public TlsHandshakeFilter { + public: + TlsInspectorRecordHandshakeMessage(uint8_t handshake_type) + : handshake_type_(handshake_type), buffer_() {} + + virtual bool FilterHandshake(uint16_t version, uint8_t handshake_type, + const DataBuffer& input, DataBuffer* output); + + const DataBuffer& buffer() const { return buffer_; } + + private: + uint8_t handshake_type_; + DataBuffer buffer_; +}; + +// Records an alert. If an alert has already been recorded, it won't save the +// new alert unless the old alert is a warning and the new one is fatal. +class TlsAlertRecorder : public TlsRecordFilter { + public: + TlsAlertRecorder() : level_(255), description_(255) {} + + virtual bool FilterRecord(uint8_t content_type, uint16_t version, + const DataBuffer& input, DataBuffer* output); + + uint8_t level() const { return level_; } + uint8_t description() const { return description_; } + + private: + uint8_t level_; + uint8_t description_; +}; + +// Runs multiple packet filters in series. +class ChainedPacketFilter : public PacketFilter { + public: + ChainedPacketFilter() {} + ChainedPacketFilter(const std::vector filters) + : filters_(filters.begin(), filters.end()) {} + virtual ~ChainedPacketFilter(); + + virtual bool Filter(const DataBuffer& input, DataBuffer* output); + + // Takes ownership of the filter. + void Add(PacketFilter* filter) { + filters_.push_back(filter); + } + + private: + std::vector filters_; +}; + +} // namespace nss_test + +#endif diff --git a/security/nss/external_tests/ssl_gtest/tls_parser.cc b/security/nss/external_tests/ssl_gtest/tls_parser.cc index cbd4c02391f7..1d56fffbff3e 100644 --- a/security/nss/external_tests/ssl_gtest/tls_parser.cc +++ b/security/nss/external_tests/ssl_gtest/tls_parser.cc @@ -6,13 +6,9 @@ #include "tls_parser.h" -// Process DTLS Records -#define CHECK_LENGTH(expected) \ - do { \ - if (remaining() < expected) return false; \ - } while (0) +namespace nss_test { -bool TlsParser::Read(unsigned char* val) { +bool TlsParser::Read(uint8_t* val) { if (remaining() < 1) { return false; } @@ -21,37 +17,55 @@ bool TlsParser::Read(unsigned char* val) { return true; } -bool TlsParser::Read(unsigned char* val, size_t len) { +bool TlsParser::Read(uint32_t* val, size_t size) { + if (size > sizeof(uint32_t)) { + return false; + } + + uint32_t v = 0; + for (size_t i = 0; i < size; ++i) { + uint8_t tmp; + if (!Read(&tmp)) { + return false; + } + + v = (v << 8) | tmp; + } + + *val = v; + return true; +} + +bool TlsParser::Read(DataBuffer* val, size_t len) { if (remaining() < len) { return false; } - if (val) { - memcpy(val, ptr(), len); - } + val->Assign(ptr(), len); consume(len); - return true; } -bool TlsRecordParser::NextRecord(uint8_t* ct, - std::auto_ptr* buffer) { - if (!remaining()) return false; - - CHECK_LENGTH(5U); - const uint8_t* ctp = reinterpret_cast(ptr()); - consume(3); // ct + version - - const uint16_t* tmp = reinterpret_cast(ptr()); - size_t length = ntohs(*tmp); - consume(2); - - CHECK_LENGTH(length); - DataBuffer* db = new DataBuffer(ptr(), length); - consume(length); - - *ct = *ctp; - buffer->reset(db); +bool TlsParser::ReadVariable(DataBuffer* val, size_t len_size) { + uint32_t len; + if (!Read(&len, len_size)) { + return false; + } + return Read(val, len); +} +bool TlsParser::Skip(size_t len) { + if (len > remaining()) { return false; } + consume(len); return true; } + +bool TlsParser::SkipVariable(size_t len_size) { + uint32_t len; + if (!Read(&len, len_size)) { + return false; + } + return Skip(len); +} + +} // namespace nss_test diff --git a/security/nss/external_tests/ssl_gtest/tls_parser.h b/security/nss/external_tests/ssl_gtest/tls_parser.h index 0276501f0fb7..9ac4bdabea03 100644 --- a/security/nss/external_tests/ssl_gtest/tls_parser.h +++ b/security/nss/external_tests/ssl_gtest/tls_parser.h @@ -8,17 +8,31 @@ #define tls_parser_h_ #include -#include -#include +#include +#include #include #include "databuffer.h" +namespace nss_test { + const uint8_t kTlsChangeCipherSpecType = 0x14; +const uint8_t kTlsAlertType = 0x15; const uint8_t kTlsHandshakeType = 0x16; +const uint8_t kTlsHandshakeClientHello = 0x01; +const uint8_t kTlsHandshakeServerHello = 0x02; const uint8_t kTlsHandshakeCertificate = 0x0b; const uint8_t kTlsHandshakeServerKeyExchange = 0x0c; +const uint8_t kTlsAlertWarning = 1; +const uint8_t kTlsAlertFatal = 2; + +const uint8_t kTlsAlertHandshakeFailure = 0x28; +const uint8_t kTlsAlertIllegalParameter = 0x2f; +const uint8_t kTlsAlertDecodeError = 0x32; +const uint8_t kTlsAlertUnsupportedExtension = 0x6e; +const uint8_t kTlsAlertNoApplicationProtocol = 0x78; + const uint8_t kTlsFakeChangeCipherSpec[] = { kTlsChangeCipherSpecType, // Type 0xfe, 0xff, // Version @@ -28,56 +42,56 @@ const uint8_t kTlsFakeChangeCipherSpec[] = { 0x01 // Value }; +inline bool IsDtls(uint16_t version) { + return (version & 0x8000) == 0x8000; +} + +inline uint16_t NormalizeTlsVersion(uint16_t version) { + if (version == 0xfeff) { + return 0x0302; // special: DTLS 1.0 == TLS 1.1 + } + if (IsDtls(version)) { + return (version ^ 0xffff) + 0x0201; + } + return version; +} + +inline void WriteVariable(DataBuffer* target, size_t index, + const DataBuffer& buf, size_t len_size) { + target->Write(index, static_cast(buf.len()), len_size); + target->Write(index + len_size, buf.data(), buf.len()); +} + class TlsParser { public: - TlsParser(const unsigned char *data, size_t len) + TlsParser(const uint8_t* data, size_t len) : buffer_(data, len), offset_(0) {} + explicit TlsParser(const DataBuffer& buf) + : buffer_(buf), offset_(0) {} - bool Read(unsigned char *val); - + bool Read(uint8_t* val); // Read an integral type of specified width. - bool Read(uint32_t *val, size_t len) { - if (len > sizeof(uint32_t)) return false; + bool Read(uint32_t* val, size_t size); + // Reads len bytes into dest buffer, overwriting it. + bool Read(DataBuffer* dest, size_t len); + // Reads bytes into dest buffer, overwriting it. The number of bytes is + // determined by reading from len_size bytes from the stream first. + bool ReadVariable(DataBuffer* dest, size_t len_size); - *val = 0; + bool Skip(size_t len); + bool SkipVariable(size_t len_size); - for (size_t i = 0; i < len; ++i) { - unsigned char tmp; - - (*val) <<= 8; - if (!Read(&tmp)) return false; - - *val += tmp; - } - - return true; - } - - bool Read(unsigned char *val, size_t len); + size_t consumed() const { return offset_; } size_t remaining() const { return buffer_.len() - offset_; } private: void consume(size_t len) { offset_ += len; } - const uint8_t *ptr() const { return buffer_.data() + offset_; } + const uint8_t* ptr() const { return buffer_.data() + offset_; } DataBuffer buffer_; size_t offset_; }; -class TlsRecordParser { - public: - TlsRecordParser(const unsigned char *data, size_t len) - : buffer_(data, len), offset_(0) {} - - bool NextRecord(uint8_t *ct, std::auto_ptr *buffer); - - private: - size_t remaining() const { return buffer_.len() - offset_; } - const uint8_t *ptr() const { return buffer_.data() + offset_; } - void consume(size_t len) { offset_ += len; } - - DataBuffer buffer_; - size_t offset_; -}; +} // namespace nss_test #endif diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index 8a3e81693c28..794e932e793c 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1064,6 +1064,7 @@ PK11_PrivDecrypt; ;+}; ;+NSS_3.18 { # NSS 3.18 release ;+ global: +__PK11_SetCertificateNickname; CERT_FindCertURLExtension; SEC_CheckCrlTimes; SEC_GetCrlTimes; diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index c5fd3252598e..963390c2577a 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -33,12 +33,12 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.18" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta" +#define NSS_VERSION "3.18" _NSS_ECC_STRING _NSS_CUSTOMIZED #define NSS_VMAJOR 3 #define NSS_VMINOR 18 #define NSS_VPATCH 0 #define NSS_VBUILD 0 -#define NSS_BETA PR_TRUE +#define NSS_BETA PR_FALSE #ifndef RC_INVOKED diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 3e6a839f3a8e..1bf8a7f50bcb 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -2682,3 +2682,25 @@ PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg) nssCryptokiObjectArray_Destroy(instances); return slotList; } + +/* + * Using __PK11_SetCertificateNickname is *DANGEROUS*. + * + * The API will update the NSS database, but it *will NOT* update the in-memory data. + * As a result, after calling this API, there will be INCONSISTENCY between + * in-memory data and the database. + * + * Use of the API should be limited to short-lived tools, which will exit immediately + * after using this API. + * + * If you ignore this warning, your process is TAINTED and will most likely misbehave. + */ +SECStatus +__PK11_SetCertificateNickname(CERTCertificate *cert, const char *nickname) +{ + /* Can't set nickname of temp cert. */ + if (!cert->slot || cert->pkcs11ID == CK_INVALID_HANDLE) { + return SEC_ERROR_INVALID_ARGS; + } + return PK11_SetObjectNickname(cert->slot, cert->pkcs11ID, nickname); +} diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h index f0bf2c882ada..d4565eb4e005 100644 --- a/security/nss/lib/pk11wrap/pk11pub.h +++ b/security/nss/lib/pk11wrap/pk11pub.h @@ -459,6 +459,21 @@ SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname); +/* + * Using __PK11_SetCertificateNickname is *DANGEROUS*. + * + * The API will update the NSS database, but it *will NOT* update the in-memory data. + * As a result, after calling this API, there will be INCONSISTENCY between + * in-memory data and the database. + * + * Use of the API should be limited to short-lived tools, which will exit immediately + * after using this API. + * + * If you ignore this warning, your process is TAINTED and will most likely misbehave. + */ +SECStatus __PK11_SetCertificateNickname(CERTCertificate *cert, + const char *nickname); + /* size to hold key in bytes */ unsigned int PK11_GetKeyLength(PK11SymKey *key); /* size of actual secret parts of key in bits */ diff --git a/security/nss/lib/pkcs12/p12local.c b/security/nss/lib/pkcs12/p12local.c index 48ac3f58d196..b8aba646279b 100644 --- a/security/nss/lib/pkcs12/p12local.c +++ b/security/nss/lib/pkcs12/p12local.c @@ -928,7 +928,8 @@ sec_pkcs12_convert_item_to_unicode(PLArenaPool *arena, SECItem *dest, return PR_FALSE; } - if((dest->data[dest->len-1] || dest->data[dest->len-2]) && zeroTerm) { + if ((dest->len >= 2) && + (dest->data[dest->len-1] || dest->data[dest->len-2]) && zeroTerm) { if(dest->len + 2 > 3 * src->len) { if(arena) { dest->data = (unsigned char*)PORT_ArenaGrow(arena, diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index bb55027aeafd..7842189ca7e6 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -437,17 +437,21 @@ nssTrustDomain_RemoveTokenCertsFromCache ( dtor.numCerts = 0; dtor.arrSize = arrSize; PZ_Lock(td->cache->lock); - nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&dtor); + nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, &dtor); for (i=0; iobject.numInstances == 0) { nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]); dtor.certs[i] = NULL; /* skip this cert in the second for loop */ + } else { + /* make sure it doesn't disappear on us before we finish */ + nssCertificate_AddRef(dtor.certs[i]); } } PZ_Unlock(td->cache->lock); for (i=0; i.[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.18" SOFTOKEN_ECC_STRING " Beta" +#define SOFTOKEN_VERSION "3.18" SOFTOKEN_ECC_STRING #define SOFTOKEN_VMAJOR 3 #define SOFTOKEN_VMINOR 18 #define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VBUILD 0 -#define SOFTOKEN_BETA PR_TRUE +#define SOFTOKEN_BETA PR_FALSE #endif /* _SOFTKVER_H_ */ diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index dfa7a2c7c2ba..90bc45729c96 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -90,12 +90,12 @@ static sslOptions ssl_defaults = { */ static SSLVersionRange versions_defaults_stream = { SSL_LIBRARY_VERSION_3_0, - SSL_LIBRARY_VERSION_TLS_1_0 + SSL_LIBRARY_VERSION_TLS_1_2 }; static SSLVersionRange versions_defaults_datagram = { SSL_LIBRARY_VERSION_TLS_1_1, - SSL_LIBRARY_VERSION_TLS_1_1 + SSL_LIBRARY_VERSION_TLS_1_2 }; #define VERSIONS_DEFAULTS(variant) \ diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index 03bd6da90265..b9d6384167fd 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -19,12 +19,12 @@ * The format of the version string should be * ".[.[.]][ ]" */ -#define NSSUTIL_VERSION "3.18 Beta" +#define NSSUTIL_VERSION "3.18" #define NSSUTIL_VMAJOR 3 #define NSSUTIL_VMINOR 18 #define NSSUTIL_VPATCH 0 #define NSSUTIL_VBUILD 0 -#define NSSUTIL_BETA PR_TRUE +#define NSSUTIL_BETA PR_FALSE SEC_BEGIN_PROTOS diff --git a/security/patches/reverted-bug-1132496.patch b/security/patches/reverted-bug-1132496.patch new file mode 100644 index 000000000000..4555abe8837d --- /dev/null +++ b/security/patches/reverted-bug-1132496.patch @@ -0,0 +1,1384 @@ + +# HG changeset patch +# User Kai Engert +# Date 1424971034 -3600 +# Node ID 484e72583add151908d4e34ff9b2f811df719f54 +# Parent 483fbe78c2b2707a53185e63ab37d72af4883aa5 +Bug 1132496 - February 2015 batch of root CA changes, r=rrelyea + +diff --git a/lib/ckfw/builtins/certdata.txt b/lib/ckfw/builtins/certdata.txt +--- a/lib/ckfw/builtins/certdata.txt ++++ b/lib/ckfw/builtins/certdata.txt +@@ -182,19 +182,19 @@ CKA_ISSUER MULTILINE_OCTAL + \020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141 + \170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151 + \146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151 + \146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171 + END + CKA_SERIAL_NUMBER MULTILINE_OCTAL + \002\004\065\336\364\317 + END +-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + + # Distrust "Distrust a pb.com certificate that does not comply with the baseline requirements." + # Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US + # Serial Number: 1407252 (0x157914) + # Subject: CN=*.pb.com,OU=Meters,O=Pitney Bowes,L=Danbury,ST=Connecticut,C=US + # Not Valid Before: Mon Feb 01 14:54:04 2010 + # Not Valid After : Tue Sep 30 00:00:00 2014 +@@ -2452,19 +2452,19 @@ CKA_ISSUER MULTILINE_OCTAL + \170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060 + \053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040 + \123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102 + \165\163\151\156\145\163\163\040\103\101\055\061 + END + CKA_SERIAL_NUMBER MULTILINE_OCTAL + \002\001\001 + END +-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + + # + # Certificate "Equifax Secure eBusiness CA 1" + # + # Issuer: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US + # Serial Number: 4 (0x4) + # Subject: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US +@@ -13169,19 +13169,19 @@ CKA_ISSUER MULTILINE_OCTAL + \103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103 + \101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124 + \162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163 + \040\063\040\103\101\040\111\111 + END + CKA_SERIAL_NUMBER MULTILINE_OCTAL + \002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277 + END +-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + + # + # Certificate "TC TrustCenter Universal CA I" + # + # Issuer: CN=TC TrustCenter Universal CA I,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE + # Serial Number:1d:a2:00:01:00:02:ec:b7:60:80:78:8d:b6:06 + # Subject: CN=TC TrustCenter Universal CA I,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE +@@ -30315,8 +30315,1278 @@ END + CKA_SERIAL_NUMBER MULTILINE_OCTAL + \002\020\057\000\156\315\027\160\146\347\137\243\202\012\171\037 + \005\256 + END + CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST + CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "Staat der Nederlanden Root CA - G3" ++# ++# Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL ++# Serial Number: 10003001 (0x98a239) ++# Subject: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL ++# Not Valid Before: Thu Nov 14 11:28:42 2013 ++# Not Valid After : Mon Nov 13 23:00:00 2028 ++# Fingerprint (SHA-256): 3C:4F:B0:B9:5A:B8:B3:00:32:F4:32:B8:6F:53:5F:E1:72:C1:85:D0:FD:39:86:58:37:CF:36:18:7F:A6:F4:28 ++# Fingerprint (SHA1): D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G3" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 ++\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 ++\122\157\157\164\040\103\101\040\055\040\107\063 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 ++\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 ++\122\157\157\164\040\103\101\040\055\040\107\063 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\000\230\242\071 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\005\164\060\202\003\134\240\003\002\001\002\002\004\000 ++\230\242\071\060\015\006\011\052\206\110\206\367\015\001\001\013 ++\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116 ++\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141 ++\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 ++\156\061\053\060\051\006\003\125\004\003\014\042\123\164\141\141 ++\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 ++\156\040\122\157\157\164\040\103\101\040\055\040\107\063\060\036 ++\027\015\061\063\061\061\061\064\061\061\062\070\064\062\132\027 ++\015\062\070\061\061\061\063\062\063\060\060\060\060\132\060\132 ++\061\013\060\011\006\003\125\004\006\023\002\116\114\061\036\060 ++\034\006\003\125\004\012\014\025\123\164\141\141\164\040\144\145 ++\162\040\116\145\144\145\162\154\141\156\144\145\156\061\053\060 ++\051\006\003\125\004\003\014\042\123\164\141\141\164\040\144\145 ++\162\040\116\145\144\145\162\154\141\156\144\145\156\040\122\157 ++\157\164\040\103\101\040\055\040\107\063\060\202\002\042\060\015 ++\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 ++\017\000\060\202\002\012\002\202\002\001\000\276\062\242\124\017 ++\160\373\054\134\131\353\154\304\244\121\350\205\052\263\314\112 ++\064\362\260\137\363\016\307\034\075\123\036\210\010\150\330\157 ++\075\255\302\236\314\202\147\007\047\207\150\161\072\237\165\226 ++\042\106\005\260\355\255\307\133\236\052\336\234\374\072\306\225 ++\247\365\027\147\030\347\057\111\010\014\134\317\346\314\064\355 ++\170\373\120\261\334\153\062\360\242\376\266\074\344\354\132\227 ++\307\077\036\160\010\060\240\334\305\263\155\157\320\202\162\021 ++\253\322\201\150\131\202\027\267\170\222\140\372\314\336\077\204 ++\353\215\070\063\220\012\162\043\372\065\314\046\161\061\321\162 ++\050\222\331\133\043\155\146\265\155\007\102\353\246\063\316\222 ++\333\300\366\154\143\170\315\312\116\075\265\345\122\233\361\276 ++\073\346\124\140\260\146\036\011\253\007\376\124\211\021\102\321 ++\367\044\272\140\170\032\230\367\311\021\375\026\301\065\032\124 ++\165\357\103\323\345\256\116\316\347\173\303\306\116\141\121\113 ++\253\232\105\113\241\037\101\275\110\123\025\161\144\013\206\263 ++\345\056\276\316\244\033\301\051\204\242\265\313\010\043\166\103 ++\042\044\037\027\004\324\156\234\306\374\177\053\146\032\354\212 ++\345\326\317\115\365\143\011\267\025\071\326\173\254\353\343\174 ++\351\116\374\165\102\310\355\130\225\014\006\102\242\234\367\344 ++\160\263\337\162\157\132\067\100\211\330\205\244\327\361\013\336 ++\103\031\324\112\130\054\214\212\071\236\277\204\207\361\026\073 ++\066\014\351\323\264\312\154\031\101\122\011\241\035\260\152\277 ++\202\357\160\121\041\062\334\005\166\214\313\367\144\344\003\120 ++\257\214\221\147\253\305\362\356\130\330\336\276\367\347\061\317 ++\154\311\073\161\301\325\210\265\145\274\300\350\027\027\007\022 ++\265\134\322\253\040\223\264\346\202\203\160\066\305\315\243\215 ++\255\213\354\243\301\103\207\346\103\342\064\276\225\213\065\355 ++\007\071\332\250\035\172\237\066\236\022\260\014\145\022\220\025 ++\140\331\046\100\104\343\126\140\245\020\324\152\074\375\101\334 ++\016\132\107\266\357\227\141\165\117\331\376\307\262\035\324\355 ++\135\111\263\251\152\313\146\204\023\325\134\240\334\337\156\167 ++\006\321\161\165\310\127\157\257\017\167\133\002\003\001\000\001 ++\243\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005 ++\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004 ++\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024 ++\124\255\372\307\222\127\256\312\065\234\056\022\373\344\272\135 ++\040\334\224\127\060\015\006\011\052\206\110\206\367\015\001\001 ++\013\005\000\003\202\002\001\000\060\231\235\005\062\310\136\016 ++\073\230\001\072\212\244\347\007\367\172\370\347\232\337\120\103 ++\123\227\052\075\312\074\107\230\056\341\025\173\361\222\363\141 ++\332\220\045\026\145\300\237\124\135\016\003\073\133\167\002\234 ++\204\266\015\230\137\064\335\073\143\302\303\050\201\302\234\051 ++\056\051\342\310\303\001\362\063\352\052\252\314\011\010\367\145 ++\147\306\315\337\323\266\053\247\275\314\321\016\160\137\270\043 ++\321\313\221\116\012\364\310\172\345\331\143\066\301\324\337\374 ++\042\227\367\140\135\352\051\057\130\262\275\130\275\215\226\117 ++\020\165\277\110\173\075\121\207\241\074\164\042\302\374\007\177 ++\200\334\304\254\376\152\301\160\060\260\351\216\151\342\054\151 ++\201\224\011\272\335\376\115\300\203\214\224\130\300\106\040\257 ++\234\037\002\370\065\125\111\057\106\324\300\360\240\226\002\017 ++\063\305\161\363\236\043\175\224\267\375\072\323\011\203\006\041 ++\375\140\075\256\062\300\322\356\215\246\360\347\264\202\174\012 ++\314\160\311\171\200\370\376\114\367\065\204\031\212\061\373\012 ++\331\327\177\233\360\242\232\153\303\005\112\355\101\140\024\060 ++\321\252\021\102\156\323\043\002\004\013\306\145\335\335\122\167 ++\332\201\153\262\250\372\001\070\271\226\352\052\154\147\227\211 ++\224\236\274\341\124\325\344\152\170\357\112\275\053\232\075\100 ++\176\306\300\165\322\156\373\150\060\354\354\213\235\371\111\065 ++\232\032\054\331\263\225\071\325\036\222\367\246\271\145\057\345 ++\075\155\072\110\114\010\334\344\050\022\050\276\175\065\134\352 ++\340\026\176\023\033\152\327\076\327\236\374\055\165\262\301\024 ++\325\043\003\333\133\157\013\076\170\057\015\336\063\215\026\267 ++\110\347\203\232\201\017\173\301\103\115\125\004\027\070\112\121 ++\325\131\242\211\164\323\237\276\036\113\327\306\155\267\210\044 ++\157\140\221\244\202\205\133\126\101\274\320\104\253\152\023\276 ++\321\054\130\267\022\063\130\262\067\143\334\023\365\224\035\077 ++\100\121\365\117\365\072\355\310\305\353\302\036\035\026\225\172 ++\307\176\102\161\223\156\113\025\267\060\337\252\355\127\205\110 ++\254\035\152\335\071\151\344\341\171\170\276\316\005\277\241\014 ++\367\200\173\041\147\047\060\131 ++END ++ ++# Trust for "Staat der Nederlanden Root CA - G3" ++# Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL ++# Serial Number: 10003001 (0x98a239) ++# Subject: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL ++# Not Valid Before: Thu Nov 14 11:28:42 2013 ++# Not Valid After : Mon Nov 13 23:00:00 2028 ++# Fingerprint (SHA-256): 3C:4F:B0:B9:5A:B8:B3:00:32:F4:32:B8:6F:53:5F:E1:72:C1:85:D0:FD:39:86:58:37:CF:36:18:7F:A6:F4:28 ++# Fingerprint (SHA1): D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G3" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\330\353\153\101\121\222\131\340\363\347\205\000\300\075\266\210 ++\227\311\356\374 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\013\106\147\007\333\020\057\031\214\065\120\140\321\013\364\067 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 ++\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 ++\122\157\157\164\040\103\101\040\055\040\107\063 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\000\230\242\071 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "Staat der Nederlanden EV Root CA" ++# ++# Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL ++# Serial Number: 10000013 (0x98968d) ++# Subject: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL ++# Not Valid Before: Wed Dec 08 11:19:29 2010 ++# Not Valid After : Thu Dec 08 11:10:28 2022 ++# Fingerprint (SHA-256): 4D:24:91:41:4C:FE:95:67:46:EC:4C:EF:A6:CF:6F:72:E2:8A:13:29:43:2F:9D:8A:90:7A:C4:CB:5D:AD:C1:5A ++# Fingerprint (SHA1): 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Staat der Nederlanden EV Root CA" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 ++\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 ++\105\126\040\122\157\157\164\040\103\101 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 ++\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 ++\105\126\040\122\157\157\164\040\103\101 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\000\230\226\215 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\005\160\060\202\003\130\240\003\002\001\002\002\004\000 ++\230\226\215\060\015\006\011\052\206\110\206\367\015\001\001\013 ++\005\000\060\130\061\013\060\011\006\003\125\004\006\023\002\116 ++\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141 ++\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 ++\156\061\051\060\047\006\003\125\004\003\014\040\123\164\141\141 ++\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 ++\156\040\105\126\040\122\157\157\164\040\103\101\060\036\027\015 ++\061\060\061\062\060\070\061\061\061\071\062\071\132\027\015\062 ++\062\061\062\060\070\061\061\061\060\062\070\132\060\130\061\013 ++\060\011\006\003\125\004\006\023\002\116\114\061\036\060\034\006 ++\003\125\004\012\014\025\123\164\141\141\164\040\144\145\162\040 ++\116\145\144\145\162\154\141\156\144\145\156\061\051\060\047\006 ++\003\125\004\003\014\040\123\164\141\141\164\040\144\145\162\040 ++\116\145\144\145\162\154\141\156\144\145\156\040\105\126\040\122 ++\157\157\164\040\103\101\060\202\002\042\060\015\006\011\052\206 ++\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 ++\002\012\002\202\002\001\000\343\307\176\211\371\044\113\072\322 ++\063\203\065\054\151\354\334\011\244\343\121\250\045\053\171\270 ++\010\075\340\221\272\204\205\306\205\244\312\346\311\056\123\244 ++\311\044\036\375\125\146\161\135\054\305\140\150\004\267\331\302 ++\122\046\070\210\244\326\073\100\246\302\315\077\315\230\223\263 ++\124\024\130\226\125\325\120\376\206\255\244\143\177\134\207\366 ++\216\346\047\222\147\027\222\002\003\054\334\326\146\164\355\335 ++\147\377\301\141\215\143\117\017\233\155\027\060\046\357\253\322 ++\037\020\240\371\305\177\026\151\201\003\107\355\036\150\215\162 ++\241\115\262\046\306\272\154\137\155\326\257\321\261\023\216\251 ++\255\363\136\151\165\046\030\076\101\053\041\177\356\213\135\007 ++\006\235\103\304\051\012\053\374\052\076\206\313\074\203\072\371 ++\311\015\332\305\231\342\274\170\101\063\166\341\277\057\135\345 ++\244\230\120\014\025\335\340\372\234\177\070\150\320\262\246\172 ++\247\321\061\275\176\212\130\047\103\263\272\063\221\323\247\230 ++\025\134\232\346\323\017\165\331\374\101\230\227\076\252\045\333 ++\217\222\056\260\173\014\137\361\143\251\067\371\233\165\151\114 ++\050\046\045\332\325\362\022\160\105\125\343\337\163\136\067\365 ++\041\154\220\216\065\132\311\323\043\353\323\300\276\170\254\102 ++\050\130\146\245\106\155\160\002\327\020\371\113\124\374\135\206 ++\112\207\317\177\312\105\254\021\132\265\040\121\215\057\210\107 ++\227\071\300\317\272\300\102\001\100\231\110\041\013\153\247\322 ++\375\226\325\321\276\106\235\111\340\013\246\240\042\116\070\320 ++\301\074\060\274\160\217\054\165\314\320\305\214\121\073\075\224 ++\010\144\046\141\175\271\303\145\217\024\234\041\320\252\375\027 ++\162\003\217\275\233\214\346\136\123\236\271\235\357\202\273\341 ++\274\342\162\101\133\041\224\323\105\067\224\321\337\011\071\135 ++\347\043\252\232\035\312\155\250\012\206\205\212\202\276\102\007 ++\326\362\070\202\163\332\207\133\345\074\323\236\076\247\073\236 ++\364\003\263\371\361\175\023\164\002\377\273\241\345\372\000\171 ++\034\246\146\101\210\134\140\127\246\056\011\304\272\375\232\317 ++\247\037\100\303\273\314\132\012\125\113\073\070\166\121\270\143 ++\213\204\224\026\346\126\363\002\003\001\000\001\243\102\060\100 ++\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 ++\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001 ++\006\060\035\006\003\125\035\016\004\026\004\024\376\253\000\220 ++\230\236\044\374\251\314\032\212\373\047\270\277\060\156\250\073 ++\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 ++\202\002\001\000\317\167\054\156\126\276\116\263\266\204\000\224 ++\253\107\311\015\322\166\307\206\237\035\007\323\266\264\273\010 ++\170\257\151\322\013\111\336\063\305\254\255\302\210\002\175\006 ++\267\065\002\301\140\311\277\304\350\224\336\324\323\251\023\045 ++\132\376\156\242\256\175\005\334\175\363\154\360\176\246\215\356 ++\331\327\316\130\027\350\251\051\256\163\110\207\347\233\312\156 ++\051\241\144\137\031\023\367\256\006\020\377\121\306\233\115\125 ++\045\117\223\231\020\001\123\165\361\023\316\307\246\101\101\322 ++\277\210\245\177\105\374\254\270\245\265\063\014\202\304\373\007 ++\366\152\345\045\204\137\006\312\301\206\071\021\333\130\315\167 ++\073\054\302\114\017\136\232\343\360\253\076\141\033\120\044\302 ++\300\364\361\031\360\021\051\266\245\030\002\233\327\143\114\160 ++\214\107\243\003\103\134\271\135\106\240\015\157\377\131\216\276 ++\335\237\162\303\133\053\337\214\133\316\345\014\106\154\222\262 ++\012\243\114\124\102\030\025\022\030\275\332\374\272\164\156\377 ++\301\266\240\144\330\251\137\125\256\237\134\152\166\226\330\163 ++\147\207\373\115\177\134\356\151\312\163\020\373\212\251\375\236 ++\275\066\070\111\111\207\364\016\024\360\351\207\270\077\247\117 ++\172\132\216\171\324\223\344\273\150\122\204\254\154\351\363\230 ++\160\125\162\062\371\064\253\053\111\265\315\040\142\344\072\172 ++\147\143\253\226\334\155\256\227\354\374\237\166\126\210\056\146 ++\317\133\266\311\244\260\327\005\272\341\047\057\223\273\046\052 ++\242\223\260\033\363\216\276\035\100\243\271\066\217\076\202\032 ++\032\136\210\352\120\370\131\342\203\106\051\013\343\104\134\341 ++\225\266\151\220\232\024\157\227\256\201\317\150\357\231\232\276 ++\265\347\341\177\370\372\023\107\026\114\314\155\010\100\347\213 ++\170\157\120\202\104\120\077\146\006\212\253\103\204\126\112\017 ++\040\055\206\016\365\322\333\322\172\212\113\315\245\350\116\361 ++\136\046\045\001\131\043\240\176\322\366\176\041\127\327\047\274 ++\025\127\114\244\106\301\340\203\036\014\114\115\037\117\006\031 ++\342\371\250\364\072\202\241\262\171\103\171\326\255\157\172\047 ++\220\003\244\352\044\207\077\331\275\331\351\362\137\120\111\034 ++\356\354\327\056 ++END ++ ++# Trust for "Staat der Nederlanden EV Root CA" ++# Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL ++# Serial Number: 10000013 (0x98968d) ++# Subject: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL ++# Not Valid Before: Wed Dec 08 11:19:29 2010 ++# Not Valid After : Thu Dec 08 11:10:28 2022 ++# Fingerprint (SHA-256): 4D:24:91:41:4C:FE:95:67:46:EC:4C:EF:A6:CF:6F:72:E2:8A:13:29:43:2F:9D:8A:90:7A:C4:CB:5D:AD:C1:5A ++# Fingerprint (SHA1): 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Staat der Nederlanden EV Root CA" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\166\342\176\301\117\333\202\301\300\246\165\265\005\276\075\051 ++\264\355\333\273 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\374\006\257\173\350\032\361\232\264\350\322\160\037\300\365\272 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 ++\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 ++\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 ++\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 ++\105\126\040\122\157\157\164\040\103\101 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\000\230\226\215 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "IdenTrust Commercial Root CA 1" ++# ++# Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US ++# Serial Number:0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 ++# Subject: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US ++# Not Valid Before: Thu Jan 16 18:12:23 2014 ++# Not Valid After : Mon Jan 16 18:12:23 2034 ++# Fingerprint (SHA-256): 5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE ++# Fingerprint (SHA1): DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "IdenTrust Commercial Root CA 1" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 ++\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 ++\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 ++\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 ++\141\154\040\122\157\157\164\040\103\101\040\061 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 ++\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 ++\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 ++\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 ++\141\154\040\122\157\157\164\040\103\101\040\061 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\020\012\001\102\200\000\000\001\105\043\310\104\265\000\000 ++\000\002 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\005\140\060\202\003\110\240\003\002\001\002\002\020\012 ++\001\102\200\000\000\001\105\043\310\104\265\000\000\000\002\060 ++\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\112 ++\061\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060 ++\020\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163 ++\164\061\047\060\045\006\003\125\004\003\023\036\111\144\145\156 ++\124\162\165\163\164\040\103\157\155\155\145\162\143\151\141\154 ++\040\122\157\157\164\040\103\101\040\061\060\036\027\015\061\064 ++\060\061\061\066\061\070\061\062\062\063\132\027\015\063\064\060 ++\061\061\066\061\070\061\062\062\063\132\060\112\061\013\060\011 ++\006\003\125\004\006\023\002\125\123\061\022\060\020\006\003\125 ++\004\012\023\011\111\144\145\156\124\162\165\163\164\061\047\060 ++\045\006\003\125\004\003\023\036\111\144\145\156\124\162\165\163 ++\164\040\103\157\155\155\145\162\143\151\141\154\040\122\157\157 ++\164\040\103\101\040\061\060\202\002\042\060\015\006\011\052\206 ++\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 ++\002\012\002\202\002\001\000\247\120\031\336\077\231\075\324\063 ++\106\361\157\121\141\202\262\251\117\217\147\211\135\204\331\123 ++\335\014\050\331\327\360\377\256\225\103\162\231\371\265\135\174 ++\212\301\102\341\061\120\164\321\201\015\174\315\233\041\253\103 ++\342\254\255\136\206\156\363\011\212\037\132\062\275\242\353\224 ++\371\350\134\012\354\377\230\322\257\161\263\264\123\237\116\207 ++\357\222\274\275\354\117\062\060\210\113\027\136\127\304\123\302 ++\366\002\227\215\331\142\053\277\044\037\142\215\337\303\270\051 ++\113\111\170\074\223\140\210\042\374\231\332\066\310\302\242\324 ++\054\124\000\147\065\156\163\277\002\130\360\244\335\345\260\242 ++\046\172\312\340\066\245\031\026\365\375\267\357\256\077\100\365 ++\155\132\004\375\316\064\312\044\334\164\043\033\135\063\023\022 ++\135\304\001\045\366\060\335\002\135\237\340\325\107\275\264\353 ++\033\241\273\111\111\330\237\133\002\363\212\344\044\220\344\142 ++\117\117\301\257\213\016\164\027\250\321\162\210\152\172\001\111 ++\314\264\106\171\306\027\261\332\230\036\007\131\372\165\041\205 ++\145\335\220\126\316\373\253\245\140\235\304\235\371\122\260\213 ++\275\207\371\217\053\043\012\043\166\073\367\063\341\311\000\363 ++\151\371\113\242\340\116\274\176\223\071\204\007\367\104\160\176 ++\376\007\132\345\261\254\321\030\314\362\065\345\111\111\010\312 ++\126\311\075\373\017\030\175\213\073\301\023\302\115\217\311\117 ++\016\067\351\037\241\016\152\337\142\056\313\065\006\121\171\054 ++\310\045\070\364\372\113\247\211\134\234\322\343\015\071\206\112 ++\164\174\325\131\207\302\077\116\014\134\122\364\075\367\122\202 ++\361\352\243\254\375\111\064\032\050\363\101\210\072\023\356\350 ++\336\377\231\035\137\272\313\350\036\362\271\120\140\300\061\323 ++\163\345\357\276\240\355\063\013\164\276\040\040\304\147\154\360 ++\010\003\172\125\200\177\106\116\226\247\364\036\076\341\366\330 ++\011\341\063\144\053\143\327\062\136\237\371\300\173\017\170\157 ++\227\274\223\232\371\234\022\220\170\172\200\207\025\327\162\164 ++\234\125\164\170\261\272\341\156\160\004\272\117\240\272\150\303 ++\173\377\061\360\163\075\075\224\052\261\013\101\016\240\376\115 ++\210\145\153\171\063\264\327\002\003\001\000\001\243\102\060\100 ++\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006 ++\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 ++\377\060\035\006\003\125\035\016\004\026\004\024\355\104\031\300 ++\323\360\006\213\356\244\173\276\102\347\046\124\310\216\066\166 ++\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 ++\202\002\001\000\015\256\220\062\366\246\113\174\104\166\031\141 ++\036\047\050\315\136\124\357\045\274\343\010\220\371\051\327\256 ++\150\010\341\224\000\130\357\056\056\176\123\122\214\266\134\007 ++\352\210\272\231\213\120\224\327\202\200\337\141\011\000\223\255 ++\015\024\346\316\301\362\067\224\170\260\137\234\263\242\163\270 ++\217\005\223\070\315\215\076\260\270\373\300\317\261\362\354\055 ++\055\033\314\354\252\232\263\252\140\202\033\055\073\303\204\075 ++\127\212\226\036\234\165\270\323\060\315\140\010\203\220\323\216 ++\124\361\115\146\300\135\164\003\100\243\356\205\176\302\037\167 ++\234\006\350\301\247\030\135\122\225\355\311\335\045\236\155\372 ++\251\355\243\072\064\320\131\173\332\355\120\363\065\277\355\353 ++\024\115\061\307\140\364\332\361\207\234\342\110\342\306\305\067 ++\373\006\020\372\165\131\146\061\107\051\332\166\232\034\351\202 ++\256\357\232\271\121\367\210\043\232\151\225\142\074\345\125\200 ++\066\327\124\002\377\361\271\135\316\324\043\157\330\105\204\112 ++\133\145\357\211\014\335\024\247\040\313\030\245\045\264\015\371 ++\001\360\242\322\364\000\310\164\216\241\052\110\216\145\333\023 ++\304\342\045\027\175\353\276\207\133\027\040\124\121\223\112\123 ++\003\013\354\135\312\063\355\142\375\105\307\057\133\334\130\240 ++\200\071\346\372\327\376\023\024\246\355\075\224\112\102\164\324 ++\303\167\131\163\315\217\106\276\125\070\357\372\350\221\062\352 ++\227\130\004\042\336\070\303\314\274\155\311\063\072\152\012\151 ++\077\240\310\352\162\217\214\143\206\043\275\155\074\226\236\225 ++\340\111\114\252\242\271\052\033\234\066\201\170\355\303\350\106 ++\342\046\131\104\165\036\331\165\211\121\315\020\204\235\141\140 ++\313\135\371\227\042\115\216\230\346\343\177\366\133\273\256\315 ++\312\112\201\153\136\013\363\121\341\164\053\351\176\047\247\331 ++\231\111\116\370\245\200\333\045\017\034\143\142\212\311\063\147 ++\153\074\020\203\306\255\336\250\315\026\216\215\360\007\067\161 ++\237\362\253\374\101\365\301\213\354\000\067\135\011\345\116\200 ++\357\372\261\134\070\006\245\033\112\341\334\070\055\074\334\253 ++\037\220\032\325\112\234\356\321\160\154\314\356\364\127\370\030 ++\272\204\156\207 ++END ++ ++# Trust for "IdenTrust Commercial Root CA 1" ++# Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US ++# Serial Number:0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 ++# Subject: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US ++# Not Valid Before: Thu Jan 16 18:12:23 2014 ++# Not Valid After : Mon Jan 16 18:12:23 2034 ++# Fingerprint (SHA-256): 5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE ++# Fingerprint (SHA1): DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "IdenTrust Commercial Root CA 1" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\337\161\176\252\112\331\116\311\125\204\231\140\055\110\336\137 ++\274\360\072\045 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\263\076\167\163\165\356\240\323\343\176\111\143\111\131\273\307 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 ++\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 ++\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 ++\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 ++\141\154\040\122\157\157\164\040\103\101\040\061 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\020\012\001\102\200\000\000\001\105\043\310\104\265\000\000 ++\000\002 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "IdenTrust Public Sector Root CA 1" ++# ++# Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US ++# Serial Number:0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 ++# Subject: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US ++# Not Valid Before: Thu Jan 16 17:53:32 2014 ++# Not Valid After : Mon Jan 16 17:53:32 2034 ++# Fingerprint (SHA-256): 30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F ++# Fingerprint (SHA1): BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "IdenTrust Public Sector Root CA 1" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 ++\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 ++\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 ++\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 ++\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 ++\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 ++\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 ++\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 ++\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\020\012\001\102\200\000\000\001\105\043\317\106\174\000\000 ++\000\002 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\005\146\060\202\003\116\240\003\002\001\002\002\020\012 ++\001\102\200\000\000\001\105\043\317\106\174\000\000\000\002\060 ++\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\115 ++\061\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060 ++\020\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163 ++\164\061\052\060\050\006\003\125\004\003\023\041\111\144\145\156 ++\124\162\165\163\164\040\120\165\142\154\151\143\040\123\145\143 ++\164\157\162\040\122\157\157\164\040\103\101\040\061\060\036\027 ++\015\061\064\060\061\061\066\061\067\065\063\063\062\132\027\015 ++\063\064\060\061\061\066\061\067\065\063\063\062\132\060\115\061 ++\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060\020 ++\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163\164 ++\061\052\060\050\006\003\125\004\003\023\041\111\144\145\156\124 ++\162\165\163\164\040\120\165\142\154\151\143\040\123\145\143\164 ++\157\162\040\122\157\157\164\040\103\101\040\061\060\202\002\042 ++\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 ++\202\002\017\000\060\202\002\012\002\202\002\001\000\266\042\224 ++\374\244\110\257\350\107\153\012\373\047\166\344\362\077\212\073 ++\172\112\054\061\052\214\215\260\251\303\061\153\250\167\166\204 ++\046\266\254\201\102\015\010\353\125\130\273\172\370\274\145\175 ++\362\240\155\213\250\107\351\142\166\036\021\356\010\024\321\262 ++\104\026\364\352\320\372\036\057\136\333\313\163\101\256\274\000 ++\260\112\053\100\262\254\341\073\113\302\055\235\344\241\233\354 ++\032\072\036\360\010\263\320\344\044\065\007\237\234\264\311\122 ++\155\333\007\312\217\265\133\360\203\363\117\307\055\245\310\255 ++\313\225\040\244\061\050\127\130\132\344\215\033\232\253\236\015 ++\014\362\012\063\071\042\071\012\227\056\363\123\167\271\104\105 ++\375\204\313\066\040\201\131\055\232\157\155\110\110\141\312\114 ++\337\123\321\257\122\274\104\237\253\057\153\203\162\357\165\200 ++\332\006\063\033\135\310\332\143\306\115\315\254\146\061\315\321 ++\336\076\207\020\066\341\271\244\172\357\140\120\262\313\312\246 ++\126\340\067\257\253\064\023\071\045\350\071\146\344\230\172\252 ++\022\230\234\131\146\206\076\255\361\260\312\076\006\017\173\360 ++\021\113\067\240\104\155\173\313\250\214\161\364\325\265\221\066 ++\314\360\025\306\053\336\121\027\261\227\114\120\075\261\225\131 ++\174\005\175\055\041\325\000\277\001\147\242\136\173\246\134\362 ++\367\042\361\220\015\223\333\252\104\121\146\314\175\166\003\353 ++\152\250\052\070\031\227\166\015\153\212\141\371\274\366\356\166 ++\375\160\053\335\051\074\370\012\036\133\102\034\213\126\057\125 ++\033\034\241\056\265\307\026\346\370\252\074\222\216\151\266\001 ++\301\265\206\235\211\017\013\070\224\124\350\352\334\236\075\045 ++\274\123\046\355\325\253\071\252\305\100\114\124\253\262\264\331 ++\331\370\327\162\333\034\274\155\275\145\137\357\210\065\052\146 ++\057\356\366\263\145\360\063\215\174\230\101\151\106\017\103\034 ++\151\372\233\265\320\141\152\315\312\113\331\114\220\106\253\025 ++\131\241\107\124\051\056\203\050\137\034\302\242\253\162\027\000 ++\006\216\105\354\213\342\063\075\177\332\031\104\344\142\162\303 ++\337\042\306\362\126\324\335\137\225\162\355\155\137\367\110\003 ++\133\375\305\052\240\366\163\043\204\020\033\001\347\002\003\001 ++\000\001\243\102\060\100\060\016\006\003\125\035\017\001\001\377 ++\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377 ++\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026 ++\004\024\343\161\340\236\330\247\102\331\333\161\221\153\224\223 ++\353\303\243\321\024\243\060\015\006\011\052\206\110\206\367\015 ++\001\001\013\005\000\003\202\002\001\000\107\372\335\012\260\021 ++\221\070\255\115\135\367\345\016\227\124\031\202\110\207\124\214 ++\252\144\231\330\132\376\210\001\305\130\245\231\261\043\124\043 ++\267\152\035\040\127\345\001\142\101\027\323\011\333\165\313\156 ++\124\220\165\376\032\237\201\012\302\335\327\367\011\320\133\162 ++\025\344\036\011\152\075\063\363\041\232\346\025\176\255\121\325 ++\015\020\355\175\102\300\217\356\300\232\010\325\101\326\134\016 ++\041\151\156\200\141\016\025\300\270\317\305\111\022\122\314\276 ++\072\314\324\056\070\005\336\065\375\037\157\270\200\150\230\075 ++\115\240\312\100\145\322\163\174\365\213\331\012\225\077\330\077 ++\043\155\032\321\052\044\031\331\205\263\027\357\170\156\251\130 ++\321\043\323\307\023\355\162\045\177\135\261\163\160\320\177\006 ++\227\011\204\051\200\141\035\372\136\377\163\254\240\343\211\270 ++\034\161\025\306\336\061\177\022\334\341\155\233\257\347\350\237 ++\165\170\114\253\106\073\232\316\277\005\030\135\115\025\074\026 ++\232\031\120\004\232\262\232\157\145\213\122\137\074\130\004\050 ++\045\300\146\141\061\176\271\340\165\271\032\250\201\326\162\027 ++\263\305\003\061\065\021\170\170\242\340\351\060\214\177\200\337 ++\130\337\074\272\047\226\342\200\064\155\343\230\323\144\047\254 ++\110\176\050\167\134\306\045\141\045\370\205\014\145\372\304\062 ++\057\245\230\005\344\370\013\147\026\026\306\202\270\062\031\371 ++\371\271\171\334\037\315\353\257\253\016\335\033\333\105\344\172 ++\347\002\342\225\135\374\151\360\123\151\141\225\165\171\013\136 ++\125\346\070\034\224\251\131\063\236\310\161\164\171\177\121\211 ++\266\310\152\270\060\310\152\070\303\156\236\341\067\026\352\005 ++\142\114\133\022\107\355\247\264\263\130\126\307\111\363\177\022 ++\150\011\061\161\360\155\370\116\107\373\326\205\356\305\130\100 ++\031\244\035\247\371\113\103\067\334\150\132\117\317\353\302\144 ++\164\336\264\025\331\364\124\124\032\057\034\327\227\161\124\220 ++\216\331\040\235\123\053\177\253\217\342\352\060\274\120\067\357 ++\361\107\265\175\174\054\004\354\150\235\264\111\104\020\364\162 ++\113\034\144\347\374\346\153\220\335\151\175\151\375\000\126\245 ++\267\254\266\255\267\312\076\001\357\234 ++END ++ ++# Trust for "IdenTrust Public Sector Root CA 1" ++# Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US ++# Serial Number:0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 ++# Subject: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US ++# Not Valid Before: Thu Jan 16 17:53:32 2014 ++# Not Valid After : Mon Jan 16 17:53:32 2034 ++# Fingerprint (SHA-256): 30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F ++# Fingerprint (SHA1): BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "IdenTrust Public Sector Root CA 1" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\272\051\101\140\167\230\077\364\363\357\362\061\005\073\056\352 ++\155\115\105\375 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\067\006\245\260\374\211\235\272\364\153\214\032\144\315\325\272 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 ++\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 ++\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 ++\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 ++\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\020\012\001\102\200\000\000\001\105\043\317\106\174\000\000 ++\000\002 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "S-TRUST Universal Root CA" ++# ++# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE ++# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e ++# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE ++# Not Valid Before: Tue Oct 22 00:00:00 2013 ++# Not Valid After : Thu Oct 21 23:59:59 2038 ++# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31 ++# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "S-TRUST Universal Root CA" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 ++\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 ++\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 ++\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 ++\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 ++\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 ++\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 ++\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 ++\040\122\157\157\164\040\103\101 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 ++\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 ++\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 ++\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 ++\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 ++\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 ++\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 ++\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 ++\040\122\157\157\164\040\103\101 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326 ++\036\036 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\003\330\060\202\002\300\240\003\002\001\002\002\020\140 ++\126\305\113\043\100\133\144\324\355\045\332\331\326\036\036\060 ++\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201 ++\205\061\013\060\011\006\003\125\004\006\023\002\104\105\061\051 ++\060\047\006\003\125\004\012\023\040\104\145\165\164\163\143\150 ++\145\162\040\123\160\141\162\153\141\163\163\145\156\040\126\145 ++\162\154\141\147\040\107\155\142\110\061\047\060\045\006\003\125 ++\004\013\023\036\123\055\124\122\125\123\124\040\103\145\162\164 ++\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143 ++\145\163\061\042\060\040\006\003\125\004\003\023\031\123\055\124 ++\122\125\123\124\040\125\156\151\166\145\162\163\141\154\040\122 ++\157\157\164\040\103\101\060\036\027\015\061\063\061\060\062\062 ++\060\060\060\060\060\060\132\027\015\063\070\061\060\062\061\062 ++\063\065\071\065\071\132\060\201\205\061\013\060\011\006\003\125 ++\004\006\023\002\104\105\061\051\060\047\006\003\125\004\012\023 ++\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153 ++\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142 ++\110\061\047\060\045\006\003\125\004\013\023\036\123\055\124\122 ++\125\123\124\040\103\145\162\164\151\146\151\143\141\164\151\157 ++\156\040\123\145\162\166\151\143\145\163\061\042\060\040\006\003 ++\125\004\003\023\031\123\055\124\122\125\123\124\040\125\156\151 ++\166\145\162\163\141\154\040\122\157\157\164\040\103\101\060\202 ++\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005 ++\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\250 ++\343\013\337\021\067\205\202\232\265\154\146\174\141\077\300\107 ++\032\035\106\343\260\125\144\345\270\202\071\050\007\176\027\377 ++\364\233\212\360\221\201\352\070\077\041\170\154\110\354\153\057 ++\242\323\212\162\262\247\327\331\352\177\264\300\111\153\060\045 ++\211\214\353\267\325\100\141\230\342\334\074\040\222\315\145\112 ++\162\237\032\216\214\372\045\025\277\363\041\203\050\015\213\257 ++\131\021\202\103\134\233\115\045\121\177\130\030\143\140\073\263 ++\265\212\213\130\143\067\110\110\220\104\302\100\335\135\367\103 ++\151\051\230\134\022\145\136\253\220\222\113\146\337\325\165\022 ++\123\124\030\246\336\212\326\273\127\003\071\131\231\030\005\014 ++\371\375\025\306\220\144\106\027\202\327\302\112\101\075\375\000 ++\276\127\162\030\224\167\033\123\132\211\001\366\063\162\016\223 ++\072\334\350\036\375\005\005\326\274\163\340\210\334\253\117\354 ++\265\030\206\117\171\204\016\110\052\146\052\335\062\310\170\145 ++\310\013\235\130\001\005\161\355\201\365\150\027\156\313\015\264 ++\113\330\241\354\256\070\353\034\130\057\241\145\003\064\057\002 ++\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023\001 ++\001\377\004\005\060\003\001\001\377\060\016\006\003\125\035\017 ++\001\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016 ++\004\026\004\024\232\175\327\353\353\177\124\230\105\051\264\040 ++\253\155\013\226\043\031\244\302\060\015\006\011\052\206\110\206 ++\367\015\001\001\013\005\000\003\202\001\001\000\116\226\022\333 ++\176\167\136\222\047\236\041\027\030\202\166\330\077\274\245\011 ++\004\146\210\211\255\333\125\263\063\152\306\145\304\217\115\363 ++\062\066\334\171\004\226\251\167\062\321\227\365\030\153\214\272 ++\355\316\021\320\104\307\222\361\264\104\216\355\210\122\110\236 ++\325\375\131\370\243\036\121\373\001\122\345\137\345\172\335\252 ++\044\117\042\213\335\166\106\366\245\240\017\065\330\312\017\230 ++\271\060\135\040\157\302\201\036\275\275\300\376\025\323\070\052 ++\011\223\230\047\033\223\173\320\053\064\136\150\245\025\117\321 ++\122\303\240\312\240\203\105\035\365\365\267\131\163\135\131\001 ++\217\252\302\107\057\024\161\325\051\343\020\265\107\223\045\314 ++\043\051\332\267\162\330\221\324\354\033\110\212\042\344\301\052 ++\367\072\150\223\237\105\031\156\103\267\314\376\270\221\232\141 ++\032\066\151\143\144\222\050\363\157\141\222\205\023\237\311\007 ++\054\213\127\334\353\236\171\325\302\336\010\325\124\262\127\116 ++\052\062\215\241\342\072\321\020\040\042\071\175\064\105\157\161 ++\073\303\035\374\377\262\117\250\342\366\060\036 ++END ++ ++# Trust for "S-TRUST Universal Root CA" ++# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE ++# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e ++# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE ++# Not Valid Before: Tue Oct 22 00:00:00 2013 ++# Not Valid After : Thu Oct 21 23:59:59 2038 ++# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31 ++# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "S-TRUST Universal Root CA" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\033\075\021\024\352\172\017\225\130\124\101\225\277\153\045\202 ++\253\100\316\232 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\130\366\101\001\256\365\133\121\231\116\134\041\350\117\324\146 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 ++\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 ++\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 ++\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 ++\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 ++\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 ++\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 ++\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 ++\040\122\157\157\164\040\103\101 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326 ++\036\036 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "Entrust Root Certification Authority - G2" ++# ++# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Serial Number: 1246989352 (0x4a538c28) ++# Subject: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Not Valid Before: Tue Jul 07 17:25:54 2009 ++# Not Valid After : Sat Dec 07 17:55:54 2030 ++# Fingerprint (SHA-256): 43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 ++# Fingerprint (SHA1): 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Entrust Root Certification Authority - G2" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 ++\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 ++\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 ++\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 ++\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 ++\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 ++\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 ++\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 ++\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 ++\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 ++\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 ++\062 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 ++\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 ++\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 ++\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 ++\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 ++\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 ++\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 ++\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 ++\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 ++\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 ++\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 ++\062 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\112\123\214\050 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\004\076\060\202\003\046\240\003\002\001\002\002\004\112 ++\123\214\050\060\015\006\011\052\206\110\206\367\015\001\001\013 ++\005\000\060\201\276\061\013\060\011\006\003\125\004\006\023\002 ++\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156\164 ++\162\165\163\164\054\040\111\156\143\056\061\050\060\046\006\003 ++\125\004\013\023\037\123\145\145\040\167\167\167\056\145\156\164 ++\162\165\163\164\056\156\145\164\057\154\145\147\141\154\055\164 ++\145\162\155\163\061\071\060\067\006\003\125\004\013\023\060\050 ++\143\051\040\062\060\060\071\040\105\156\164\162\165\163\164\054 ++\040\111\156\143\056\040\055\040\146\157\162\040\141\165\164\150 ++\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171\061 ++\062\060\060\006\003\125\004\003\023\051\105\156\164\162\165\163 ++\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 ++\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\055 ++\040\107\062\060\036\027\015\060\071\060\067\060\067\061\067\062 ++\065\065\064\132\027\015\063\060\061\062\060\067\061\067\065\065 ++\065\064\132\060\201\276\061\013\060\011\006\003\125\004\006\023 ++\002\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156 ++\164\162\165\163\164\054\040\111\156\143\056\061\050\060\046\006 ++\003\125\004\013\023\037\123\145\145\040\167\167\167\056\145\156 ++\164\162\165\163\164\056\156\145\164\057\154\145\147\141\154\055 ++\164\145\162\155\163\061\071\060\067\006\003\125\004\013\023\060 ++\050\143\051\040\062\060\060\071\040\105\156\164\162\165\163\164 ++\054\040\111\156\143\056\040\055\040\146\157\162\040\141\165\164 ++\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171 ++\061\062\060\060\006\003\125\004\003\023\051\105\156\164\162\165 ++\163\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143 ++\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040 ++\055\040\107\062\060\202\001\042\060\015\006\011\052\206\110\206 ++\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012 ++\002\202\001\001\000\272\204\266\162\333\236\014\153\342\231\351 ++\060\001\247\166\352\062\270\225\101\032\311\332\141\116\130\162 ++\317\376\366\202\171\277\163\141\006\012\245\047\330\263\137\323 ++\105\116\034\162\326\116\062\362\162\212\017\367\203\031\320\152 ++\200\200\000\105\036\260\307\347\232\277\022\127\047\034\243\150 ++\057\012\207\275\152\153\016\136\145\363\034\167\325\324\205\215 ++\160\041\264\263\062\347\213\242\325\206\071\002\261\270\322\107 ++\316\344\311\111\304\073\247\336\373\124\175\127\276\360\350\156 ++\302\171\262\072\013\125\342\120\230\026\062\023\134\057\170\126 ++\301\302\224\263\362\132\344\047\232\237\044\327\306\354\320\233 ++\045\202\343\314\302\304\105\305\214\227\172\006\153\052\021\237 ++\251\012\156\110\073\157\333\324\021\031\102\367\217\007\277\365 ++\123\137\234\076\364\027\054\346\151\254\116\062\114\142\167\352 ++\267\350\345\273\064\274\031\213\256\234\121\347\267\176\265\123 ++\261\063\042\345\155\317\160\074\032\372\342\233\147\266\203\364 ++\215\245\257\142\114\115\340\130\254\144\064\022\003\370\266\215 ++\224\143\044\244\161\002\003\001\000\001\243\102\060\100\060\016 ++\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\017 ++\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060 ++\035\006\003\125\035\016\004\026\004\024\152\162\046\172\320\036 ++\357\175\347\073\151\121\324\154\215\237\220\022\146\253\060\015 ++\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001 ++\001\000\171\237\035\226\306\266\171\077\042\215\207\323\207\003 ++\004\140\152\153\232\056\131\211\163\021\254\103\321\365\023\377 ++\215\071\053\300\362\275\117\160\214\251\057\352\027\304\013\124 ++\236\324\033\226\230\063\074\250\255\142\242\000\166\253\131\151 ++\156\006\035\176\304\271\104\215\230\257\022\324\141\333\012\031 ++\106\107\363\353\367\143\301\100\005\100\245\322\267\364\265\232 ++\066\277\251\210\166\210\004\125\004\053\234\207\177\032\067\074 ++\176\055\245\032\330\324\211\136\312\275\254\075\154\330\155\257 ++\325\363\166\017\315\073\210\070\042\235\154\223\232\304\075\277 ++\202\033\145\077\246\017\135\252\374\345\262\025\312\265\255\306 ++\274\075\320\204\350\352\006\162\260\115\071\062\170\277\076\021 ++\234\013\244\235\232\041\363\360\233\013\060\170\333\301\334\207 ++\103\376\274\143\232\312\305\302\034\311\307\215\377\073\022\130 ++\010\346\266\075\354\172\054\116\373\203\226\316\014\074\151\207 ++\124\163\244\163\302\223\377\121\020\254\025\124\001\330\374\005 ++\261\211\241\177\164\203\232\111\327\334\116\173\212\110\157\213 ++\105\366 ++END ++ ++# Trust for "Entrust Root Certification Authority - G2" ++# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Serial Number: 1246989352 (0x4a538c28) ++# Subject: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Not Valid Before: Tue Jul 07 17:25:54 2009 ++# Not Valid After : Sat Dec 07 17:55:54 2030 ++# Fingerprint (SHA-256): 43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 ++# Fingerprint (SHA1): 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Entrust Root Certification Authority - G2" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\214\364\047\375\171\014\072\321\146\006\215\350\036\127\357\273 ++\223\042\162\324 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\113\342\311\221\226\145\014\364\016\132\223\222\240\012\376\262 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 ++\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 ++\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 ++\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 ++\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 ++\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 ++\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 ++\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 ++\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 ++\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 ++\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 ++\062 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\112\123\214\050 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "Entrust Root Certification Authority - EC1" ++# ++# Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Serial Number:00:a6:8b:79:29:00:00:00:00:50:d0:91:f9 ++# Subject: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Not Valid Before: Tue Dec 18 15:25:36 2012 ++# Not Valid After : Fri Dec 18 15:55:36 2037 ++# Fingerprint (SHA-256): 02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 ++# Fingerprint (SHA1): 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Entrust Root Certification Authority - EC1" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 ++\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 ++\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 ++\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 ++\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 ++\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 ++\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 ++\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 ++\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 ++\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 ++\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 ++\103\061 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 ++\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 ++\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 ++\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 ++\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 ++\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 ++\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 ++\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 ++\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 ++\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 ++\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 ++\103\061 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\015\000\246\213\171\051\000\000\000\000\120\320\221\371 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\002\371\060\202\002\200\240\003\002\001\002\002\015\000 ++\246\213\171\051\000\000\000\000\120\320\221\371\060\012\006\010 ++\052\206\110\316\075\004\003\003\060\201\277\061\013\060\011\006 ++\003\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004 ++\012\023\015\105\156\164\162\165\163\164\054\040\111\156\143\056 ++\061\050\060\046\006\003\125\004\013\023\037\123\145\145\040\167 ++\167\167\056\145\156\164\162\165\163\164\056\156\145\164\057\154 ++\145\147\141\154\055\164\145\162\155\163\061\071\060\067\006\003 ++\125\004\013\023\060\050\143\051\040\062\060\061\062\040\105\156 ++\164\162\165\163\164\054\040\111\156\143\056\040\055\040\146\157 ++\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145 ++\040\157\156\154\171\061\063\060\061\006\003\125\004\003\023\052 ++\105\156\164\162\165\163\164\040\122\157\157\164\040\103\145\162 ++\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 ++\162\151\164\171\040\055\040\105\103\061\060\036\027\015\061\062 ++\061\062\061\070\061\065\062\065\063\066\132\027\015\063\067\061 ++\062\061\070\061\065\065\065\063\066\132\060\201\277\061\013\060 ++\011\006\003\125\004\006\023\002\125\123\061\026\060\024\006\003 ++\125\004\012\023\015\105\156\164\162\165\163\164\054\040\111\156 ++\143\056\061\050\060\046\006\003\125\004\013\023\037\123\145\145 ++\040\167\167\167\056\145\156\164\162\165\163\164\056\156\145\164 ++\057\154\145\147\141\154\055\164\145\162\155\163\061\071\060\067 ++\006\003\125\004\013\023\060\050\143\051\040\062\060\061\062\040 ++\105\156\164\162\165\163\164\054\040\111\156\143\056\040\055\040 ++\146\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165 ++\163\145\040\157\156\154\171\061\063\060\061\006\003\125\004\003 ++\023\052\105\156\164\162\165\163\164\040\122\157\157\164\040\103 ++\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 ++\150\157\162\151\164\171\040\055\040\105\103\061\060\166\060\020 ++\006\007\052\206\110\316\075\002\001\006\005\053\201\004\000\042 ++\003\142\000\004\204\023\311\320\272\155\101\173\342\154\320\353 ++\125\137\146\002\032\044\364\133\211\151\107\343\270\302\175\361 ++\362\002\305\237\240\366\133\325\213\006\031\206\117\123\020\155 ++\007\044\047\241\240\370\325\107\031\141\114\175\312\223\047\352 ++\164\014\357\157\226\011\376\143\354\160\135\066\255\147\167\256 ++\311\235\174\125\104\072\242\143\121\037\365\343\142\324\251\107 ++\007\076\314\040\243\102\060\100\060\016\006\003\125\035\017\001 ++\001\377\004\004\003\002\001\006\060\017\006\003\125\035\023\001 ++\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016 ++\004\026\004\024\267\143\347\032\335\215\351\010\246\125\203\244 ++\340\152\120\101\145\021\102\111\060\012\006\010\052\206\110\316 ++\075\004\003\003\003\147\000\060\144\002\060\141\171\330\345\102 ++\107\337\034\256\123\231\027\266\157\034\175\341\277\021\224\321 ++\003\210\165\344\215\211\244\212\167\106\336\155\141\357\002\365 ++\373\265\337\314\376\116\377\376\251\346\247\002\060\133\231\327 ++\205\067\006\265\173\010\375\353\047\213\112\224\371\341\372\247 ++\216\046\010\350\174\222\150\155\163\330\157\046\254\041\002\270 ++\231\267\046\101\133\045\140\256\320\110\032\356\006 ++END ++ ++# Trust for "Entrust Root Certification Authority - EC1" ++# Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Serial Number:00:a6:8b:79:29:00:00:00:00:50:d0:91:f9 ++# Subject: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US ++# Not Valid Before: Tue Dec 18 15:25:36 2012 ++# Not Valid After : Fri Dec 18 15:55:36 2037 ++# Fingerprint (SHA-256): 02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 ++# Fingerprint (SHA1): 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "Entrust Root Certification Authority - EC1" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\040\330\006\100\337\233\045\365\022\045\072\021\352\367\131\212 ++\353\024\265\107 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\266\176\035\360\130\305\111\154\044\073\075\355\230\030\355\274 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 ++\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 ++\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 ++\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 ++\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 ++\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 ++\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 ++\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 ++\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 ++\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 ++\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 ++\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 ++\103\061 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\015\000\246\213\171\051\000\000\000\000\120\320\221\371 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE ++ ++# ++# Certificate "CFCA EV ROOT" ++# ++# Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN ++# Serial Number: 407555286 (0x184accd6) ++# Subject: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN ++# Not Valid Before: Wed Aug 08 03:07:01 2012 ++# Not Valid After : Mon Dec 31 03:07:01 2029 ++# Fingerprint (SHA-256): 5C:C3:D7:8E:4E:1D:5E:45:54:7A:04:E6:87:3E:64:F9:0C:F9:53:6D:1C:CC:2E:F8:00:F3:55:C4:C5:FD:70:FD ++# Fingerprint (SHA1): E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 ++CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "CFCA EV ROOT" ++CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 ++CKA_SUBJECT MULTILINE_OCTAL ++\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 ++\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 ++\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 ++\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 ++\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 ++\040\105\126\040\122\117\117\124 ++END ++CKA_ID UTF8 "0" ++CKA_ISSUER MULTILINE_OCTAL ++\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 ++\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 ++\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 ++\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 ++\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 ++\040\105\126\040\122\117\117\124 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\030\112\314\326 ++END ++CKA_VALUE MULTILINE_OCTAL ++\060\202\005\215\060\202\003\165\240\003\002\001\002\002\004\030 ++\112\314\326\060\015\006\011\052\206\110\206\367\015\001\001\013 ++\005\000\060\126\061\013\060\011\006\003\125\004\006\023\002\103 ++\116\061\060\060\056\006\003\125\004\012\014\047\103\150\151\156 ++\141\040\106\151\156\141\156\143\151\141\154\040\103\145\162\164 ++\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162 ++\151\164\171\061\025\060\023\006\003\125\004\003\014\014\103\106 ++\103\101\040\105\126\040\122\117\117\124\060\036\027\015\061\062 ++\060\070\060\070\060\063\060\067\060\061\132\027\015\062\071\061 ++\062\063\061\060\063\060\067\060\061\132\060\126\061\013\060\011 ++\006\003\125\004\006\023\002\103\116\061\060\060\056\006\003\125 ++\004\012\014\047\103\150\151\156\141\040\106\151\156\141\156\143 ++\151\141\154\040\103\145\162\164\151\146\151\143\141\164\151\157 ++\156\040\101\165\164\150\157\162\151\164\171\061\025\060\023\006 ++\003\125\004\003\014\014\103\106\103\101\040\105\126\040\122\117 ++\117\124\060\202\002\042\060\015\006\011\052\206\110\206\367\015 ++\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 ++\002\001\000\327\135\153\315\020\077\037\005\131\325\005\115\067 ++\261\016\354\230\053\216\025\035\372\223\113\027\202\041\161\020 ++\122\327\121\144\160\026\302\125\151\115\216\025\155\237\277\014 ++\033\302\340\243\147\326\014\254\317\042\256\257\167\124\052\113 ++\114\212\123\122\172\303\356\056\336\263\161\045\301\351\135\075 ++\356\241\057\243\367\052\074\311\043\035\152\253\035\241\247\361 ++\363\354\240\325\104\317\025\317\162\057\035\143\227\350\231\371 ++\375\223\244\124\200\114\122\324\122\253\056\111\337\220\315\270 ++\137\276\077\336\241\312\115\040\324\045\350\204\051\123\267\261 ++\210\037\377\372\332\220\237\012\251\055\101\077\261\361\030\051 ++\356\026\131\054\064\111\032\250\006\327\250\210\322\003\162\172 ++\062\342\352\150\115\156\054\226\145\173\312\131\372\362\342\335 ++\356\060\054\373\314\106\254\304\143\353\157\177\066\053\064\163 ++\022\224\177\337\314\046\236\361\162\135\120\145\131\217\151\263 ++\207\136\062\157\303\030\212\265\225\217\260\172\067\336\132\105 ++\073\307\066\341\357\147\321\071\323\227\133\163\142\031\110\055 ++\207\034\006\373\164\230\040\111\163\360\005\322\033\261\240\243 ++\267\033\160\323\210\151\271\132\326\070\364\142\334\045\213\170 ++\277\370\350\176\270\134\311\225\117\137\247\055\271\040\153\317 ++\153\335\365\015\364\202\267\364\262\146\056\020\050\366\227\132 ++\173\226\026\217\001\031\055\154\156\177\071\130\006\144\203\001 ++\203\203\303\115\222\335\062\306\207\244\067\351\026\316\252\055 ++\150\257\012\201\145\072\160\301\233\255\115\155\124\312\052\055 ++\113\205\033\263\200\346\160\105\015\153\136\065\360\177\073\270 ++\234\344\004\160\211\022\045\223\332\012\231\042\140\152\143\140 ++\116\166\006\230\116\275\203\255\035\130\212\045\205\322\307\145 ++\036\055\216\306\337\266\306\341\177\212\004\041\025\051\164\360 ++\076\234\220\235\014\056\361\212\076\132\252\014\011\036\307\325 ++\074\243\355\227\303\036\064\372\070\371\010\016\343\300\135\053 ++\203\321\126\152\311\266\250\124\123\056\170\062\147\075\202\177 ++\164\320\373\341\266\005\140\271\160\333\216\013\371\023\130\157 ++\161\140\020\122\020\271\301\101\011\357\162\037\147\061\170\377 ++\226\005\215\002\003\001\000\001\243\143\060\141\060\037\006\003 ++\125\035\043\004\030\060\026\200\024\343\376\055\375\050\320\013 ++\265\272\266\242\304\277\006\252\005\214\223\373\057\060\017\006 ++\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016 ++\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035 ++\006\003\125\035\016\004\026\004\024\343\376\055\375\050\320\013 ++\265\272\266\242\304\277\006\252\005\214\223\373\057\060\015\006 ++\011\052\206\110\206\367\015\001\001\013\005\000\003\202\002\001 ++\000\045\306\272\153\353\207\313\336\202\071\226\075\360\104\247 ++\153\204\163\003\336\235\053\117\272\040\177\274\170\262\317\227 ++\260\033\234\363\327\171\056\365\110\266\322\373\027\210\346\323 ++\172\077\355\123\023\320\342\057\152\171\313\000\043\050\346\036 ++\067\127\065\211\204\302\166\117\064\066\255\147\303\316\101\006 ++\210\305\367\356\330\032\270\326\013\177\120\377\223\252\027\113 ++\214\354\355\122\140\262\244\006\352\116\353\364\153\031\375\353 ++\365\032\340\045\052\232\334\307\101\066\367\310\164\005\204\071 ++\225\071\326\013\073\244\047\372\010\330\134\036\370\004\140\122 ++\021\050\050\003\377\357\123\146\000\245\112\064\026\146\174\375 ++\011\244\256\236\147\032\157\101\013\153\006\023\233\217\206\161 ++\005\264\057\215\211\146\063\051\166\124\232\021\370\047\372\262 ++\077\221\340\316\015\033\363\060\032\255\277\042\135\033\323\277 ++\045\005\115\341\222\032\177\231\237\074\104\223\312\324\100\111 ++\154\200\207\327\004\072\303\062\122\065\016\126\370\245\335\175 ++\304\213\015\021\037\123\313\036\262\027\266\150\167\132\340\324 ++\313\310\007\256\365\072\056\216\067\267\320\001\113\103\051\167 ++\214\071\227\217\202\132\370\121\345\211\240\030\347\150\177\135 ++\012\056\373\243\107\016\075\246\043\172\306\001\307\217\310\136 ++\277\155\200\126\276\212\044\272\063\352\237\341\062\021\236\361 ++\322\117\200\366\033\100\257\070\236\021\120\171\163\022\022\315 ++\346\154\235\054\210\162\074\060\201\006\221\042\352\131\255\332 ++\031\056\042\302\215\271\214\207\340\146\274\163\043\137\041\144 ++\143\200\110\365\240\074\030\075\224\310\110\101\035\100\272\136 ++\376\376\126\071\241\310\317\136\236\031\144\106\020\332\027\221 ++\267\005\200\254\213\231\222\175\347\242\330\007\013\066\047\347 ++\110\171\140\212\303\327\023\134\370\162\100\337\112\313\317\231 ++\000\012\000\013\021\225\332\126\105\003\210\012\237\147\320\325 ++\171\261\250\215\100\155\015\302\172\100\372\363\137\144\107\222 ++\313\123\271\273\131\316\117\375\320\025\123\001\330\337\353\331 ++\346\166\357\320\043\273\073\251\171\263\325\002\051\315\211\243 ++\226\017\112\065\347\116\102\300\165\315\007\317\346\054\353\173 ++\056 ++END ++ ++# Trust for "CFCA EV ROOT" ++# Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN ++# Serial Number: 407555286 (0x184accd6) ++# Subject: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN ++# Not Valid Before: Wed Aug 08 03:07:01 2012 ++# Not Valid After : Mon Dec 31 03:07:01 2029 ++# Fingerprint (SHA-256): 5C:C3:D7:8E:4E:1D:5E:45:54:7A:04:E6:87:3E:64:F9:0C:F9:53:6D:1C:CC:2E:F8:00:F3:55:C4:C5:FD:70:FD ++# Fingerprint (SHA1): E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 ++CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST ++CKA_TOKEN CK_BBOOL CK_TRUE ++CKA_PRIVATE CK_BBOOL CK_FALSE ++CKA_MODIFIABLE CK_BBOOL CK_FALSE ++CKA_LABEL UTF8 "CFCA EV ROOT" ++CKA_CERT_SHA1_HASH MULTILINE_OCTAL ++\342\270\051\113\125\204\253\153\130\302\220\106\154\254\077\270 ++\071\217\204\203 ++END ++CKA_CERT_MD5_HASH MULTILINE_OCTAL ++\164\341\266\355\046\172\172\104\060\063\224\253\173\047\201\060 ++END ++CKA_ISSUER MULTILINE_OCTAL ++\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 ++\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 ++\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 ++\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 ++\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 ++\040\105\126\040\122\117\117\124 ++END ++CKA_SERIAL_NUMBER MULTILINE_OCTAL ++\002\004\030\112\314\326 ++END ++CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR ++CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST ++CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE +diff --git a/lib/ckfw/builtins/nssckbi.h b/lib/ckfw/builtins/nssckbi.h +--- a/lib/ckfw/builtins/nssckbi.h ++++ b/lib/ckfw/builtins/nssckbi.h +@@ -40,18 +40,18 @@ + * ... + * - NSS 3.29 branch: 250-255 + * + * NSS_BUILTINS_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear + * whether we may use its full range (0-255) or only 0-99 because + * of the comment in the CK_VERSION type definition. + */ + #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2 +-#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 2 +-#define NSS_BUILTINS_LIBRARY_VERSION "2.2" ++#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 3 ++#define NSS_BUILTINS_LIBRARY_VERSION "2.3" + + /* These version numbers detail the semantic changes to the ckfw engine. */ + #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 + #define NSS_BUILTINS_HARDWARE_VERSION_MINOR 0 + + /* These version numbers detail the semantic changes to ckbi itself + * (new PKCS #11 objects), etc. */ + #define NSS_BUILTINS_FIRMWARE_VERSION_MAJOR 1 + From baf253e663928cf78fb024abb4445cd84d5140de Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Sat, 7 Mar 2015 14:35:01 +0000 Subject: [PATCH 02/42] Bug 1140160 - Handle insertions into a
child with display:contents correctly. r=roc --- layout/base/nsCSSFrameConstructor.cpp | 13 +++-- .../display-contents-fieldset-ref.html | 51 +++++++++++++++++++ .../display-contents-fieldset.html | 48 +++++++++++++++++ layout/reftests/css-display/reftest.list | 1 + 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 layout/reftests/css-display/display-contents-fieldset-ref.html create mode 100644 layout/reftests/css-display/display-contents-fieldset.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 1bb033468ddb..59981abe8b32 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -6572,7 +6572,12 @@ nsCSSFrameConstructor::GetInsertionPrevSibling(InsertionPoint* aInsertion, // the container would be inserted. This is needed when inserting // into nested display:contents nodes. nsIContent* child = aInsertion->mContainer; - InsertionPoint fakeInsertion(aInsertion->mParentFrame, child->GetParent()); + nsIContent* parent = child->GetParent(); + aInsertion->mParentFrame = + ::GetAdjustedParentFrame(aInsertion->mParentFrame, + aInsertion->mParentFrame->GetType(), + parent); + InsertionPoint fakeInsertion(aInsertion->mParentFrame, parent); nsIFrame* result = GetInsertionPrevSibling(&fakeInsertion, child, aIsAppend, aIsRangeInsertSafe, nullptr, nullptr); MOZ_ASSERT(aInsertion->mParentFrame == fakeInsertion.mParentFrame); @@ -8913,8 +8918,10 @@ nsCSSFrameConstructor::GetInsertionPoint(nsIContent* aContainer, InsertionPoint insertion(GetContentInsertionFrameFor(insertionElement), insertionElement); - // Fieldsets have multiple insertion points. - if (insertionElement->IsHTMLElement(nsGkAtoms::fieldset)) { + // Fieldset frames have multiple normal flow child frame lists so handle it + // the same as if it had multiple content insertion points. + if (insertion.mParentFrame && + insertion.mParentFrame->GetType() == nsGkAtoms::fieldSetFrame) { insertion.mMultiple = true; } diff --git a/layout/reftests/css-display/display-contents-fieldset-ref.html b/layout/reftests/css-display/display-contents-fieldset-ref.html new file mode 100644 index 000000000000..4887b5fb2579 --- /dev/null +++ b/layout/reftests/css-display/display-contents-fieldset-ref.html @@ -0,0 +1,51 @@ + + + + + +
+
x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/layout/reftests/css-display/display-contents-fieldset.html b/layout/reftests/css-display/display-contents-fieldset.html new file mode 100644 index 000000000000..06cf5c99ea44 --- /dev/null +++ b/layout/reftests/css-display/display-contents-fieldset.html @@ -0,0 +1,48 @@ + + + + + +
+
x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/layout/reftests/css-display/reftest.list b/layout/reftests/css-display/reftest.list index f61e36ee64cb..89d181a2f7a2 100644 --- a/layout/reftests/css-display/reftest.list +++ b/layout/reftests/css-display/reftest.list @@ -22,3 +22,4 @@ skip-if(B2G) pref(layout.css.display-contents.enabled,true) == display-contents- skip-if(B2G) asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-3.xul display-contents-xbl-3-ref.xul # bug 1089223 skip pref(layout.css.display-contents.enabled,true) == display-contents-xbl-4.xul display-contents-xbl-4-ref.xul # fails (not just asserts) due to bug 1089223 skip-if(B2G) asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-5.xul display-contents-xbl-3-ref.xul # bug 1089223 +asserts(0-1) pref(layout.css.display-contents.enabled,true) == display-contents-fieldset.html display-contents-fieldset-ref.html # bug 1089223 From c8890df726ee633dd82d433f22630ebecb7c0f1f Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Sat, 7 Mar 2015 14:35:01 +0000 Subject: [PATCH 03/42] Bug 1140198 - Make s have a legend frame when nearest ancestor frame is a fieldset frame. r=roc IOW, drop the requirement that the parent *content* is a
, thus allowing a to become the fieldset legend also when it's wrapped in one or more nodes that are styled with display:contents. --- layout/base/nsCSSFrameConstructor.cpp | 2 -- .../css-display/display-contents-fieldset-ref.html | 13 +++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 59981abe8b32..8d8baf4b7eb4 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3472,8 +3472,6 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement, if (aTag == nsGkAtoms::legend && (!aParentFrame || !IsFrameForFieldSet(aParentFrame, aParentFrame->GetType()) || - !aElement->GetParent() || - !aElement->GetParent()->IsHTMLElement(nsGkAtoms::fieldset) || aStyleContext->StyleDisplay()->IsFloatingStyle() || aStyleContext->StyleDisplay()->IsAbsolutelyPositionedStyle())) { // is only special inside fieldset, check both the frame tree diff --git a/layout/reftests/css-display/display-contents-fieldset-ref.html b/layout/reftests/css-display/display-contents-fieldset-ref.html index 4887b5fb2579..43a67343c354 100644 --- a/layout/reftests/css-display/display-contents-fieldset-ref.html +++ b/layout/reftests/css-display/display-contents-fieldset-ref.html @@ -14,6 +14,7 @@ legend { border: 1px solid; } .before::before { content:"::before"; } .nb legend.static { border: 1px solid; } .nb legend { border-style:none; } +.p0 legend { padding:0; } @@ -23,17 +24,17 @@ legend { border: 1px solid; }
-
+
-
-
-
-
-
+
+
+
+
+
+ + + diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index 50e5885131bf..f2ddf572f701 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -458,3 +458,4 @@ load 1061028.html load 1116104.html load 1107508-1.html load 1127198-1.html +load 1140198.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 8d8baf4b7eb4..254312b1813b 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2598,8 +2598,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle newFrame = frameItems.FirstChild(); NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames"); } else { - MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK || - display->mDisplay == NS_STYLE_DISPLAY_CONTENTS, + MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK, "Unhandled display type for root element"); contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext); nsFrameItems frameItems; diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 7f428374e3e9..ed6cc23ab6d0 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -562,7 +562,14 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup) // doesn't get confused by looking at the style data. if (!mParent) { uint8_t displayVal = disp->mDisplay; - nsRuleNode::EnsureBlockDisplay(displayVal, true); + if (displayVal != NS_STYLE_DISPLAY_CONTENTS) { + nsRuleNode::EnsureBlockDisplay(displayVal, true); + } else { + // http://dev.w3.org/csswg/css-display/#transformations + // "... a display-outside of 'contents' computes to block-level + // on the root element." + displayVal = NS_STYLE_DISPLAY_BLOCK; + } if (displayVal != disp->mDisplay) { nsStyleDisplay *mutable_display = static_cast(GetUniqueStyleData(eStyleStruct_Display)); From 4c74b7ca6b5a6563f377f6d489fd9daf8f4ddbf8 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Sat, 7 Mar 2015 14:53:45 +0000 Subject: [PATCH 05/42] Bug 1140579 - (backout rev 27ac269bb796 b/c wrong bug number in commit message) --- layout/base/nsCSSFrameConstructor.cpp | 2 ++ .../css-display/display-contents-fieldset-ref.html | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 254312b1813b..633d505b1660 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3471,6 +3471,8 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement, if (aTag == nsGkAtoms::legend && (!aParentFrame || !IsFrameForFieldSet(aParentFrame, aParentFrame->GetType()) || + !aElement->GetParent() || + !aElement->GetParent()->IsHTMLElement(nsGkAtoms::fieldset) || aStyleContext->StyleDisplay()->IsFloatingStyle() || aStyleContext->StyleDisplay()->IsAbsolutelyPositionedStyle())) { // is only special inside fieldset, check both the frame tree diff --git a/layout/reftests/css-display/display-contents-fieldset-ref.html b/layout/reftests/css-display/display-contents-fieldset-ref.html index 43a67343c354..4887b5fb2579 100644 --- a/layout/reftests/css-display/display-contents-fieldset-ref.html +++ b/layout/reftests/css-display/display-contents-fieldset-ref.html @@ -14,7 +14,6 @@ legend { border: 1px solid; } .before::before { content:"::before"; } .nb legend.static { border: 1px solid; } .nb legend { border-style:none; } -.p0 legend { padding:0; } @@ -24,17 +23,17 @@ legend { border: 1px solid; }
-
+
-
-
-
-
-
+
+
+
+
+
+ + +
+
+
+ + From a58f2089241bf528b84ac2fe49fdad35bd2199b6 Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Thu, 5 Mar 2015 12:27:16 +0800 Subject: [PATCH 09/42] Bug 1081819 - Handle InMutedCycle() in TrackUnionStream::ProcessInput. r=roc,padenot --- dom/media/TrackUnionStream.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dom/media/TrackUnionStream.cpp b/dom/media/TrackUnionStream.cpp index 1e4044d2b641..bb59bf9867b8 100644 --- a/dom/media/TrackUnionStream.cpp +++ b/dom/media/TrackUnionStream.cpp @@ -272,6 +272,8 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) : segment->AppendNullData(ticks); STREAM_LOG(PR_LOG_DEBUG+1, ("TrackUnionStream %p appending %lld ticks of null data to track %d", this, (long long)ticks, outputTrack->GetID())); + } else if (InMutedCycle()) { + segment->AppendNullData(ticks); } else { MOZ_ASSERT(outputTrack->GetEnd() == GraphTimeToStreamTime(interval.mStart), "Samples missing"); From 1e027edc3b9fbf8ddaeabdd616c2fcc0ff859a6a Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 7 Mar 2015 16:35:04 +0100 Subject: [PATCH 10/42] Bug 1140324 - Remove __noSuchMethod__ handling from WebIDL parser and throw an exception instead. r=peterv --HG-- extra : rebase_source : 46e3fec0c5b1f399d209dd5e4038eeed6aabdc28 --- dom/bindings/parser/WebIDL.py | 7 +++++-- dom/bindings/parser/tests/test_method.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index e5263bb11cfa..cef662266fb7 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -338,7 +338,10 @@ class IDLUnresolvedIdentifier(IDLObject): assert len(name) > 0 - if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore: + if name == "__noSuchMethod__": + raise WebIDLError("__noSuchMethod__ is deprecated", [location]) + + if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore: raise WebIDLError("Identifiers beginning with __ are reserved", [location]) if name[0] == '_' and not allowDoubleUnderscore: @@ -3825,7 +3828,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope): return self._hasOverloads def isIdentifierLess(self): - return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__" + return self.identifier.name[:2] == "__" def resolve(self, parentScope): assert isinstance(parentScope, IDLScope) diff --git a/dom/bindings/parser/tests/test_method.py b/dom/bindings/parser/tests/test_method.py index 43fa2828b664..f6f54c33ab6e 100644 --- a/dom/bindings/parser/tests/test_method.py +++ b/dom/bindings/parser/tests/test_method.py @@ -169,3 +169,16 @@ def WebIDLTest(parser, harness): except Exception, x: threw = True harness.ok(threw, "Should spell [Throws] correctly on methods") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + interface A { + void __noSuchMethod__(); + }; + """) + results = parser.finish() + except Exception, x: + threw = True + harness.ok(threw, "Should not allow __noSuchMethod__ methods") From fd1677916d244ec492ca41531c90e3aa46297c6b Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 7 Mar 2015 16:35:07 +0100 Subject: [PATCH 11/42] Bug 1140334 - Remove __noSuchMethod__ from PlacesUtils.jsm. r=mak --HG-- extra : rebase_source : 91f82e812b8b16ea1db3f8ce2da02d0b5188b88d --- toolkit/components/places/PlacesUtils.jsm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/toolkit/components/places/PlacesUtils.jsm b/toolkit/components/places/PlacesUtils.jsm index a8120cfdfb68..f84799173778 100644 --- a/toolkit/components/places/PlacesUtils.jsm +++ b/toolkit/components/places/PlacesUtils.jsm @@ -1958,7 +1958,12 @@ let GuidHelper = { }, QueryInterface: XPCOMUtils.generateQI(Ci.nsINavBookmarkObserver), - __noSuchMethod__: () => {}, // Catch all all onItem* methods. + + onBeginUpdateBatch: function() {}, + onEndUpdateBatch: function() {}, + onItemChanged: function() {}, + onItemVisited: function() {}, + onItemMoved: function() {}, }; PlacesUtils.bookmarks.addObserver(this.observer, false); PlacesUtils.registerShutdownFunction(() => { From a27d5b32509f3d14f82eb5e4cb34de52219bd3ce Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 7 Mar 2015 16:35:13 +0100 Subject: [PATCH 12/42] Bug 1140342 - Remove __noSuchMethod__ from url-classifier debugging functions. r=gavin --HG-- extra : rebase_source : f166642526caf13e2ff41a71851338e36876ca58 --- .../url-classifier/content/moz/debug.js | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/toolkit/components/url-classifier/content/moz/debug.js b/toolkit/components/url-classifier/content/moz/debug.js index 3c5cb07ad802..ed4c117932da 100644 --- a/toolkit/components/url-classifier/content/moz/debug.js +++ b/toolkit/components/url-classifier/content/moz/debug.js @@ -838,6 +838,30 @@ if (G_GDEBUG) { this.G_Debug = function G_Debug(who, msg) { } this.G_Assert = function G_Assert(who, condition, msg) { } this.G_Error = function G_Error(who, msg) { } -this.G_debugService = { __noSuchMethod__: function() { } }; +this.G_debugService = { + alsoDumpToConsole: () => {}, + logFileIsEnabled: () => {}, + enableLogFile: () => {}, + disableLogFile: () => {}, + getLogFile: () => {}, + setLogFile: () => {}, + enableDumpToConsole: () => {}, + disableDumpToConsole: () => {}, + getZone: () => {}, + enableZone: () => {}, + disableZone: () => {}, + allZonesEnabled: () => {}, + enableAllZones: () => {}, + disableAllZones: () => {}, + callTracingEnabled: () => {}, + enableCallTracing: () => {}, + disableCallTracing: () => {}, + getLogFileErrorLevel: () => {}, + setLogFileErrorLevel: () => {}, + dump: () => {}, + maybeDumpToFile: () => {}, + observe: () => {}, + reportScriptError_: () => {} +}; #endif From 01e2b0e158d06bcfd3325ceab55aeb4a5b4fb412 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Sat, 7 Mar 2015 10:44:23 -0500 Subject: [PATCH 13/42] Bug 1140111 - Whitelist readlinkat along with readlink. r=kang --- security/sandbox/linux/SandboxFilter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp index a63eff7864fc..d6dbabd752e7 100644 --- a/security/sandbox/linux/SandboxFilter.cpp +++ b/security/sandbox/linux/SandboxFilter.cpp @@ -209,6 +209,7 @@ SandboxFilterImplContent::Build() { Deny(EACCES, SOCKETCALL(socket, SOCKET)); Allow(SYSCALL(open)); Allow(SYSCALL(readlink)); /* Workaround for bug 964455 */ + Allow(SYSCALL(readlinkat)); /* Workaround for bug 964455 */ Allow(SYSCALL(prctl)); Allow(SYSCALL(access)); Allow(SYSCALL(unlink)); From 6181573297f3bc0fb206e6954f5b864a9a41f11d Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Sat, 7 Mar 2015 09:46:27 -0600 Subject: [PATCH 14/42] Bug 1138740 - Notify Ion when changing a typed array's data pointer due to making a lazy buffer for it, r=sfink. --- js/src/jit-test/tests/ion/bug1138740.js | 12 ++++++++++++ js/src/vm/TypedArrayObject.cpp | 4 ++++ 2 files changed, 16 insertions(+) create mode 100644 js/src/jit-test/tests/ion/bug1138740.js diff --git a/js/src/jit-test/tests/ion/bug1138740.js b/js/src/jit-test/tests/ion/bug1138740.js new file mode 100644 index 000000000000..0c3acf30784f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1138740.js @@ -0,0 +1,12 @@ + +with({}){} +x = Int8Array(1) +function f(y) { + x[0] = y +} +f() +f(3) +f(7) +x.buffer; +f(0); +assertEq(x[0], 0); diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index ecbafd438f0d..5903e4389c9f 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -120,6 +120,10 @@ TypedArrayObject::ensureHasBuffer(JSContext *cx, Handle tarr tarray->setPrivate(buffer->dataPointer()); tarray->setSlot(TypedArrayLayout::BUFFER_SLOT, ObjectValue(*buffer)); + + // Notify compiled jit code that the base pointer has moved. + MarkObjectStateChange(cx, tarray); + return true; } From eaaf4319bbc67951fac27355e6129181e355fb82 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Sat, 7 Mar 2015 17:38:57 +0000 Subject: [PATCH 15/42] Bug 1140198 - Tweak display:contents test to make this test green again. r=me on a CLOSED TREE --- layout/style/test/test_root_node_display.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/layout/style/test/test_root_node_display.html b/layout/style/test/test_root_node_display.html index f5174ff58e5d..547fb0e48d22 100644 --- a/layout/style/test/test_root_node_display.html +++ b/layout/style/test/test_root_node_display.html @@ -45,6 +45,11 @@ function test_display_value(val) "We traditionally convert 'display:list-item' on the root node to " + "'display:block' (though if that changes, it's not technically a bug, " + "as long as we support it properly)."); + } else if (val == "contents") { + is(floatConversion, val, "'float' shouldn't affect 'display:contents'"); + is(rootConversion, "block", + "'display:contents' on the root node computes to block-level per" + + "http://dev.w3.org/csswg/css-display/#transformations"); } else { is(rootConversion, floatConversion, "root node should make 'display:" + val + "' compute to the same " + From 7e639c3e57a72d8f6aa8833e4ff40cbfe37e8088 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sat, 7 Mar 2015 11:44:04 -0800 Subject: [PATCH 16/42] Bug 1137470 followup, touch /CLOBBER to force full rebuild of NSS CLOSED TREE --- CLOBBER | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLOBBER b/CLOBBER index d4cdfaff33de..d05e85e790b9 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Merge day clobber \ No newline at end of file +Bug 1137470 NSS update required a clobber to fully rebuild From 9ac240c1f94e8bf0903b4edd6ddcf7bf96f19953 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sat, 7 Mar 2015 11:44:08 -0800 Subject: [PATCH 17/42] Bug 1140739 - Adjust browser_net_security-details.js's expectation of the label for a TLSv1.2 connection following the bug 1137470 NSS 3.18RC0 update's increase of the default maximum enabled TLS version CLOSED TREE --- .../devtools/netmonitor/test/browser_net_security-details.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/devtools/netmonitor/test/browser_net_security-details.js b/browser/devtools/netmonitor/test/browser_net_security-details.js index 3fa18e63f91b..837d54ef7e22 100644 --- a/browser/devtools/netmonitor/test/browser_net_security-details.js +++ b/browser/devtools/netmonitor/test/browser_net_security-details.js @@ -37,7 +37,7 @@ add_task(function* () { is(infobox.hidden, false, "Information box visible."); // Connection - checkLabel("#security-protocol-version-value", "TLSv1"); + checkLabel("#security-protocol-version-value", "TLSv1.2"); checkLabel("#security-ciphersuite-value", "TLS_RSA_WITH_AES_128_CBC_SHA"); // Host From b42aa70b5d6689b3f75056b5be3699dcd66909d3 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Wed, 18 Feb 2015 12:25:46 +0000 Subject: [PATCH 18/42] Bug 1114329 - Reftests for floats within blocks of varying width and directionality. r=smontagu --- .../reftests/floats/float-in-rtl-1-ref.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-1a.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-1b.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-1c.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-1d.html | 19 +++++++++++++++++++ .../reftests/floats/float-in-rtl-2-ref.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-2a.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-2b.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-2c.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-2d.html | 19 +++++++++++++++++++ .../reftests/floats/float-in-rtl-3-ref.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-3a.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-3b.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-3c.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-3d.html | 19 +++++++++++++++++++ .../reftests/floats/float-in-rtl-4-ref.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-4a.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-4b.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-4c.html | 17 +++++++++++++++++ layout/reftests/floats/float-in-rtl-4d.html | 19 +++++++++++++++++++ layout/reftests/floats/reftest.list | 16 ++++++++++++++++ 21 files changed, 364 insertions(+) create mode 100644 layout/reftests/floats/float-in-rtl-1-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-1a.html create mode 100644 layout/reftests/floats/float-in-rtl-1b.html create mode 100644 layout/reftests/floats/float-in-rtl-1c.html create mode 100644 layout/reftests/floats/float-in-rtl-1d.html create mode 100644 layout/reftests/floats/float-in-rtl-2-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-2a.html create mode 100644 layout/reftests/floats/float-in-rtl-2b.html create mode 100644 layout/reftests/floats/float-in-rtl-2c.html create mode 100644 layout/reftests/floats/float-in-rtl-2d.html create mode 100644 layout/reftests/floats/float-in-rtl-3-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-3a.html create mode 100644 layout/reftests/floats/float-in-rtl-3b.html create mode 100644 layout/reftests/floats/float-in-rtl-3c.html create mode 100644 layout/reftests/floats/float-in-rtl-3d.html create mode 100644 layout/reftests/floats/float-in-rtl-4-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-4a.html create mode 100644 layout/reftests/floats/float-in-rtl-4b.html create mode 100644 layout/reftests/floats/float-in-rtl-4c.html create mode 100644 layout/reftests/floats/float-in-rtl-4d.html diff --git a/layout/reftests/floats/float-in-rtl-1-ref.html b/layout/reftests/floats/float-in-rtl-1-ref.html new file mode 100644 index 000000000000..211d65036fb0 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-1-ref.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-1a.html b/layout/reftests/floats/float-in-rtl-1a.html new file mode 100644 index 000000000000..221f7b5e5c5b --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-1a.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-1b.html b/layout/reftests/floats/float-in-rtl-1b.html new file mode 100644 index 000000000000..58a39703a18d --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-1b.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-1c.html b/layout/reftests/floats/float-in-rtl-1c.html new file mode 100644 index 000000000000..ecc2d4079dca --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-1c.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-1d.html b/layout/reftests/floats/float-in-rtl-1d.html new file mode 100644 index 000000000000..9e66a8cf54aa --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-1d.html @@ -0,0 +1,19 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-2-ref.html b/layout/reftests/floats/float-in-rtl-2-ref.html new file mode 100644 index 000000000000..7c447d79955d --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-2-ref.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-2a.html b/layout/reftests/floats/float-in-rtl-2a.html new file mode 100644 index 000000000000..260151d677e4 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-2a.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-2b.html b/layout/reftests/floats/float-in-rtl-2b.html new file mode 100644 index 000000000000..145fb78b0423 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-2b.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-2c.html b/layout/reftests/floats/float-in-rtl-2c.html new file mode 100644 index 000000000000..66b490592e1f --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-2c.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-2d.html b/layout/reftests/floats/float-in-rtl-2d.html new file mode 100644 index 000000000000..668046fec0bf --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-2d.html @@ -0,0 +1,19 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-3-ref.html b/layout/reftests/floats/float-in-rtl-3-ref.html new file mode 100644 index 000000000000..e21d05be8085 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-3-ref.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-3a.html b/layout/reftests/floats/float-in-rtl-3a.html new file mode 100644 index 000000000000..15671d8a981c --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-3a.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-3b.html b/layout/reftests/floats/float-in-rtl-3b.html new file mode 100644 index 000000000000..8d9a43cc01df --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-3b.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-3c.html b/layout/reftests/floats/float-in-rtl-3c.html new file mode 100644 index 000000000000..71c1937c85c0 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-3c.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-3d.html b/layout/reftests/floats/float-in-rtl-3d.html new file mode 100644 index 000000000000..a177286221ce --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-3d.html @@ -0,0 +1,19 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+
+
+This text should appear to the RIGHT of the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-4-ref.html b/layout/reftests/floats/float-in-rtl-4-ref.html new file mode 100644 index 000000000000..85e5ab7852da --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-4-ref.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-4a.html b/layout/reftests/floats/float-in-rtl-4a.html new file mode 100644 index 000000000000..e28104da8fd5 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-4a.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-4b.html b/layout/reftests/floats/float-in-rtl-4b.html new file mode 100644 index 000000000000..44f5435aa1a0 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-4b.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-4c.html b/layout/reftests/floats/float-in-rtl-4c.html new file mode 100644 index 000000000000..8bd2ce76d785 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-4c.html @@ -0,0 +1,17 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-4d.html b/layout/reftests/floats/float-in-rtl-4d.html new file mode 100644 index 000000000000..8a2b727874a0 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-4d.html @@ -0,0 +1,19 @@ + + + +Bug 1114329 testcase + + +
+
+
+
+
+
+
+
+
+This text should appear to the LEFT of the red and green blocks. +
+ + diff --git a/layout/reftests/floats/reftest.list b/layout/reftests/floats/reftest.list index e2e0e6e27d29..2a8ac1a21ab5 100644 --- a/layout/reftests/floats/reftest.list +++ b/layout/reftests/floats/reftest.list @@ -19,3 +19,19 @@ fails == 345369-2.html 345369-2-ref.html == 546048-1.html 546048-1-ref.html == 775350-1.html 775350-1-ref.html == 1114329.html 1114329-ref.html +fails == float-in-rtl-1a.html float-in-rtl-1-ref.html # bug 1114329 +fails == float-in-rtl-1b.html float-in-rtl-1-ref.html # bug 1114329 +fails == float-in-rtl-1c.html float-in-rtl-1-ref.html # bug 1114329 +fails == float-in-rtl-1d.html float-in-rtl-1-ref.html # bug 1114329 +fails == float-in-rtl-2a.html float-in-rtl-2-ref.html # bug 1114329 +fails == float-in-rtl-2b.html float-in-rtl-2-ref.html # bug 1114329 +fails == float-in-rtl-2c.html float-in-rtl-2-ref.html # bug 1114329 +fails == float-in-rtl-2d.html float-in-rtl-2-ref.html # bug 1114329 +fails == float-in-rtl-3a.html float-in-rtl-3-ref.html # bug 1114329 +fails == float-in-rtl-3b.html float-in-rtl-3-ref.html # bug 1114329 +fails == float-in-rtl-3c.html float-in-rtl-3-ref.html # bug 1114329 +fails == float-in-rtl-3d.html float-in-rtl-3-ref.html # bug 1114329 +fails == float-in-rtl-4a.html float-in-rtl-4-ref.html # bug 1114329 +fails == float-in-rtl-4b.html float-in-rtl-4-ref.html # bug 1114329 +fails == float-in-rtl-4c.html float-in-rtl-4-ref.html # bug 1114329 +fails == float-in-rtl-4d.html float-in-rtl-4-ref.html # bug 1114329 From 0d0b0e8f2dc0e3121f18cb786dc3cb455bf68013 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Sat, 7 Mar 2015 12:27:36 -0800 Subject: [PATCH 19/42] Bug 1140486 patch 1 - Pass block frame instead of block reflow state to nsTextFrame::RecomputeOverflow. r=jfkthame This allows calling it from UpdateOverflow in patch 2. --- layout/generic/nsLineLayout.cpp | 2 +- layout/generic/nsTextFrame.cpp | 5 ++--- layout/generic/nsTextFrame.h | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index edb70635b681..0b64085500c2 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -3267,7 +3267,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo if (pfd->mRecomputeOverflow || frame->StyleContext()->HasTextDecorationLines()) { nsTextFrame* f = static_cast(frame); - r = f->RecomputeOverflow(*mBlockReflowState); + r = f->RecomputeOverflow(mBlockReflowState->frame); } frame->FinishAndStoreOverflow(r, frame->GetSize()); } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index ff455f2a49a3..5c17ea1b0bf7 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -8672,7 +8672,7 @@ nsTextFrame::TrimTrailingWhiteSpace(nsRenderingContext* aRC) } nsOverflowAreas -nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState) +nsTextFrame::RecomputeOverflow(nsIFrame* aBlockFrame) { nsRect bounds(nsPoint(0, 0), GetSize()); nsOverflowAreas result(bounds, bounds); @@ -8701,8 +8701,7 @@ nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState) } nsRect &vis = result.VisualOverflow(); vis.UnionRect(vis, boundingBox); - UnionAdditionalOverflow(PresContext(), aBlockReflowState.frame, provider, - &vis, true); + UnionAdditionalOverflow(PresContext(), aBlockFrame, provider, &vis, true); return result; } diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index b822f27d1d4a..42458dd8337f 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -252,8 +252,7 @@ public: uint32_t aSkippedStartOffset = 0, uint32_t aSkippedMaxLength = UINT32_MAX) MOZ_OVERRIDE; - nsOverflowAreas - RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState); + nsOverflowAreas RecomputeOverflow(nsIFrame* aBlockFrame); enum TextRunType { // Anything in reflow (but not intrinsic width calculation) or From 10fa0b3d2f782cd9dc2a99f99a4e03296f39cfbc Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Sat, 7 Mar 2015 12:27:36 -0800 Subject: [PATCH 20/42] Bug 1140486 patch 2 - Make nsTextFrame::UpdateOverflow include the visual overflow from the text metrics by calling existing RecomputeOverflow. r=jfkthame UpdateOverflow and RecomputeOverflow need to remain two separate functions since RecomputeOverflow is called from line layout, prior to setting the overflow areas, whereas UpdateOverflow needs to reset the overflow areas and (via its return value) propagate the change to ancestors. However, they should share more code than they do today. The only substantive (non-error-handling) change this is making is that it's adding the MeasureText call, manipulation of the resulting boundingBox, and inclusion of that bounding box in the visual overflow. This is exactly the change that I'm trying to make in this bug. It's also changing the error handling if EnsureTextRun returns null, but I don't think we need to worry about that case much. --- layout/generic/nsTextFrame.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 5c17ea1b0bf7..113a63238fb0 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -8996,18 +8996,9 @@ nsTextFrame::HasAnyNoncollapsedCharacters() bool nsTextFrame::UpdateOverflow() { - const nsRect rect(nsPoint(0, 0), GetSize()); - nsOverflowAreas overflowAreas(rect, rect); - if (GetStateBits() & NS_FRAME_FIRST_REFLOW) { return false; } - gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated); - if (!mTextRun) { - return false; - } - PropertyProvider provider(this, iter, nsTextFrame::eInflated); - provider.InitializeForDisplay(true); nsIFrame* decorationsBlock; if (IsFloatingFirstLetterChild()) { @@ -9029,8 +9020,8 @@ nsTextFrame::UpdateOverflow() } } - UnionAdditionalOverflow(PresContext(), decorationsBlock, provider, - &overflowAreas.VisualOverflow(), true); + nsOverflowAreas overflowAreas = RecomputeOverflow(decorationsBlock); + return FinishAndStoreOverflow(overflowAreas, GetSize()); } From f6aaca04652e59bda8e3cb653d7e7a50dc63eec3 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Sat, 7 Mar 2015 12:42:56 -0600 Subject: [PATCH 21/42] Bug 1138181 - Be more aggressive in updating plugin geometry in the compositor, avoids filtering out important offset updates that don't involve remote layer tree updates. r=roc --- gfx/layers/ipc/CompositorChild.cpp | 2 -- gfx/layers/ipc/CompositorParent.cpp | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index bd48f99b6831..e163269209d2 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -252,8 +252,6 @@ CompositorChild::RecvUpdatePluginConfigurations(const nsIntPoint& aContentOffset // Handle invalidation, this can be costly, avoid if it is not needed. if (isVisible) { // invalidate region (widget origin) - nsIntRect bounds = aPlugins[pluginsIdx].bounds(); - nsIntRect rect(0, 0, bounds.width, bounds.height); #if defined(XP_WIN) // Work around for flash's crummy sandbox. See bug 762948. This call // digs down into the window hirearchy, invalidating regions on diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 76d34928cf09..4b656d531b6b 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -1818,8 +1818,7 @@ UpdatePluginWindowState(uint64_t aId) } bool shouldComposePlugin = !!lts.mRoot && - !!lts.mRoot->GetParent() && - lts.mUpdatedPluginDataAvailable; + !!lts.mRoot->GetParent(); bool shouldHidePlugin = (!lts.mRoot || !lts.mRoot->GetParent()) && @@ -1832,6 +1831,7 @@ UpdatePluginWindowState(uint64_t aId) // calculating clipping. nsTArray aVisibleIdList; unused << lts.mParent->SendUpdatePluginVisibility(aVisibleIdList); + lts.mUpdatedPluginDataAvailable = false; return; } From c0e9fddc57073a396b3412b2d0588e8436704f13 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Sat, 7 Mar 2015 14:14:04 -0600 Subject: [PATCH 22/42] Bug 1132874 - Improve protections against sending a parent plugin protocol shutdown message to the child after the child has torn down. r=aklotz --- dom/plugins/ipc/PluginWidgetParent.cpp | 38 +++++++++++++++----------- dom/plugins/ipc/PluginWidgetParent.h | 1 + 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/dom/plugins/ipc/PluginWidgetParent.cpp b/dom/plugins/ipc/PluginWidgetParent.cpp index 528ee69cf52a..367018a5be2f 100644 --- a/dom/plugins/ipc/PluginWidgetParent.cpp +++ b/dom/plugins/ipc/PluginWidgetParent.cpp @@ -70,18 +70,7 @@ PluginWidgetParent::~PluginWidgetParent() // A destroy call can actually get skipped if a widget is associated // with the last out-of-process page, make sure and cleanup any left // over widgets if we have them. - if (mWidget) { -#if defined(MOZ_WIDGET_GTK) - mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0); - mWrapper = nullptr; -#elif defined(XP_WIN) - ::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW), - kPluginWidgetParentProperty); -#endif - mWidget->UnregisterPluginWindowForRemoteUpdates(); - mWidget->Destroy(); - mWidget = nullptr; - } + KillWidget(); } mozilla::dom::TabParent* @@ -191,14 +180,30 @@ PluginWidgetParent::RecvCreate(nsresult* aResult) return true; } +void +PluginWidgetParent::KillWidget() +{ + PWLOG("PluginWidgetParent::KillWidget() widget=%p\n", mWidget); + if (mWidget) { +#if defined(MOZ_WIDGET_GTK) + mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0); + mWrapper = nullptr; +#elif defined(XP_WIN) + ::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW), + kPluginWidgetParentProperty); +#endif + mWidget->UnregisterPluginWindowForRemoteUpdates(); + mWidget->Destroy(); + mWidget = nullptr; + } +} + void PluginWidgetParent::Shutdown(ShutdownType aType) { + PWLOG("PluginWidgetParent::Shutdown(%s)\n", aType == TAB_CLOSURE ? "TAB_CLOSURE" : "CONTENT"); if (mWidget) { - mWidget->UnregisterPluginWindowForRemoteUpdates(); - DebugOnly rv = mWidget->Destroy(); - NS_ASSERTION(NS_SUCCEEDED(rv), "widget destroy failure"); - mWidget = nullptr; + KillWidget(); unused << SendParentShutdown(aType); } } @@ -207,6 +212,7 @@ void PluginWidgetParent::ActorDestroy(ActorDestroyReason aWhy) { PWLOG("PluginWidgetParent::ActorDestroy()\n"); + KillWidget(); } // Called by TabParent's Destroy() in response to an early tear down (Early diff --git a/dom/plugins/ipc/PluginWidgetParent.h b/dom/plugins/ipc/PluginWidgetParent.h index 4e80cf14b44e..dd0d4ba6d9a1 100644 --- a/dom/plugins/ipc/PluginWidgetParent.h +++ b/dom/plugins/ipc/PluginWidgetParent.h @@ -63,6 +63,7 @@ public: private: void Shutdown(ShutdownType aType); + void KillWidget(); // The chrome side native widget. nsCOMPtr mWidget; From af18a63f82b5178e179107cbb7dee1033563fce4 Mon Sep 17 00:00:00 2001 From: Nikhil Marathe Date: Sun, 22 Feb 2015 01:52:10 -0800 Subject: [PATCH 23/42] Bug 1133861 - Enable the Fetch API by default. r=jst --HG-- extra : rebase_source : 97dc853238ad7ce4cec7277c4732bf3f4ec1b962 --- dom/base/test/csp/test_connect-src.html | 4 +-- dom/cache/test/mochitest/test_cache.html | 3 +-- dom/fetch/Headers.cpp | 26 ------------------- .../mochitest/fetch/test_fetch_basic.html | 8 ++---- .../fetch/test_fetch_basic_http.html | 8 ++---- .../fetch/test_fetch_basic_worker.html | 6 +---- .../mochitest/fetch/test_fetch_cors.html | 8 ++---- dom/tests/mochitest/fetch/test_headers.html | 10 +++---- .../mochitest/general/test_interfaces.html | 6 ++--- dom/webidl/Fetch.webidl | 2 +- dom/webidl/Headers.webidl | 3 +-- dom/webidl/Request.webidl | 3 +-- dom/webidl/Response.webidl | 3 +-- dom/workers/RuntimeService.cpp | 16 ------------ dom/workers/WorkerPrivate.h | 7 ----- dom/workers/Workers.h | 1 - dom/workers/test/fetch/test_interfaces.html | 6 +---- dom/workers/test/fetch/test_request.html | 6 +---- dom/workers/test/fetch/test_response.html | 6 +---- .../test/serviceworkers/test_fetch_event.html | 1 - .../test_serviceworker_interfaces.html | 1 - .../test_serviceworker_interfaces.js | 2 +- dom/workers/test/test_worker_interfaces.js | 6 ++++- modules/libpref/init/all.js | 2 -- 24 files changed, 28 insertions(+), 116 deletions(-) diff --git a/dom/base/test/csp/test_connect-src.html b/dom/base/test/csp/test_connect-src.html index c61fb39ff0be..f21107c67cd1 100644 --- a/dom/base/test/csp/test_connect-src.html +++ b/dom/base/test/csp/test_connect-src.html @@ -122,9 +122,7 @@ function loadNextTest() { } // start running the tests -SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] -]}, loadNextTest); +loadNextTest(); diff --git a/dom/cache/test/mochitest/test_cache.html b/dom/cache/test/mochitest/test_cache.html index ff7bad44b6f8..fae5ac90d581 100644 --- a/dom/cache/test/mochitest/test_cache.html +++ b/dom/cache/test/mochitest/test_cache.html @@ -13,8 +13,7 @@ diff --git a/dom/tests/mochitest/fetch/test_fetch_basic_http.html b/dom/tests/mochitest/fetch/test_fetch_basic_http.html index b4e75836da48..1601d9407fb0 100644 --- a/dom/tests/mochitest/fetch/test_fetch_basic_http.html +++ b/dom/tests/mochitest/fetch/test_fetch_basic_http.html @@ -42,12 +42,8 @@ function testOnWorker(done) { // Driver // -SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] -]}, function() { - testOnWorker(function() { - SimpleTest.finish(); - }); +testOnWorker(function() { + SimpleTest.finish(); }); diff --git a/dom/tests/mochitest/fetch/test_fetch_basic_worker.html b/dom/tests/mochitest/fetch/test_fetch_basic_worker.html index 54f15e5ce9f7..a373528f0a45 100644 --- a/dom/tests/mochitest/fetch/test_fetch_basic_worker.html +++ b/dom/tests/mochitest/fetch/test_fetch_basic_worker.html @@ -36,11 +36,7 @@ SimpleTest.waitForExplicitFinish(); - SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] - ]}, function() { - runTest(); - }); + runTest(); diff --git a/dom/tests/mochitest/fetch/test_fetch_cors.html b/dom/tests/mochitest/fetch/test_fetch_cors.html index 30b73081ce21..222132bc4d36 100644 --- a/dom/tests/mochitest/fetch/test_fetch_cors.html +++ b/dom/tests/mochitest/fetch/test_fetch_cors.html @@ -42,12 +42,8 @@ function testOnWorker(done) { // Driver // -SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] -]}, function() { - testOnWorker(function() { - SimpleTest.finish(); - }); +testOnWorker(function() { + SimpleTest.finish(); }); diff --git a/dom/tests/mochitest/fetch/test_headers.html b/dom/tests/mochitest/fetch/test_headers.html index 103c88e629b0..4e461f6949a8 100644 --- a/dom/tests/mochitest/fetch/test_headers.html +++ b/dom/tests/mochitest/fetch/test_headers.html @@ -53,13 +53,9 @@ function testOnMainThread(done) { // Driver // -SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] -]}, function() { - testOnMainThread(function() { - testOnWorker(function() { - SimpleTest.finish(); - }); +testOnMainThread(function() { + testOnWorker(function() { + SimpleTest.finish(); }); }); diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 65fc19b778e3..3a8f5df1fbaf 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -437,7 +437,7 @@ var interfaceNamesInGlobalScope = // IMPORTANT: Do not change this list without review from a DOM peer! "HashChangeEvent", // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "Headers", pref: "dom.fetch.enabled"}, + "Headers", // IMPORTANT: Do not change this list without review from a DOM peer! "History", // IMPORTANT: Do not change this list without review from a DOM peer! @@ -871,9 +871,9 @@ var interfaceNamesInGlobalScope = // IMPORTANT: Do not change this list without review from a DOM peer! "Rect", // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "Request", pref: "dom.fetch.enabled"}, + "Request", // IMPORTANT: Do not change this list without review from a DOM peer! - {name: "Response", pref: "dom.fetch.enabled"}, + "Response", // IMPORTANT: Do not change this list without review from a DOM peer! "RGBColor", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/Fetch.webidl b/dom/webidl/Fetch.webidl index fb022126998c..f92599addb29 100644 --- a/dom/webidl/Fetch.webidl +++ b/dom/webidl/Fetch.webidl @@ -29,7 +29,7 @@ interface Body { [NoInterfaceObject, Exposed=(Window,Worker)] interface GlobalFetch { - [Throws, Func="mozilla::dom::Headers::PrefEnabled"] + [Throws] Promise fetch(RequestInfo input, optional RequestInit init); }; diff --git a/dom/webidl/Headers.webidl b/dom/webidl/Headers.webidl index a240e37295a2..f27a1ec05411 100644 --- a/dom/webidl/Headers.webidl +++ b/dom/webidl/Headers.webidl @@ -19,8 +19,7 @@ enum HeadersGuardEnum { }; [Constructor(optional HeadersInit init), - Exposed=(Window,Worker), - Func="mozilla::dom::Headers::PrefEnabled"] + Exposed=(Window,Worker)] interface Headers { [Throws] void append(ByteString name, ByteString value); [Throws] void delete(ByteString name); diff --git a/dom/webidl/Request.webidl b/dom/webidl/Request.webidl index 0ca4ff116075..df8db1ac56e2 100644 --- a/dom/webidl/Request.webidl +++ b/dom/webidl/Request.webidl @@ -10,8 +10,7 @@ typedef (Request or USVString) RequestInfo; [Constructor(RequestInfo input, optional RequestInit init), - Exposed=(Window,Worker), - Func="mozilla::dom::Headers::PrefEnabled"] + Exposed=(Window,Worker)] interface Request { readonly attribute ByteString method; readonly attribute USVString url; diff --git a/dom/webidl/Response.webidl b/dom/webidl/Response.webidl index fb6b5cc74438..3f1598558210 100644 --- a/dom/webidl/Response.webidl +++ b/dom/webidl/Response.webidl @@ -8,8 +8,7 @@ */ [Constructor(optional BodyInit body, optional ResponseInit init), - Exposed=(Window,Worker), - Func="mozilla::dom::Headers::PrefEnabled"] + Exposed=(Window,Worker)] interface Response { [NewObject] static Response error(); [Throws, diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 2de612e52bb3..457da1110322 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -154,7 +154,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1, #define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled" #endif -#define PREF_DOM_FETCH_ENABLED "dom.fetch.enabled" #define PREF_DOM_CACHES_ENABLED "dom.caches.enabled" #define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion" #define PREF_INTL_ACCEPT_LANGUAGES "intl.accept_languages" @@ -1826,10 +1825,6 @@ RuntimeService::Init() PREF_DOM_WINDOW_DUMP_ENABLED, reinterpret_cast(WORKERPREF_DUMP))) || #endif - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_DOM_FETCH_ENABLED, - reinterpret_cast(WORKERPREF_DOM_FETCH))) || NS_FAILED(Preferences::RegisterCallbackAndCall( WorkerPrefChanged, PREF_DOM_CACHES_ENABLED, @@ -2027,10 +2022,6 @@ RuntimeService::Cleanup() WorkerPrefChanged, PREF_DOM_CACHES_ENABLED, reinterpret_cast(WORKERPREF_DOM_CACHES))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_DOM_FETCH_ENABLED, - reinterpret_cast(WORKERPREF_DOM_FETCH))) || #if DUMP_CONTROLLED_BY_PREF NS_FAILED(Preferences::UnregisterCallback( WorkerPrefChanged, @@ -2560,18 +2551,11 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure) } #endif - if (key == WORKERPREF_DOM_FETCH) { - key = WORKERPREF_DOM_FETCH; - sDefaultPreferences[WORKERPREF_DOM_FETCH] = - Preferences::GetBool(PREF_DOM_FETCH_ENABLED, false); - } - if (key == WORKERPREF_DOM_CACHES) { key = WORKERPREF_DOM_CACHES; sDefaultPreferences[WORKERPREF_DOM_CACHES] = Preferences::GetBool(PREF_DOM_CACHES_ENABLED, false); } - // This function should never be registered as a callback for a preference it // does not handle. MOZ_ASSERT(key != WORKERPREF_COUNT); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 80d85269166e..37edf19d81a6 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -1101,13 +1101,6 @@ public: return mPreferences[WORKERPREF_DUMP]; } - bool - DOMFetchEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_DOM_FETCH]; - } - bool DOMCachesEnabled() const { diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index 49337e1ee664..abdb6ae6907b 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -194,7 +194,6 @@ struct JSSettings enum WorkerPreference { WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled - WORKERPREF_DOM_FETCH,// dom.fetch.enabled WORKERPREF_DOM_CACHES, // dom.caches.enabled WORKERPREF_COUNT }; diff --git a/dom/workers/test/fetch/test_interfaces.html b/dom/workers/test/fetch/test_interfaces.html index dbbf21f6d18c..207674486d8a 100644 --- a/dom/workers/test/fetch/test_interfaces.html +++ b/dom/workers/test/fetch/test_interfaces.html @@ -36,11 +36,7 @@ SimpleTest.waitForExplicitFinish(); - SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] - ]}, function() { - checkEnabled(); - }); + checkEnabled(); diff --git a/dom/workers/test/fetch/test_request.html b/dom/workers/test/fetch/test_request.html index 73d7b5b9898e..6473636a93e5 100644 --- a/dom/workers/test/fetch/test_request.html +++ b/dom/workers/test/fetch/test_request.html @@ -36,11 +36,7 @@ SimpleTest.waitForExplicitFinish(); - SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] - ]}, function() { - checkEnabled(); - }); + checkEnabled(); diff --git a/dom/workers/test/fetch/test_response.html b/dom/workers/test/fetch/test_response.html index e1bbd399ed65..9e38ec31afda 100644 --- a/dom/workers/test/fetch/test_response.html +++ b/dom/workers/test/fetch/test_response.html @@ -36,11 +36,7 @@ SimpleTest.waitForExplicitFinish(); - SpecialPowers.pushPrefEnv({"set": [ - ["dom.fetch.enabled", true] - ]}, function() { - runTest(); - }); + runTest(); diff --git a/dom/workers/test/serviceworkers/test_fetch_event.html b/dom/workers/test/serviceworkers/test_fetch_event.html index e2a2166026f2..84ca3e3c3d70 100644 --- a/dom/workers/test/serviceworkers/test_fetch_event.html +++ b/dom/workers/test/serviceworkers/test_fetch_event.html @@ -53,7 +53,6 @@ SpecialPowers.pushPrefEnv({"set": [ ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true], - ["dom.fetch.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.html b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.html index 27d053601eb2..90625d09a1fb 100644 --- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.html +++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.html @@ -104,7 +104,6 @@ ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true], - ["dom.fetch.enabled", true], ["dom.caches.enabled", true] ]}, runTest); }; diff --git a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js index 818daf6eb79f..c9c675934d7d 100644 --- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js +++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js @@ -115,7 +115,7 @@ var interfaceNamesInGlobalScope = // IMPORTANT: Do not change this list without review from a DOM peer! "FileReaderSync", // IMPORTANT: Do not change this list without review from a DOM peer! - { name: "Headers", pref: "dom.fetch.enabled" }, + "Headers", // IMPORTANT: Do not change this list without review from a DOM peer! "IDBCursor", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/workers/test/test_worker_interfaces.js b/dom/workers/test/test_worker_interfaces.js index f46b64a05933..8fa79778d9c4 100644 --- a/dom/workers/test/test_worker_interfaces.js +++ b/dom/workers/test/test_worker_interfaces.js @@ -109,7 +109,7 @@ var interfaceNamesInGlobalScope = // IMPORTANT: Do not change this list without review from a DOM peer! "FileReaderSync", // IMPORTANT: Do not change this list without review from a DOM peer! - { name: "Headers", pref: "dom.fetch.enabled" }, + "Headers", // IMPORTANT: Do not change this list without review from a DOM peer! "IDBCursor", // IMPORTANT: Do not change this list without review from a DOM peer! @@ -140,6 +140,10 @@ var interfaceNamesInGlobalScope = "Performance", // IMPORTANT: Do not change this list without review from a DOM peer! "Promise", +// IMPORTANT: Do not change this list without review from a DOM peer! + "Request", +// IMPORTANT: Do not change this list without review from a DOM peer! + "Response", // IMPORTANT: Do not change this list without review from a DOM peer! "TextDecoder", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 435c9a432ff1..76f7aac42def 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4456,8 +4456,6 @@ pref("beacon.enabled", true); // Camera prefs pref("camera.control.face_detection.enabled", true); -// Fetch API. -pref("dom.fetch.enabled", false); // SW Cache API pref("dom.caches.enabled", false); From b4227d7b33cf9dadbee56f8bf6203bfeb7d98f7a Mon Sep 17 00:00:00 2001 From: Nikhil Marathe Date: Tue, 3 Mar 2015 14:30:58 -0800 Subject: [PATCH 24/42] Bug 1053275 - Exempt ServiceWorkers from per domain thread limits. r=sicking --HG-- extra : rebase_source : 4f48830c13e1ba471147774b7d93f4f2c795543d --- dom/workers/RuntimeService.cpp | 10 +++++++++- dom/workers/test/serviceworkers/test_controller.html | 1 + dom/workers/test/serviceworkers/test_fetch_event.html | 1 + .../test/serviceworkers/test_install_event.html | 1 + .../test/serviceworkers/test_installation_simple.html | 1 + dom/workers/test/serviceworkers/test_match_all.html | 1 + dom/workers/test/serviceworkers/test_navigator.html | 1 + dom/workers/test/serviceworkers/test_post_message.html | 1 + .../serviceworkers/test_post_message_advanced.html | 1 + dom/workers/test/serviceworkers/test_scopes.html | 1 + dom/workers/test/serviceworkers/test_unregister.html | 1 + .../test/serviceworkers/test_workerUnregister.html | 1 + dom/workers/test/serviceworkers/test_workerUpdate.html | 1 + 13 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 457da1110322..143d4f56e517 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -1422,6 +1422,13 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate) NS_ASSERTION(!sharedWorkerScriptSpec.IsEmpty(), "Empty spec!"); } + bool exemptFromPerDomainMax = false; + if (aWorkerPrivate->IsServiceWorker()) { + AssertIsOnMainThread(); + exemptFromPerDomainMax = Preferences::GetBool("dom.serviceWorkers.exemptFromPerDomainMax", + false); + } + const nsCString& domain = aWorkerPrivate->Domain(); WorkerDomainInfo* domainInfo; @@ -1439,7 +1446,8 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate) queued = gMaxWorkersPerDomain && domainInfo->ActiveWorkerCount() >= gMaxWorkersPerDomain && - !domain.IsEmpty(); + !domain.IsEmpty() && + !exemptFromPerDomainMax; if (queued) { domainInfo->mQueuedWorkers.AppendElement(aWorkerPrivate); diff --git a/dom/workers/test/serviceworkers/test_controller.html b/dom/workers/test/serviceworkers/test_controller.html index 07ecc16b92cf..483f488397b9 100644 --- a/dom/workers/test/serviceworkers/test_controller.html +++ b/dom/workers/test/serviceworkers/test_controller.html @@ -60,6 +60,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_fetch_event.html b/dom/workers/test/serviceworkers/test_fetch_event.html index 84ca3e3c3d70..31dec802a30f 100644 --- a/dom/workers/test/serviceworkers/test_fetch_event.html +++ b/dom/workers/test/serviceworkers/test_fetch_event.html @@ -51,6 +51,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true], ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_install_event.html b/dom/workers/test/serviceworkers/test_install_event.html index dcfc2d239342..86532002d699 100644 --- a/dom/workers/test/serviceworkers/test_install_event.html +++ b/dom/workers/test/serviceworkers/test_install_event.html @@ -102,6 +102,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_installation_simple.html b/dom/workers/test/serviceworkers/test_installation_simple.html index 4619f39cb21a..8f5c61898e01 100644 --- a/dom/workers/test/serviceworkers/test_installation_simple.html +++ b/dom/workers/test/serviceworkers/test_installation_simple.html @@ -177,6 +177,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.messageChannel.enabled", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] diff --git a/dom/workers/test/serviceworkers/test_match_all.html b/dom/workers/test/serviceworkers/test_match_all.html index ce60647ab65d..c6d3bdbee9c3 100644 --- a/dom/workers/test/serviceworkers/test_match_all.html +++ b/dom/workers/test/serviceworkers/test_match_all.html @@ -67,6 +67,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_navigator.html b/dom/workers/test/serviceworkers/test_navigator.html index cb8936e22bcc..164f41bcd2cf 100644 --- a/dom/workers/test/serviceworkers/test_navigator.html +++ b/dom/workers/test/serviceworkers/test_navigator.html @@ -27,6 +27,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true] ]}, function() { checkEnabled(); diff --git a/dom/workers/test/serviceworkers/test_post_message.html b/dom/workers/test/serviceworkers/test_post_message.html index 0bf48f93a42b..2a1bf99c33fd 100644 --- a/dom/workers/test/serviceworkers/test_post_message.html +++ b/dom/workers/test/serviceworkers/test_post_message.html @@ -66,6 +66,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_post_message_advanced.html b/dom/workers/test/serviceworkers/test_post_message_advanced.html index a91fe7fef24a..7d4c9ba27743 100644 --- a/dom/workers/test/serviceworkers/test_post_message_advanced.html +++ b/dom/workers/test/serviceworkers/test_post_message_advanced.html @@ -95,6 +95,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_scopes.html b/dom/workers/test/serviceworkers/test_scopes.html index 51a0bd073291..74a2a3edf9b1 100644 --- a/dom/workers/test/serviceworkers/test_scopes.html +++ b/dom/workers/test/serviceworkers/test_scopes.html @@ -88,6 +88,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_unregister.html b/dom/workers/test/serviceworkers/test_unregister.html index a568b4e1311c..8366f50c1ce6 100644 --- a/dom/workers/test/serviceworkers/test_unregister.html +++ b/dom/workers/test/serviceworkers/test_unregister.html @@ -127,6 +127,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_workerUnregister.html b/dom/workers/test/serviceworkers/test_workerUnregister.html index 9322b9ae0d92..947861c176b8 100644 --- a/dom/workers/test/serviceworkers/test_workerUnregister.html +++ b/dom/workers/test/serviceworkers/test_workerUnregister.html @@ -71,6 +71,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); diff --git a/dom/workers/test/serviceworkers/test_workerUpdate.html b/dom/workers/test/serviceworkers/test_workerUpdate.html index 15240262c918..16aae86fee73 100644 --- a/dom/workers/test/serviceworkers/test_workerUpdate.html +++ b/dom/workers/test/serviceworkers/test_workerUpdate.html @@ -44,6 +44,7 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.exemptFromPerDomainMax", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true] ]}, runTest); From 6704643316f79d407ef7035c0276f84743dc14bd Mon Sep 17 00:00:00 2001 From: Nikhil Marathe Date: Tue, 3 Mar 2015 15:57:15 -0800 Subject: [PATCH 25/42] Bug 1133805 - Enable all serviceworker tests on all platforms except b2g. r=baku --HG-- extra : rebase_source : a479570684910bc93fc82b26916020276d7f38dd --- dom/workers/test/serviceworkers/mochitest.ini | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dom/workers/test/serviceworkers/mochitest.ini b/dom/workers/test/serviceworkers/mochitest.ini index 6b74b649783b..db54f815fa3f 100644 --- a/dom/workers/test/serviceworkers/mochitest.ini +++ b/dom/workers/test/serviceworkers/mochitest.ini @@ -32,19 +32,15 @@ support-files = close_test.js [test_unregister.html] -skip-if = true # Bug 1133805 [test_installation_simple.html] [test_fetch_event.html] [test_match_all.html] [test_install_event.html] [test_navigator.html] [test_scopes.html] -skip-if = true # Bug 1037739 [test_controller.html] [test_workerUpdate.html] -skip-if = true # Bug 1133805 [test_workerUnregister.html] -skip-if = true # Bug 1133805 [test_post_message.html] [test_post_message_advanced.html] [test_match_all_client_properties.html] From 050556d853f73e9f6a83497bb62a84ce134eaf23 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Thu, 5 Mar 2015 16:58:35 -0500 Subject: [PATCH 26/42] Bug 1090439 - PPrinting calls from child to parent via ShowProgress and ShowPrintDialog should not be sync. r=smaug. --HG-- extra : rebase_source : 5976ab33f9d1f7a4d2046e266f7fd763567d97ab --- .../printingui/ipc/PPrintSettingsDialog.ipdl | 21 +++++ .../components/printingui/ipc/PPrinting.ipdl | 84 ++---------------- .../printingui/ipc/PPrintingTypes.ipdlh | 85 +++++++++++++++++++ .../ipc/PrintSettingsDialogChild.cpp | 34 ++++++++ .../printingui/ipc/PrintSettingsDialogChild.h | 36 ++++++++ .../ipc/PrintSettingsDialogParent.cpp | 28 ++++++ .../ipc/PrintSettingsDialogParent.h | 29 +++++++ .../printingui/ipc/PrintingParent.cpp | 64 +++++++++----- .../printingui/ipc/PrintingParent.h | 29 +++++-- embedding/components/printingui/ipc/moz.build | 4 + .../printingui/ipc/nsPrintingProxy.cpp | 39 +++++++-- .../printingui/ipc/nsPrintingProxy.h | 6 ++ 12 files changed, 345 insertions(+), 114 deletions(-) create mode 100644 embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl create mode 100644 embedding/components/printingui/ipc/PPrintingTypes.ipdlh create mode 100644 embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp create mode 100644 embedding/components/printingui/ipc/PrintSettingsDialogChild.h create mode 100644 embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp create mode 100644 embedding/components/printingui/ipc/PrintSettingsDialogParent.h diff --git a/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl b/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl new file mode 100644 index 000000000000..ff87c612b9b2 --- /dev/null +++ b/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl @@ -0,0 +1,21 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* 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 PPrintingTypes; +include protocol PPrinting; + +namespace mozilla { +namespace embedding { + +protocol PPrintSettingsDialog +{ + manager PPrinting; + +child: + __delete__(nsresult rv, PrintData data); +}; + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PPrinting.ipdl b/embedding/components/printingui/ipc/PPrinting.ipdl index 7a01a008e4e7..30601bf4eb73 100644 --- a/embedding/components/printingui/ipc/PPrinting.ipdl +++ b/embedding/components/printingui/ipc/PPrinting.ipdl @@ -3,92 +3,20 @@ * 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 PPrintingTypes; include protocol PContent; include protocol PBrowser; include protocol PPrintProgressDialog; +include protocol PPrintSettingsDialog; namespace mozilla { namespace embedding { -struct PrintData { - int32_t startPageRange; - int32_t endPageRange; - double edgeTop; - double edgeLeft; - double edgeBottom; - double edgeRight; - double marginTop; - double marginLeft; - double marginBottom; - double marginRight; - double unwriteableMarginTop; - double unwriteableMarginLeft; - double unwriteableMarginBottom; - double unwriteableMarginRight; - double scaling; - bool printBGColors; - bool printBGImages; - short printRange; - nsString title; - nsString docURL; - nsString headerStrLeft; - nsString headerStrCenter; - nsString headerStrRight; - nsString footerStrLeft; - nsString footerStrCenter; - nsString footerStrRight; - - short howToEnableFrameUI; - bool isCancelled; - short printFrameTypeUsage; - short printFrameType; - bool printSilent; - bool shrinkToFit; - bool showPrintProgress; - - nsString paperName; - short paperSizeType; - short paperData; - double paperWidth; - double paperHeight; - short paperSizeUnit; - nsString plexName; - nsString colorspace; - nsString resolutionName; - bool downloadFonts; - bool printReversed; - bool printInColor; - int32_t orientation; - nsString printCommand; - int32_t numCopies; - nsString printerName; - bool printToFile; - nsString toFileName; - short outputFormat; - int32_t printPageDelay; - int32_t resolution; - int32_t duplex; - bool isInitializedFromPrinter; - bool isInitializedFromPrefs; - bool persistMarginBoxSettings; - - /* Windows-specific things */ - nsString driverName; - nsString deviceName; - bool isFramesetDocument; - bool isFramesetFrameSelected; - bool isIFrameSelected; - bool isRangeSelection; - - /* TODO: OS X specific things - specifically, an array of names for the - * document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames - */ -}; - sync protocol PPrinting { manager PContent; manages PPrintProgressDialog; + manages PPrintSettingsDialog; parent: sync ShowProgress(PBrowser browser, @@ -97,10 +25,12 @@ parent: returns(bool notifyOnOpen, bool success); - sync ShowPrintDialog(PBrowser browser, PrintData settings) - returns(PrintData modifiedSettings, bool success); + async ShowPrintDialog(PPrintSettingsDialog dialog, + PBrowser browser, + PrintData settings); PPrintProgressDialog(); + PPrintSettingsDialog(); sync SavePrintSettings(PrintData settings, bool usePrinterNamePrefix, uint32_t flags) diff --git a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh new file mode 100644 index 000000000000..f7cedf625d7f --- /dev/null +++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh @@ -0,0 +1,85 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* 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/. */ + +namespace mozilla { +namespace embedding { + +struct PrintData { + int32_t startPageRange; + int32_t endPageRange; + double edgeTop; + double edgeLeft; + double edgeBottom; + double edgeRight; + double marginTop; + double marginLeft; + double marginBottom; + double marginRight; + double unwriteableMarginTop; + double unwriteableMarginLeft; + double unwriteableMarginBottom; + double unwriteableMarginRight; + double scaling; + bool printBGColors; + bool printBGImages; + short printRange; + nsString title; + nsString docURL; + nsString headerStrLeft; + nsString headerStrCenter; + nsString headerStrRight; + nsString footerStrLeft; + nsString footerStrCenter; + nsString footerStrRight; + + short howToEnableFrameUI; + bool isCancelled; + short printFrameTypeUsage; + short printFrameType; + bool printSilent; + bool shrinkToFit; + bool showPrintProgress; + + nsString paperName; + short paperSizeType; + short paperData; + double paperWidth; + double paperHeight; + short paperSizeUnit; + nsString plexName; + nsString colorspace; + nsString resolutionName; + bool downloadFonts; + bool printReversed; + bool printInColor; + int32_t orientation; + nsString printCommand; + int32_t numCopies; + nsString printerName; + bool printToFile; + nsString toFileName; + short outputFormat; + int32_t printPageDelay; + int32_t resolution; + int32_t duplex; + bool isInitializedFromPrinter; + bool isInitializedFromPrefs; + bool persistMarginBoxSettings; + + /* Windows-specific things */ + nsString driverName; + nsString deviceName; + bool isFramesetDocument; + bool isFramesetFrameSelected; + bool isIFrameSelected; + bool isRangeSelection; + + /* TODO: OS X specific things - specifically, an array of names for the + * document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames + */ +}; + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp b/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp new file mode 100644 index 000000000000..7b268cdbaf24 --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp @@ -0,0 +1,34 @@ +/* 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 "PrintSettingsDialogChild.h" + +using mozilla::unused; + +namespace mozilla { +namespace embedding { + +MOZ_IMPLICIT PrintSettingsDialogChild::PrintSettingsDialogChild() +: mReturned(false) +{ + MOZ_COUNT_CTOR(PrintSettingsDialogChild); +} + +MOZ_IMPLICIT PrintSettingsDialogChild::~PrintSettingsDialogChild() +{ + MOZ_COUNT_DTOR(PrintSettingsDialogChild); +} + +bool +PrintSettingsDialogChild::Recv__delete__(const nsresult& aResult, + const PrintData& aData) +{ + mResult = aResult; + mData = aData; + mReturned = true; + return true; +} + +} // namespace embedding +} // namespace mozilla diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogChild.h b/embedding/components/printingui/ipc/PrintSettingsDialogChild.h new file mode 100644 index 000000000000..292cd169b58e --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogChild.h @@ -0,0 +1,36 @@ +/* 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 mozilla_embedding_PrintSettingsDialogChild_h +#define mozilla_embedding_PrintSettingsDialogChild_h + +#include "mozilla/embedding/PPrintSettingsDialogChild.h" +namespace mozilla { +namespace embedding { + +class PrintSettingsDialogChild MOZ_FINAL : public PPrintSettingsDialogChild +{ + NS_INLINE_DECL_REFCOUNTING(PrintSettingsDialogChild) + +public: + MOZ_IMPLICIT PrintSettingsDialogChild(); + + virtual bool Recv__delete__(const nsresult& aResult, + const PrintData& aData) MOZ_OVERRIDE; + + bool returned() { return mReturned; }; + nsresult result() { return mResult; }; + PrintData data() { return mData; }; + +private: + virtual ~PrintSettingsDialogChild(); + bool mReturned; + nsresult mResult; + PrintData mData; +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp b/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp new file mode 100644 index 000000000000..721425b2c5ec --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp @@ -0,0 +1,28 @@ +/* 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 "PrintSettingsDialogParent.h" + +// C++ file contents +namespace mozilla { +namespace embedding { + +MOZ_IMPLICIT PrintSettingsDialogParent::PrintSettingsDialogParent() +{ + MOZ_COUNT_CTOR(PrintSettingsDialogParent); +} + +MOZ_IMPLICIT PrintSettingsDialogParent::~PrintSettingsDialogParent() +{ + MOZ_COUNT_DTOR(PrintSettingsDialogParent); +} + +void +PrintSettingsDialogParent::ActorDestroy(ActorDestroyReason aWhy) +{ +} + +} // namespace embedding +} // namespace mozilla + diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogParent.h b/embedding/components/printingui/ipc/PrintSettingsDialogParent.h new file mode 100644 index 000000000000..231a25a9f2be --- /dev/null +++ b/embedding/components/printingui/ipc/PrintSettingsDialogParent.h @@ -0,0 +1,29 @@ +/* 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 mozilla_embedding_PrintSettingsDialogParent_h +#define mozilla_embedding_PrintSettingsDialogParent_h + +#include "mozilla/embedding/PPrintSettingsDialogParent.h" + +// Header file contents +namespace mozilla { +namespace embedding { + +class PrintSettingsDialogParent MOZ_FINAL : public PPrintSettingsDialogParent +{ +public: + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + MOZ_IMPLICIT PrintSettingsDialogParent(); + +private: + virtual ~PrintSettingsDialogParent(); +}; + +} // namespace embedding +} // namespace mozilla + +#endif diff --git a/embedding/components/printingui/ipc/PrintingParent.cpp b/embedding/components/printingui/ipc/PrintingParent.cpp index f051c237beb8..03071a902149 100644 --- a/embedding/components/printingui/ipc/PrintingParent.cpp +++ b/embedding/components/printingui/ipc/PrintingParent.cpp @@ -18,6 +18,7 @@ #include "PrintingParent.h" #include "PrintDataUtils.h" #include "PrintProgressDialogParent.h" +#include "PrintSettingsDialogParent.h" using namespace mozilla; using namespace mozilla::dom; @@ -65,50 +66,58 @@ PrintingParent::RecvShowProgress(PBrowserParent* parent, return true; } -bool -PrintingParent::RecvShowPrintDialog(PBrowserParent* parent, - const PrintData& data, - PrintData* retVal, - bool* success) +nsresult +PrintingParent::ShowPrintDialog(PBrowserParent* aParent, + const PrintData& aData, + PrintData* aResult) { - *success = false; - - nsCOMPtr parentWin = DOMWindowFromBrowserParent(parent); + nsCOMPtr parentWin = DOMWindowFromBrowserParent(aParent); if (!parentWin) { - return true; + return NS_ERROR_FAILURE; } nsCOMPtr pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1")); if (!pps) { - return true; + return NS_ERROR_FAILURE; } // The initSettings we got can be wrapped using // PrintDataUtils' MockWebBrowserPrint, which implements enough of // nsIWebBrowserPrint to keep the dialogs happy. - nsCOMPtr wbp = new MockWebBrowserPrint(data); + nsCOMPtr wbp = new MockWebBrowserPrint(aData); nsresult rv; nsCOMPtr po = do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv); - NS_ENSURE_SUCCESS(rv, true); + NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr settings; rv = po->CreatePrintSettings(getter_AddRefs(settings)); - NS_ENSURE_SUCCESS(rv, true); + NS_ENSURE_SUCCESS(rv, rv); - rv = po->DeserializeToPrintSettings(data, settings); - NS_ENSURE_SUCCESS(rv, true); + rv = po->DeserializeToPrintSettings(aData, settings); + NS_ENSURE_SUCCESS(rv, rv); rv = pps->ShowPrintDialog(parentWin, wbp, settings); - NS_ENSURE_SUCCESS(rv, true); + NS_ENSURE_SUCCESS(rv, rv); // And send it back. - PrintData result; - rv = po->SerializeToPrintData(settings, nullptr, &result); - NS_ENSURE_SUCCESS(rv, true); + rv = po->SerializeToPrintData(settings, nullptr, aResult); + return rv; +} - *retVal = result; - *success = true; +bool +PrintingParent::RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog, + PBrowserParent* aParent, + const PrintData& aData) +{ + PrintData resultData; + nsresult rv = ShowPrintDialog(aParent, aData, &resultData); + + // The child has been spinning an event loop while waiting + // to hear about the print settings. We return the results + // with an async message which frees the child process from + // its nested event loop. + mozilla::unused << aDialog->Send__delete__(aDialog, rv, resultData); return true; } @@ -157,6 +166,19 @@ PrintingParent::DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* do return true; } +PPrintSettingsDialogParent* +PrintingParent::AllocPPrintSettingsDialogParent() +{ + return new PrintSettingsDialogParent(); +} + +bool +PrintingParent::DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aDoomed) +{ + delete aDoomed; + return true; +} + void PrintingParent::ActorDestroy(ActorDestroyReason aWhy) { diff --git a/embedding/components/printingui/ipc/PrintingParent.h b/embedding/components/printingui/ipc/PrintingParent.h index af66100a9748..ee406425c5f8 100644 --- a/embedding/components/printingui/ipc/PrintingParent.h +++ b/embedding/components/printingui/ipc/PrintingParent.h @@ -9,9 +9,10 @@ #include "mozilla/dom/PBrowserParent.h" #include "mozilla/embedding/PPrintingParent.h" -#include "mozilla/embedding/PPrintProgressDialogParent.h" class nsIDOMWindow; +class PPrintProgressDialogParent; +class PPrintSettingsDialogParent; namespace mozilla { namespace embedding { @@ -26,16 +27,15 @@ public: bool* notifyOnOpen, bool* success); virtual bool - RecvShowPrintDialog(PBrowserParent* parent, - const PrintData& initSettings, - PrintData* retVal, - bool* success); + RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog, + PBrowserParent* aParent, + const PrintData& aData); virtual bool - RecvSavePrintSettings(const PrintData& aData, - const bool& aUsePrinterNamePrefix, - const uint32_t& aFlags, - nsresult* aResult); + RecvSavePrintSettings(const PrintData& data, + const bool& usePrinterNamePrefix, + const uint32_t& flags, + nsresult* rv); virtual PPrintProgressDialogParent* AllocPPrintProgressDialogParent(); @@ -43,6 +43,12 @@ public: virtual bool DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* aActor); + virtual PPrintSettingsDialogParent* + AllocPPrintSettingsDialogParent(); + + virtual bool + DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aActor); + virtual void ActorDestroy(ActorDestroyReason aWhy); @@ -52,6 +58,11 @@ public: private: nsIDOMWindow* DOMWindowFromBrowserParent(PBrowserParent* parent); + + nsresult + ShowPrintDialog(PBrowserParent* parent, + const PrintData& data, + PrintData* result); }; } // namespace embedding } // namespace mozilla diff --git a/embedding/components/printingui/ipc/moz.build b/embedding/components/printingui/ipc/moz.build index 3101e0c5dda8..484c7aa5ae99 100644 --- a/embedding/components/printingui/ipc/moz.build +++ b/embedding/components/printingui/ipc/moz.build @@ -19,11 +19,15 @@ if CONFIG['NS_PRINTING']: 'PrintingParent.cpp', 'PrintProgressDialogChild.cpp', 'PrintProgressDialogParent.cpp', + 'PrintSettingsDialogChild.cpp', + 'PrintSettingsDialogParent.cpp', ] IPDL_SOURCES += [ 'PPrinting.ipdl', + 'PPrintingTypes.ipdlh', 'PPrintProgressDialog.ipdl', + 'PPrintSettingsDialog.ipdl', ] include('/ipc/chromium/chromium-config.mozbuild') diff --git a/embedding/components/printingui/ipc/nsPrintingProxy.cpp b/embedding/components/printingui/ipc/nsPrintingProxy.cpp index a2eb33915d58..730850e4244a 100644 --- a/embedding/components/printingui/ipc/nsPrintingProxy.cpp +++ b/embedding/components/printingui/ipc/nsPrintingProxy.cpp @@ -95,17 +95,24 @@ nsPrintingProxy::ShowPrintDialog(nsIDOMWindow *parent, rv = po->SerializeToPrintData(printSettings, webBrowserPrint, &inSettings); NS_ENSURE_SUCCESS(rv, rv); - PrintData modifiedSettings; - bool success; + // Now, the waiting game. The parent process should be showing + // the printing dialog soon. In the meantime, we need to spin a + // nested event loop while we wait for the results of the dialog + // to be returned to us. - mozilla::unused << SendShowPrintDialog(pBrowser, inSettings, &modifiedSettings, &success); + nsRefPtr dialog = new PrintSettingsDialogChild(); + SendPPrintSettingsDialogConstructor(dialog); - if (!success) { - // Something failed in the parent. - return NS_ERROR_FAILURE; + mozilla::unused << SendShowPrintDialog(dialog, pBrowser, inSettings); + + while(!dialog->returned()) { + NS_ProcessNextEvent(nullptr, true); } - rv = po->DeserializeToPrintSettings(modifiedSettings, printSettings); + rv = dialog->result(); + NS_ENSURE_SUCCESS(rv, rv); + + rv = po->DeserializeToPrintSettings(dialog->data(), printSettings); return NS_OK; } @@ -206,3 +213,21 @@ nsPrintingProxy::DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aAc "called on nsPrintingProxy."); return false; } + +PPrintSettingsDialogChild* +nsPrintingProxy::AllocPPrintSettingsDialogChild() +{ + // The parent process will never initiate the PPrintSettingsDialog + // protocol connection, so no need to provide an allocator here. + NS_NOTREACHED("Allocator for PPrintSettingsDialogChild should not be " + "called on nsPrintingProxy."); + return nullptr; +} + +bool +nsPrintingProxy::DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor) +{ + // The PrintSettingsDialogChild implements refcounting, and + // will take itself out. + return true; +} diff --git a/embedding/components/printingui/ipc/nsPrintingProxy.h b/embedding/components/printingui/ipc/nsPrintingProxy.h index 3fc91b31b4c4..1485406d14a6 100644 --- a/embedding/components/printingui/ipc/nsPrintingProxy.h +++ b/embedding/components/printingui/ipc/nsPrintingProxy.h @@ -33,6 +33,12 @@ public: virtual bool DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor) MOZ_OVERRIDE; + + virtual PPrintSettingsDialogChild* + AllocPPrintSettingsDialogChild() MOZ_OVERRIDE; + + virtual bool + DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor) MOZ_OVERRIDE; }; #endif From 1129ae3cbd124a9cbdda55396e98e574b92d7fe4 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sat, 7 Mar 2015 14:37:31 -0800 Subject: [PATCH 27/42] Backed out 2 changesets (bug 1138181, bug 1132874) for e10s crashes in browser_windowopen_reflows.js CLOSED TREE Backed out changeset fdf4671db324 (bug 1132874) Backed out changeset ddd5517ce7d2 (bug 1138181) --- dom/plugins/ipc/PluginWidgetParent.cpp | 38 +++++++++++--------------- dom/plugins/ipc/PluginWidgetParent.h | 1 - gfx/layers/ipc/CompositorChild.cpp | 2 ++ gfx/layers/ipc/CompositorParent.cpp | 4 +-- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/dom/plugins/ipc/PluginWidgetParent.cpp b/dom/plugins/ipc/PluginWidgetParent.cpp index 367018a5be2f..528ee69cf52a 100644 --- a/dom/plugins/ipc/PluginWidgetParent.cpp +++ b/dom/plugins/ipc/PluginWidgetParent.cpp @@ -70,7 +70,18 @@ PluginWidgetParent::~PluginWidgetParent() // A destroy call can actually get skipped if a widget is associated // with the last out-of-process page, make sure and cleanup any left // over widgets if we have them. - KillWidget(); + if (mWidget) { +#if defined(MOZ_WIDGET_GTK) + mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0); + mWrapper = nullptr; +#elif defined(XP_WIN) + ::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW), + kPluginWidgetParentProperty); +#endif + mWidget->UnregisterPluginWindowForRemoteUpdates(); + mWidget->Destroy(); + mWidget = nullptr; + } } mozilla::dom::TabParent* @@ -180,30 +191,14 @@ PluginWidgetParent::RecvCreate(nsresult* aResult) return true; } -void -PluginWidgetParent::KillWidget() -{ - PWLOG("PluginWidgetParent::KillWidget() widget=%p\n", mWidget); - if (mWidget) { -#if defined(MOZ_WIDGET_GTK) - mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0); - mWrapper = nullptr; -#elif defined(XP_WIN) - ::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW), - kPluginWidgetParentProperty); -#endif - mWidget->UnregisterPluginWindowForRemoteUpdates(); - mWidget->Destroy(); - mWidget = nullptr; - } -} - void PluginWidgetParent::Shutdown(ShutdownType aType) { - PWLOG("PluginWidgetParent::Shutdown(%s)\n", aType == TAB_CLOSURE ? "TAB_CLOSURE" : "CONTENT"); if (mWidget) { - KillWidget(); + mWidget->UnregisterPluginWindowForRemoteUpdates(); + DebugOnly rv = mWidget->Destroy(); + NS_ASSERTION(NS_SUCCEEDED(rv), "widget destroy failure"); + mWidget = nullptr; unused << SendParentShutdown(aType); } } @@ -212,7 +207,6 @@ void PluginWidgetParent::ActorDestroy(ActorDestroyReason aWhy) { PWLOG("PluginWidgetParent::ActorDestroy()\n"); - KillWidget(); } // Called by TabParent's Destroy() in response to an early tear down (Early diff --git a/dom/plugins/ipc/PluginWidgetParent.h b/dom/plugins/ipc/PluginWidgetParent.h index dd0d4ba6d9a1..4e80cf14b44e 100644 --- a/dom/plugins/ipc/PluginWidgetParent.h +++ b/dom/plugins/ipc/PluginWidgetParent.h @@ -63,7 +63,6 @@ public: private: void Shutdown(ShutdownType aType); - void KillWidget(); // The chrome side native widget. nsCOMPtr mWidget; diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index e163269209d2..bd48f99b6831 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -252,6 +252,8 @@ CompositorChild::RecvUpdatePluginConfigurations(const nsIntPoint& aContentOffset // Handle invalidation, this can be costly, avoid if it is not needed. if (isVisible) { // invalidate region (widget origin) + nsIntRect bounds = aPlugins[pluginsIdx].bounds(); + nsIntRect rect(0, 0, bounds.width, bounds.height); #if defined(XP_WIN) // Work around for flash's crummy sandbox. See bug 762948. This call // digs down into the window hirearchy, invalidating regions on diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 4b656d531b6b..76d34928cf09 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -1818,7 +1818,8 @@ UpdatePluginWindowState(uint64_t aId) } bool shouldComposePlugin = !!lts.mRoot && - !!lts.mRoot->GetParent(); + !!lts.mRoot->GetParent() && + lts.mUpdatedPluginDataAvailable; bool shouldHidePlugin = (!lts.mRoot || !lts.mRoot->GetParent()) && @@ -1831,7 +1832,6 @@ UpdatePluginWindowState(uint64_t aId) // calculating clipping. nsTArray aVisibleIdList; unused << lts.mParent->SendUpdatePluginVisibility(aVisibleIdList); - lts.mUpdatedPluginDataAvailable = false; return; } From 7b1faeab4d8d1229a6c785d6455144ac9750fcb7 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Sat, 7 Mar 2015 12:35:27 -0500 Subject: [PATCH 28/42] Bug 1140497 - add more roles into markup map, r=marcoz --- accessible/base/MarkupMap.h | 16 ++++++++-------- accessible/html/HTMLElementAccessibles.cpp | 12 ------------ accessible/html/HTMLElementAccessibles.h | 2 -- accessible/html/HTMLFormControlAccessible.cpp | 18 ------------------ accessible/html/HTMLFormControlAccessible.h | 3 --- 5 files changed, 8 insertions(+), 43 deletions(-) diff --git a/accessible/base/MarkupMap.h b/accessible/base/MarkupMap.h index 7d41072ce747..8a51e5af607c 100644 --- a/accessible/base/MarkupMap.h +++ b/accessible/base/MarkupMap.h @@ -7,7 +7,7 @@ MARKUPMAP(a, New_HTMLLink, - 0) + roles::LINK) MARKUPMAP(abbr, New_HyperText, @@ -47,11 +47,11 @@ MARKUPMAP(dt, MARKUPMAP(figcaption, New_HTMLFigcaption, - 0) + roles::CAPTION) MARKUPMAP(figure, New_HTMLFigure, - 0) + roles::FIGURE) MARKUPMAP(form, New_HyperText, @@ -91,11 +91,11 @@ MARKUPMAP(h6, MARKUPMAP(label, New_HTMLLabel, - 0) + roles::LABEL) MARKUPMAP(legend, New_HTMLLegend, - 0) + roles::LABEL) MARKUPMAP(li, New_HTMLListitem, @@ -107,7 +107,7 @@ MARKUPMAP(nav, MARKUPMAP(ol, New_HTMLList, - 0) + roles::LIST) MARKUPMAP(option, New_HTMLOption, @@ -119,7 +119,7 @@ MARKUPMAP(optgroup, MARKUPMAP(output, New_HTMLOutput, - 0) + roles::SECTION) MARKUPMAP(progress, New_HTMLProgress, @@ -147,4 +147,4 @@ MARKUPMAP(th, MARKUPMAP(ul, New_HTMLList, - 0) + roles::LIST) diff --git a/accessible/html/HTMLElementAccessibles.cpp b/accessible/html/HTMLElementAccessibles.cpp index 92e797e87e66..c56740bc32fd 100644 --- a/accessible/html/HTMLElementAccessibles.cpp +++ b/accessible/html/HTMLElementAccessibles.cpp @@ -75,12 +75,6 @@ HTMLLabelAccessible::RelationByType(RelationType aType) return rel; } -role -HTMLLabelAccessible::NativeRole() -{ - return roles::LABEL; -} - //////////////////////////////////////////////////////////////////////////////// // nsHTMLOuputAccessible //////////////////////////////////////////////////////////////////////////////// @@ -97,12 +91,6 @@ HTMLOutputAccessible::RelationByType(RelationType aType) return rel; } -role -HTMLOutputAccessible::NativeRole() -{ - return roles::SECTION; -} - already_AddRefed HTMLOutputAccessible::NativeAttributes() { diff --git a/accessible/html/HTMLElementAccessibles.h b/accessible/html/HTMLElementAccessibles.h index 09d6ed3ee287..ae81c43558e8 100644 --- a/accessible/html/HTMLElementAccessibles.h +++ b/accessible/html/HTMLElementAccessibles.h @@ -60,7 +60,6 @@ public: NS_DECL_ISUPPORTS_INHERITED // Accessible - virtual a11y::role NativeRole() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; protected: @@ -81,7 +80,6 @@ public: NS_DECL_ISUPPORTS_INHERITED // Accessible - virtual a11y::role NativeRole() MOZ_OVERRIDE; virtual already_AddRefed NativeAttributes() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; diff --git a/accessible/html/HTMLFormControlAccessible.cpp b/accessible/html/HTMLFormControlAccessible.cpp index 9d655bbee6e4..d2eb8897f138 100644 --- a/accessible/html/HTMLFormControlAccessible.cpp +++ b/accessible/html/HTMLFormControlAccessible.cpp @@ -762,12 +762,6 @@ HTMLLegendAccessible::RelationByType(RelationType aType) return rel; } -role -HTMLLegendAccessible::NativeRole() -{ - return roles::LABEL; -} - //////////////////////////////////////////////////////////////////////////////// // HTMLFigureAccessible //////////////////////////////////////////////////////////////////////////////// @@ -790,12 +784,6 @@ HTMLFigureAccessible::NativeAttributes() return attributes.forget(); } -role -HTMLFigureAccessible::NativeRole() -{ - return roles::FIGURE; -} - ENameValueFlag HTMLFigureAccessible::NativeName(nsString& aName) { @@ -844,12 +832,6 @@ HTMLFigcaptionAccessible:: { } -role -HTMLFigcaptionAccessible::NativeRole() -{ - return roles::CAPTION; -} - Relation HTMLFigcaptionAccessible::RelationByType(RelationType aType) { diff --git a/accessible/html/HTMLFormControlAccessible.h b/accessible/html/HTMLFormControlAccessible.h index b8e2935ba55c..12356f76cc55 100644 --- a/accessible/html/HTMLFormControlAccessible.h +++ b/accessible/html/HTMLFormControlAccessible.h @@ -243,7 +243,6 @@ public: HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc); // Accessible - virtual mozilla::a11y::role NativeRole() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; }; @@ -257,7 +256,6 @@ public: // Accessible virtual already_AddRefed NativeAttributes() MOZ_OVERRIDE; - virtual mozilla::a11y::role NativeRole() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; protected: @@ -278,7 +276,6 @@ public: HTMLFigcaptionAccessible(nsIContent* aContent, DocAccessible* aDoc); // Accessible - virtual mozilla::a11y::role NativeRole() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; }; From ed7eebd0f5b040a6b7ff53fdd8315938474cae75 Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Sat, 7 Mar 2015 17:05:21 -0600 Subject: [PATCH 29/42] Bug 1139474 - Watch for unboxed object properties when attaching Ion SETPROP ICs, r=jandem. --- js/src/jit/IonCaches.cpp | 3 +++ js/src/vm/Shape.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index dc3d6cb66ea6..9e2217ab64c2 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -2933,6 +2933,9 @@ CanAttachNativeSetProp(JSContext *cx, HandleObject obj, HandleId id, ConstantOrR if (!shape || (obj != holder && shape->hasDefaultSetter() && shape->hasSlot())) return SetPropertyIC::MaybeCanAttachAddSlot; + if (IsImplicitNonNativeProperty(shape)) + return SetPropertyIC::CanAttachNone; + if (IsCacheableSetPropCallPropertyOp(obj, holder, shape) || IsCacheableSetPropCallNative(obj, holder, shape) || IsCacheableSetPropCallScripted(obj, holder, shape)) diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index d176e17186ce..62096f6648cd 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -1549,6 +1549,12 @@ IsImplicitDenseOrTypedArrayElement(Shape *prop) return prop == reinterpret_cast(1); } +static inline bool +IsImplicitNonNativeProperty(Shape *prop) +{ + return prop == reinterpret_cast(1); +} + Shape * ReshapeForParentAndAllocKind(JSContext *cx, Shape *shape, TaggedProto proto, JSObject *parent, gc::AllocKind allocKind); From fd4b4808713782f306d2e09b66321ca640373636 Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Sat, 7 Mar 2015 17:11:02 -0600 Subject: [PATCH 30/42] Bug 1138912 - Watch for MNewObject instructions without a template object when recovering, r=jandem. --- js/src/jit/MIR.h | 2 +- js/src/jit/Recover.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index b65e68ad7e09..ba1c7fbbb4eb 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -3058,7 +3058,7 @@ class MNewObject bool canRecoverOnBailout() const MOZ_OVERRIDE { // The template object can safely be used in the recover instruction // because it can never be mutated by any other function execution. - return true; + return templateObject() != nullptr; } }; diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 3a348b594970..f9fe7a28ab68 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -1171,7 +1171,7 @@ RNewObject::RNewObject(CompactBufferReader &reader) bool RNewObject::recover(JSContext *cx, SnapshotIterator &iter) const { - RootedPlainObject templateObject(cx, &iter.read().toObject().as()); + RootedObject templateObject(cx, &iter.read().toObject()); RootedValue result(cx); JSObject *resultObject = nullptr; @@ -1180,7 +1180,7 @@ RNewObject::recover(JSContext *cx, SnapshotIterator &iter) const resultObject = NewObjectOperationWithTemplate(cx, templateObject); } else { MOZ_ASSERT(mode_ == MNewObject::ObjectCreate); - resultObject = ObjectCreateWithTemplate(cx, templateObject); + resultObject = ObjectCreateWithTemplate(cx, templateObject.as()); } if (!resultObject) From 15e050bbb2452a9cbc145bd6bf15c6bb346080c5 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Sat, 7 Mar 2015 17:29:05 -0600 Subject: [PATCH 31/42] Bug 1138181 - Be more aggressive in updating plugin geometry in the compositor, avoids filtering out important offset updates that don't involve remote layer tree updates. r=roc --- gfx/layers/ipc/CompositorParent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 76d34928cf09..4b656d531b6b 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -1818,8 +1818,7 @@ UpdatePluginWindowState(uint64_t aId) } bool shouldComposePlugin = !!lts.mRoot && - !!lts.mRoot->GetParent() && - lts.mUpdatedPluginDataAvailable; + !!lts.mRoot->GetParent(); bool shouldHidePlugin = (!lts.mRoot || !lts.mRoot->GetParent()) && @@ -1832,6 +1831,7 @@ UpdatePluginWindowState(uint64_t aId) // calculating clipping. nsTArray aVisibleIdList; unused << lts.mParent->SendUpdatePluginVisibility(aVisibleIdList); + lts.mUpdatedPluginDataAvailable = false; return; } From bb6fd0650f34efa288f134944fd23d96b49cd8ee Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Sat, 7 Mar 2015 20:20:17 -0500 Subject: [PATCH 32/42] Bug 1140500 - add object attributes declaration into markup map, r=marcoz --- accessible/base/MarkupMap.h | 16 ++++-- accessible/base/nsAccessibilityService.cpp | 51 ++++++++++++++++++- accessible/base/nsAccessibilityService.h | 16 ++++++ accessible/generic/HyperTextAccessible.cpp | 21 +------- accessible/html/HTMLElementAccessibles.cpp | 12 ----- accessible/html/HTMLElementAccessibles.h | 1 - accessible/html/HTMLFormControlAccessible.cpp | 14 +---- accessible/html/HTMLFormControlAccessible.h | 1 - dom/base/nsGkAtomList.h | 1 + 9 files changed, 80 insertions(+), 53 deletions(-) diff --git a/accessible/base/MarkupMap.h b/accessible/base/MarkupMap.h index 8a51e5af607c..286c8bc1b421 100644 --- a/accessible/base/MarkupMap.h +++ b/accessible/base/MarkupMap.h @@ -19,7 +19,8 @@ MARKUPMAP(acronym, MARKUPMAP(article, New_HyperText, - roles::DOCUMENT) + roles::DOCUMENT, + Attr(xmlroles, article)) MARKUPMAP(aside, New_HyperText, @@ -51,7 +52,8 @@ MARKUPMAP(figcaption, MARKUPMAP(figure, New_HTMLFigure, - roles::FIGURE) + roles::FIGURE, + Attr(xmlroles, figure)) MARKUPMAP(form, New_HyperText, @@ -119,7 +121,8 @@ MARKUPMAP(optgroup, MARKUPMAP(output, New_HTMLOutput, - roles::SECTION) + roles::SECTION, + Attr(live, polite)) MARKUPMAP(progress, New_HTMLProgress, @@ -131,11 +134,14 @@ MARKUPMAP(q, MARKUPMAP(section, New_HyperText, - roles::SECTION) + roles::SECTION, + Attr(xmlroles, region)) MARKUPMAP(time, New_HyperText, - 0) + 0, + Attr(xmlroles, time), + AttrFromDOM(datetime, datetime)) MARKUPMAP(td, New_HTMLTableHeaderCellIfScope, diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index a540ade4687b..07ab4d621d67 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -220,13 +220,25 @@ New_HTMLTableHeaderCellIfScope(nsIContent* aContent, Accessible* aContext) //////////////////////////////////////////////////////////////////////////////// // Markup maps array. -#define MARKUPMAP(atom, new_func, r) \ - { &nsGkAtoms::atom, new_func, static_cast(r) }, +#define Attr(name, value) \ + { &nsGkAtoms::name, &nsGkAtoms::value } + +#define AttrFromDOM(name, DOMAttrName) \ + { &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName } + +#define AttrFromDOMIf(name, DOMAttrName, DOMAttrValue) \ + { &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName, &nsGkAtoms::DOMAttrValue } + +#define MARKUPMAP(atom, new_func, r, ... ) \ + { &nsGkAtoms::atom, new_func, static_cast(r), { __VA_ARGS__ } }, static const MarkupMapInfo sMarkupMapList[] = { #include "MarkupMap.h" }; +#undef Attr +#undef AttrFromDOM +#undef AttrFromDOMIf #undef MARKUPMAP //////////////////////////////////////////////////////////////////////////////// @@ -1610,6 +1622,41 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame, return newAcc.forget(); } +void +nsAccessibilityService::MarkupAttributes(const nsIContent* aContent, + nsIPersistentProperties* aAttributes) const +{ + const mozilla::a11y::MarkupMapInfo* markupMap = + mMarkupMaps.Get(aContent->NodeInfo()->NameAtom()); + if (!markupMap) + return; + + for (uint32_t i = 0; i < ArrayLength(markupMap->attrs); i++) { + const MarkupAttrInfo* info = markupMap->attrs + i; + if (!info->name) + break; + + if (info->DOMAttrName) { + if (info->DOMAttrValue) { + if (aContent->AttrValueIs(kNameSpaceID_None, *info->DOMAttrName, + *info->DOMAttrValue, eCaseMatters)) { + nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->DOMAttrValue); + } + continue; + } + + nsAutoString value; + aContent->GetAttr(kNameSpaceID_None, *info->DOMAttrName, value); + if (!value.IsEmpty()) + nsAccUtils::SetAccAttr(aAttributes, *info->name, value); + + continue; + } + + nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->value); + } +} + //////////////////////////////////////////////////////////////////////////////// // nsIAccessibilityService (DON'T put methods here) diff --git a/accessible/base/nsAccessibilityService.h b/accessible/base/nsAccessibilityService.h index 586eddd446c6..7761058e9a3c 100644 --- a/accessible/base/nsAccessibilityService.h +++ b/accessible/base/nsAccessibilityService.h @@ -17,6 +17,7 @@ #include "nsIObserver.h" class nsImageFrame; +class nsIPersistentProperties; class nsPluginFrame; class nsITreeView; @@ -44,10 +45,19 @@ xpcAccessibleApplication* XPCApplicationAcc(); typedef Accessible* (New_Accessible)(nsIContent* aContent, Accessible* aContext); +struct MarkupAttrInfo { + nsIAtom** name; + nsIAtom** value; + + nsIAtom** DOMAttrName; + nsIAtom** DOMAttrValue; +}; + struct MarkupMapInfo { nsIAtom** tag; New_Accessible* new_func; a11y::role role; + MarkupAttrInfo attrs[2]; }; } // namespace a11y @@ -182,6 +192,12 @@ public: return markupMap ? markupMap->role : mozilla::a11y::roles::NOTHING; } + /** + * Set the object attribute defined by markup for the given element. + */ + void MarkupAttributes(const nsIContent* aContent, + nsIPersistentProperties* aAttributes) const; + private: // nsAccessibilityService creation is controlled by friend // NS_GetAccessibilityService, keep constructors private. diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 1992b219a71a..bba558296b77 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -977,25 +977,8 @@ HyperTextAccessible::NativeAttributes() } } - if (!HasOwnContent()) - return attributes.forget(); - - if (mContent->IsHTMLElement(nsGkAtoms::section)) { - nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, - NS_LITERAL_STRING("region")); - } else if (mContent->IsHTMLElement(nsGkAtoms::article)) { - nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, - NS_LITERAL_STRING("article")); - } else if (mContent->IsHTMLElement(nsGkAtoms::time)) { - nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, - NS_LITERAL_STRING("time")); - - if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::datetime)) { - nsAutoString datetime; - mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::datetime, datetime); - nsAccUtils::SetAccAttr(attributes, nsGkAtoms::datetime, datetime); - } - } + if (HasOwnContent()) + GetAccService()->MarkupAttributes(mContent, attributes); return attributes.forget(); } diff --git a/accessible/html/HTMLElementAccessibles.cpp b/accessible/html/HTMLElementAccessibles.cpp index c56740bc32fd..938abc178e8f 100644 --- a/accessible/html/HTMLElementAccessibles.cpp +++ b/accessible/html/HTMLElementAccessibles.cpp @@ -90,15 +90,3 @@ HTMLOutputAccessible::RelationByType(RelationType aType) return rel; } - -already_AddRefed -HTMLOutputAccessible::NativeAttributes() -{ - nsCOMPtr attributes = - AccessibleWrap::NativeAttributes(); - nsAccUtils::SetAccAttr(attributes, nsGkAtoms::live, - NS_LITERAL_STRING("polite")); - - return attributes.forget(); -} - diff --git a/accessible/html/HTMLElementAccessibles.h b/accessible/html/HTMLElementAccessibles.h index ae81c43558e8..397d59c5e18f 100644 --- a/accessible/html/HTMLElementAccessibles.h +++ b/accessible/html/HTMLElementAccessibles.h @@ -80,7 +80,6 @@ public: NS_DECL_ISUPPORTS_INHERITED // Accessible - virtual already_AddRefed NativeAttributes() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; protected: diff --git a/accessible/html/HTMLFormControlAccessible.cpp b/accessible/html/HTMLFormControlAccessible.cpp index d2eb8897f138..27fe73e900a7 100644 --- a/accessible/html/HTMLFormControlAccessible.cpp +++ b/accessible/html/HTMLFormControlAccessible.cpp @@ -89,7 +89,7 @@ HTMLCheckboxAccessible::NativeState() if (input->Checked()) return state | states::CHECKED; - + return state; } @@ -772,18 +772,6 @@ HTMLFigureAccessible:: { } -already_AddRefed -HTMLFigureAccessible::NativeAttributes() -{ - nsCOMPtr attributes = - HyperTextAccessibleWrap::NativeAttributes(); - - // Expose figure xml-role. - nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, - NS_LITERAL_STRING("figure")); - return attributes.forget(); -} - ENameValueFlag HTMLFigureAccessible::NativeName(nsString& aName) { diff --git a/accessible/html/HTMLFormControlAccessible.h b/accessible/html/HTMLFormControlAccessible.h index 12356f76cc55..8e5be8638226 100644 --- a/accessible/html/HTMLFormControlAccessible.h +++ b/accessible/html/HTMLFormControlAccessible.h @@ -255,7 +255,6 @@ public: HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc); // Accessible - virtual already_AddRefed NativeAttributes() MOZ_OVERRIDE; virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE; protected: diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 651eaca938a4..6eca907de9d8 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -2289,6 +2289,7 @@ GK_ATOM(mixed, "mixed") GK_ATOM(multiline, "multiline") GK_ATOM(navigation, "navigation") GK_ATOM(password, "password") +GK_ATOM(polite, "polite") GK_ATOM(posinset, "posinset") GK_ATOM(presentation, "presentation") GK_ATOM(progressbar, "progressbar") From d47a9820a5d35178f0fc9c5be44b7501d6a2df41 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Fri, 6 Mar 2015 19:37:37 +0200 Subject: [PATCH 33/42] Bug 1139972 - IPC Proxy for charAt, r=tbsaunde --HG-- extra : rebase_source : 23a21c190d67960a0d9962c8fd1c6ff0ff870644 --- accessible/atk/nsMaiInterfaceText.cpp | 20 +++++++++++++------- accessible/ipc/DocAccessibleChild.cpp | 11 +++++++++++ accessible/ipc/DocAccessibleChild.h | 4 ++++ accessible/ipc/PDocAccessible.ipdl | 1 + accessible/ipc/ProxyAccessible.cpp | 8 ++++++++ accessible/ipc/ProxyAccessible.h | 2 ++ 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index 3468fc1ea1d0..38b7e24a0246 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -183,15 +183,21 @@ static gunichar getCharacterAtOffsetCB(AtkText* aText, gint aOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return 0; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return 0; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return 0; + // char16_t is unsigned short in Mozilla, gnuichar is guint32 in glib. + return static_cast(text->CharAt(aOffset)); + } - // char16_t is unsigned short in Mozilla, gnuichar is guint32 in glib. - return static_cast(text->CharAt(aOffset)); + if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + return static_cast(proxy->CharAt(aOffset)); + } + + return 0; } static gchar* diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index 2d7b413c604f..3d326d5c1ae3 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -292,5 +292,16 @@ DocAccessibleChild::RecvGetTextBeforeOffset(const uint64_t& aID, return true; } +bool +DocAccessibleChild::RecvCharAt(const uint64_t& aID, + const int32_t& aOffset, + uint16_t* aChar) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + *aChar = acc && acc->IsTextRole() ? + static_cast(acc->CharAt(aOffset)) : 0; + return true; +} + } } diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 3b798f69980b..1badf8976c83 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -90,6 +90,10 @@ public: nsString* aText, int32_t* aStartOffset, int32_t* aEndOffset) MOZ_OVERRIDE; + virtual bool RecvCharAt(const uint64_t& aID, + const int32_t& aOffset, + uint16_t* aChar) MOZ_OVERRIDE; + private: DocAccessible* mDoc; }; diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 21be62a09227..1ee77ab2e27b 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -75,6 +75,7 @@ child: returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset); prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType) returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset); + prio(high) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar); }; } diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index 3ef225ff06c1..9159ad4e8026 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -202,5 +202,13 @@ ProxyAccessible::GetTextBeforeOffset(int32_t aOffset, &aText, aStartOffset, aEndOffset); } +char16_t +ProxyAccessible::CharAt(int32_t aOffset) +{ + uint16_t retval = 0; + unused << mDoc->SendCharAt(mID, aOffset, &retval); + return static_cast(retval); +} + } } diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index 7c89f3dd8524..e584cb19d861 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -120,6 +120,8 @@ public: nsString& aText, int32_t* aStartOffset, int32_t* aEndOffset); + char16_t CharAt(int32_t aOffset); + /** * Allow the platform to store a pointers worth of data on us. */ From 72cda11ebfb1b71df7ae5148229854c0c002f234 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Fri, 6 Mar 2015 22:43:25 +0200 Subject: [PATCH 34/42] Bug 1139887 - IPC Proxy for caretOffset, r=tbsaunde --HG-- extra : rebase_source : 0c567e44c2f5a382690da0504d725aadde8f0905 --- accessible/atk/nsMaiInterfaceText.cpp | 40 ++++++++++++++++++--------- accessible/ipc/DocAccessibleChild.cpp | 24 +++++++++++++++- accessible/ipc/DocAccessibleChild.h | 5 ++++ accessible/ipc/PDocAccessible.ipdl | 2 ++ accessible/ipc/ProxyAccessible.cpp | 16 +++++++++++ accessible/ipc/ProxyAccessible.h | 3 ++ 6 files changed, 76 insertions(+), 14 deletions(-) diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index 38b7e24a0246..081c21adc19b 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -229,14 +229,20 @@ static gint getCaretOffsetCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return 0; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return 0; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return 0; + return static_cast(text->CaretOffset()); + } - return static_cast(text->CaretOffset()); + if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + return static_cast(proxy->CaretOffset()); + } + + return 0; } static AtkAttributeSet* @@ -461,15 +467,23 @@ static gboolean setCaretOffsetCB(AtkText *aText, gint aOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return FALSE; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset)) { + return FALSE; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset)) - return FALSE; + text->SetCaretOffset(aOffset); + return TRUE; + } - text->SetCaretOffset(aOffset); - return TRUE; + if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + if (proxy->SetCaretOffset(aOffset)) { + return TRUE; + } + } + + return FALSE; } } diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index 3d326d5c1ae3..07b435801a38 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -9,7 +9,7 @@ #include "Accessible-inl.h" #include "ProxyAccessible.h" #include "Relation.h" - +#include "HyperTextAccessible-inl.h" #include "nsIPersistentProperties2.h" #include "nsISimpleEnumerator.h" @@ -207,6 +207,28 @@ DocAccessibleChild::RecvRelations(const uint64_t& aID, return true; } +bool +DocAccessibleChild::RecvCaretOffset(const uint64_t& aID, int32_t* aOffset) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + *aOffset = acc && acc->IsTextRole() ? acc->CaretOffset() : 0; + return true; +} + +bool +DocAccessibleChild::RecvSetCaretOffset(const uint64_t& aID, + const int32_t& aOffset, + bool* aRetVal) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + *aRetVal = false; + if (acc && acc->IsTextRole() && acc->IsValidOffset(aOffset)) { + *aRetVal = true; + acc->SetCaretOffset(aOffset); + } + return true; +} + bool DocAccessibleChild::RecvCharacterCount(const uint64_t& aID, int32_t* aCount) { diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 1badf8976c83..6e615fa64503 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -64,6 +64,11 @@ public: virtual bool RecvAttributes(const uint64_t& aID, nsTArray *aAttributes) MOZ_OVERRIDE; + virtual bool RecvCaretOffset(const uint64_t& aID, int32_t* aOffset) + MOZ_OVERRIDE; + virtual bool RecvSetCaretOffset(const uint64_t& aID, const int32_t& aOffset, + bool* aValid) MOZ_OVERRIDE; + virtual bool RecvCharacterCount(const uint64_t& aID, int32_t* aCount) MOZ_OVERRIDE; virtual bool RecvSelectionCount(const uint64_t& aID, int32_t* aCount) diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 1ee77ab2e27b..f418dafb2ff2 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -65,6 +65,8 @@ child: // AccessibleText // TextSubstring is getText in IDL. + prio(high) sync CaretOffset(uint64_t aID) returns(int32_t aOffset); + prio(high) sync SetCaretOffset(uint64_t aID, int32_t aOffset) returns (bool aValid); prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount); prio(high) sync SelectionCount(uint64_t aID) returns(int32_t aCount); prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index 9159ad4e8026..fbcc2f71f7f5 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -149,6 +149,22 @@ ProxyAccessible::Relations(nsTArray* aTypes, } } +int32_t +ProxyAccessible::CaretOffset() +{ + int32_t offset = 0; + unused << mDoc->SendCaretOffset(mID, &offset); + return offset; +} + +bool +ProxyAccessible::SetCaretOffset(int32_t aOffset) +{ + bool valid = false; + unused << mDoc->SendSetCaretOffset(mID, aOffset, &valid); + return valid; +} + int32_t ProxyAccessible::CharacterCount() { diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index e584cb19d861..3a1c97a2f316 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -99,6 +99,9 @@ public: void Relations(nsTArray* aTypes, nsTArray>* aTargetSets) const; + int32_t CaretOffset(); + bool SetCaretOffset(int32_t aOffset); + int32_t CharacterCount(); int32_t SelectionCount(); From 65b9bf86cc85441002bd686ec0509dfe8ace79f1 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Fri, 6 Mar 2015 22:44:02 +0200 Subject: [PATCH 35/42] Bug 1140162 - IPC Proxy for TextAttributes and DefaultTextAttributes, r=tbsaunde --HG-- extra : rebase_source : d77d53488bd03e938bd7d30d3081f9997f906bfe --- accessible/atk/nsMaiInterfaceText.cpp | 152 +++++++++++++++++--------- accessible/ipc/DocAccessibleChild.cpp | 44 +++++++- accessible/ipc/DocAccessibleChild.h | 15 +++ accessible/ipc/PDocAccessible.ipdl | 5 + accessible/ipc/ProxyAccessible.cpp | 17 +++ accessible/ipc/ProxyAccessible.h | 7 ++ 6 files changed, 184 insertions(+), 56 deletions(-) diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index 081c21adc19b..1f6ccf4441f5 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "InterfaceInitFuncs.h" - +#include "mozilla/a11y/PDocAccessible.h" #include "Accessible-inl.h" #include "HyperTextAccessible-inl.h" #include "nsMai.h" @@ -22,6 +22,65 @@ using namespace mozilla::a11y; static const char* sAtkTextAttrNames[ATK_TEXT_ATTR_LAST_DEFINED]; +void +ConvertTextAttributeToAtkAttribute(const nsACString& aName, + const nsAString& aValue, + AtkAttributeSet** aAttributeSet) +{ + // Handle attributes where atk has its own name. + const char* atkName = nullptr; + nsAutoString atkValue; + if (aName.EqualsLiteral("color")) { + // The format of the atk attribute is r,g,b and the gecko one is + // rgb(r,g,b). + atkValue = Substring(aValue, 5, aValue.Length() - 1); + atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR]; + } else if (aName.EqualsLiteral("background-color")) { + // The format of the atk attribute is r,g,b and the gecko one is + // rgb(r,g,b). + atkValue = Substring(aValue, 5, aValue.Length() - 1); + atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR]; + } else if (aName.EqualsLiteral("font-family")) { + atkValue = aValue; + atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME]; + } else if (aName.EqualsLiteral("font-size")) { + // ATK wants the number of pixels without px at the end. + atkValue = StringHead(aValue, aValue.Length() - 2); + atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE]; + } else if (aName.EqualsLiteral("font-weight")) { + atkValue = aValue; + atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT]; + } else if (aName.EqualsLiteral("invalid")) { + atkValue = aValue; + atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID]; + } + + if (atkName) { + AtkAttribute* objAttr = + static_cast(g_malloc(sizeof(AtkAttribute))); + objAttr->name = g_strdup(atkName); + objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get()); + *aAttributeSet = g_slist_prepend(*aAttributeSet, objAttr); + } +} + +static AtkAttributeSet* +ConvertToAtkTextAttributeSet(nsTArray& aAttributes) +{ + AtkAttributeSet* objAttributeSet = nullptr; + for (size_t i = 0; i < aAttributes.Length(); ++i) { + AtkAttribute* objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute)); + objAttr->name = g_strdup(aAttributes[i].Name().get()); + objAttr->value = + g_strdup(NS_ConvertUTF16toUTF8(aAttributes[i].Value()).get()); + objAttributeSet = g_slist_prepend(objAttributeSet, objAttr); + ConvertTextAttributeToAtkAttribute(aAttributes[i].Name(), + aAttributes[i].Value(), + &objAttributeSet); + } + return objAttributeSet; +} + static AtkAttributeSet* ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes) { @@ -55,40 +114,7 @@ ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes) objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get()); objAttributeSet = g_slist_prepend(objAttributeSet, objAttr); - // Handle attributes where atk has its own name. - const char* atkName = nullptr; - nsAutoString atkValue; - if (name.EqualsLiteral("color")) { - // The format of the atk attribute is r,g,b and the gecko one is - // rgb(r,g,b). - atkValue = Substring(value, 5, value.Length() - 1); - atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR]; - } else if (name.EqualsLiteral("background-color")) { - // The format of the atk attribute is r,g,b and the gecko one is - // rgb(r,g,b). - atkValue = Substring(value, 5, value.Length() - 1); - atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR]; - } else if (name.EqualsLiteral("font-family")) { - atkValue = value; - atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME]; - } else if (name.EqualsLiteral("font-size")) { - // ATK wants the number of pixels without px at the end. - atkValue = StringHead(value, value.Length() - 2); - atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE]; - } else if (name.EqualsLiteral("font-weight")) { - atkValue = value; - atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT]; - } else if (name.EqualsLiteral("invalid")) { - atkValue = value; - atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID]; - } - - if (atkName) { - objAttr = static_cast(g_malloc(sizeof(AtkAttribute))); - objAttr->name = g_strdup(atkName); - objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get()); - objAttributeSet = g_slist_prepend(objAttributeSet, objAttr); - } + ConvertTextAttributeToAtkAttribute(name, value, &objAttributeSet); } // libatk-adaptor will free it @@ -252,38 +278,58 @@ getRunAttributesCB(AtkText *aText, gint aOffset, { *aStartOffset = -1; *aEndOffset = -1; + int32_t startOffset = 0, endOffset = 0; AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return nullptr; + } + + nsCOMPtr attributes = + text->TextAttributes(false, aOffset, &startOffset, &endOffset); + + *aStartOffset = startOffset; + *aEndOffset = endOffset; + + return ConvertToAtkTextAttributeSet(attributes); + } + + ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText)); + if (!proxy) { return nullptr; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return nullptr; - - int32_t startOffset = 0, endOffset = 0; - nsCOMPtr attributes = - text->TextAttributes(false, aOffset, &startOffset, &endOffset); - + nsAutoTArray attrs; + proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset); *aStartOffset = startOffset; *aEndOffset = endOffset; - - return ConvertToAtkTextAttributeSet(attributes); + return ConvertToAtkTextAttributeSet(attrs); } static AtkAttributeSet* getDefaultAttributesCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return nullptr; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return nullptr; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return nullptr; + nsCOMPtr attributes = text->DefaultTextAttributes(); + return ConvertToAtkTextAttributeSet(attributes); + } - nsCOMPtr attributes = text->DefaultTextAttributes(); - return ConvertToAtkTextAttributeSet(attributes); + ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText)); + if (!proxy) { + return nullptr; + } + + nsAutoTArray attrs; + proxy->DefaultTextAttributes(&attrs); + return ConvertToAtkTextAttributeSet(attrs); } static void diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index 07b435801a38..f1b2772a9b8d 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -127,11 +127,18 @@ DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray* aAt return true; nsCOMPtr props = acc->Attributes(); - if (!props) - return true; + return PersistentPropertiesToArray(props, aAttributes); +} +bool +DocAccessibleChild::PersistentPropertiesToArray(nsIPersistentProperties* aProps, + nsTArray* aAttributes) +{ + if (!aProps) { + return true; + } nsCOMPtr propEnum; - nsresult rv = props->Enumerate(getter_AddRefs(propEnum)); + nsresult rv = aProps->Enumerate(getter_AddRefs(propEnum)); NS_ENSURE_SUCCESS(rv, false); bool hasMore; @@ -325,5 +332,36 @@ DocAccessibleChild::RecvCharAt(const uint64_t& aID, return true; } +bool +DocAccessibleChild::RecvTextAttributes(const uint64_t& aID, + const bool& aIncludeDefAttrs, + const int32_t& aOffset, + nsTArray* aAttributes, + int32_t* aStartOffset, + int32_t* aEndOffset) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + if (!acc || !acc->IsTextRole()) { + return true; + } + + nsCOMPtr props = + acc->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset); + return PersistentPropertiesToArray(props, aAttributes); +} + +bool +DocAccessibleChild::RecvDefaultTextAttributes(const uint64_t& aID, + nsTArray *aAttributes) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + if (!acc || !acc->IsTextRole()) { + return true; + } + + nsCOMPtr props = acc->DefaultTextAttributes(); + return PersistentPropertiesToArray(props, aAttributes); +} + } } diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 6e615fa64503..3b14e098259f 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -99,7 +99,22 @@ public: const int32_t& aOffset, uint16_t* aChar) MOZ_OVERRIDE; + virtual bool RecvTextAttributes(const uint64_t& aID, + const bool& aIncludeDefAttrs, + const int32_t& aOffset, + nsTArray* aAttributes, + int32_t* aStartOffset, + int32_t* aEndOffset) + MOZ_OVERRIDE; + + virtual bool RecvDefaultTextAttributes(const uint64_t& aID, + nsTArray* aAttributes) + MOZ_OVERRIDE; + private: + bool PersistentPropertiesToArray(nsIPersistentProperties* aProps, + nsTArray* aAttributes); + DocAccessible* mDoc; }; diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index f418dafb2ff2..0ca22193a6b4 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -75,9 +75,14 @@ child: returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset); prio(high) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType) returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset); + prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType) returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset); prio(high) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar); + + prio(high) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset) + returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset); + prio(high) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes); }; } diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index fbcc2f71f7f5..e3d20e2732b3 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -226,5 +226,22 @@ ProxyAccessible::CharAt(int32_t aOffset) return static_cast(retval); } +void +ProxyAccessible::TextAttributes(bool aIncludeDefAttrs, + int32_t aOffset, + nsTArray* aAttributes, + int32_t* aStartOffset, + int32_t* aEndOffset) +{ + unused << mDoc->SendTextAttributes(mID, aIncludeDefAttrs, aOffset, + aAttributes, aStartOffset, aEndOffset); +} + +void +ProxyAccessible::DefaultTextAttributes(nsTArray* aAttrs) +{ + unused << mDoc->SendDefaultTextAttributes(mID, aAttrs); +} + } } diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index 3a1c97a2f316..771105620f18 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -125,6 +125,13 @@ public: char16_t CharAt(int32_t aOffset); + void TextAttributes(bool aIncludeDefAttrs, + const int32_t aOffset, + nsTArray* aAttributes, + int32_t* aStartOffset, + int32_t* aEndOffset); + void DefaultTextAttributes(nsTArray* aAttrs); + /** * Allow the platform to store a pointers worth of data on us. */ From b8599a6f9636dcf27de484be1ff6b3d635206a38 Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Sat, 7 Mar 2015 19:37:21 -0500 Subject: [PATCH 36/42] Bug 1140404 - The interval's start/end time was properly set fails for browser_perf-overview-time-interval.js, r=orange --- .../performance/test/browser_perf-overview-time-interval.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/devtools/performance/test/browser_perf-overview-time-interval.js b/browser/devtools/performance/test/browser_perf-overview-time-interval.js index c6c23967af01..f2e53a479cc2 100644 --- a/browser/devtools/performance/test/browser_perf-overview-time-interval.js +++ b/browser/devtools/performance/test/browser_perf-overview-time-interval.js @@ -42,9 +42,9 @@ function spawnTest () { let firstInterval = OverviewView.getTimeInterval(); info("First interval start time: " + firstInterval.startTime); info("First interval end time: " + firstInterval.endTime); - ok(firstInterval.startTime - 10 < Number.EPSILON, + is(Math.round(firstInterval.startTime), 10, "The interval's start time was properly set."); - ok(firstInterval.endTime - 20 < Number.EPSILON, + is(Math.round(firstInterval.endTime), 20, "The interval's end time was properly set."); // Get/set another time interval and make sure there's no event propagation. From df31a989def69b98160e18fe4cab393ea447a578 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sat, 7 Mar 2015 18:14:05 -0800 Subject: [PATCH 37/42] Backed out 3 changesets (bug 1081819) for frequent mochitest-e10s failures Backed out changeset b78fd38002f5 (bug 1081819) Backed out changeset ff063b9a1ea2 (bug 1081819) Backed out changeset 322d60fc413e (bug 1081819) --- dom/media/TrackUnionStream.cpp | 15 ++- dom/media/TrackUnionStream.h | 8 ++ dom/media/tests/mochitest/mochitest.ini | 2 - .../test_peerConnection_webAudio.html | 97 ------------------- .../MediaStreamAudioDestinationNode.cpp | 55 +++++++++-- 5 files changed, 66 insertions(+), 111 deletions(-) delete mode 100644 dom/media/tests/mochitest/test_peerConnection_webAudio.html diff --git a/dom/media/TrackUnionStream.cpp b/dom/media/TrackUnionStream.cpp index bb59bf9867b8..c7d545ec539b 100644 --- a/dom/media/TrackUnionStream.cpp +++ b/dom/media/TrackUnionStream.cpp @@ -50,7 +50,8 @@ PRLogModuleInfo* gTrackUnionStreamLog; #endif TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) : - ProcessedMediaStream(aWrapper) + ProcessedMediaStream(aWrapper), + mFilterCallback(nullptr) { #ifdef PR_LOGGING if (!gTrackUnionStreamLog) { @@ -113,7 +114,7 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) : break; } } - if (!found) { + if (!found && (!mFilterCallback || mFilterCallback(tracks.get()))) { bool trackFinished = false; trackAdded = true; uint32_t mapIndex = AddTrack(mInputs[i], tracks.get(), aFrom); @@ -152,6 +153,14 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) : } } + // Consumers may specify a filtering callback to apply to every input track. + // Returns true to allow the track to act as an input; false to reject it entirely. + + void TrackUnionStream::SetTrackIDFilter(TrackIDFilterCallback aCallback) + { + mFilterCallback = aCallback; + } + // Forward SetTrackEnabled(output_track_id, enabled) to the Source MediaStream, // translating the output track ID into the correct ID in the source. void TrackUnionStream::ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) @@ -272,8 +281,6 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) : segment->AppendNullData(ticks); STREAM_LOG(PR_LOG_DEBUG+1, ("TrackUnionStream %p appending %lld ticks of null data to track %d", this, (long long)ticks, outputTrack->GetID())); - } else if (InMutedCycle()) { - segment->AppendNullData(ticks); } else { MOZ_ASSERT(outputTrack->GetEnd() == GraphTimeToStreamTime(interval.mStart), "Samples missing"); diff --git a/dom/media/TrackUnionStream.h b/dom/media/TrackUnionStream.h index fa2a3fcaee39..a9216741eae2 100644 --- a/dom/media/TrackUnionStream.h +++ b/dom/media/TrackUnionStream.h @@ -21,11 +21,19 @@ public: virtual void RemoveInput(MediaInputPort* aPort) MOZ_OVERRIDE; virtual void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE; + // Consumers may specify a filtering callback to apply to every input track. + // Returns true to allow the track to act as an input; false to reject it entirely. + typedef bool (*TrackIDFilterCallback)(StreamBuffer::Track*); + + void SetTrackIDFilter(TrackIDFilterCallback aCallback); + // Forward SetTrackEnabled(output_track_id, enabled) to the Source MediaStream, // translating the output track ID into the correct ID in the source. virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) MOZ_OVERRIDE; protected: + TrackIDFilterCallback mFilterCallback; + // Only non-ended tracks are allowed to persist in this map. struct TrackMapEntry { // mEndOfConsumedInputTicks is the end of the input ticks that we've consumed. diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index 8e235ffc877a..0cdee3c9cf25 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -178,8 +178,6 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1059867) skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_addDataChannelNoBundle.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) -[test_peerConnection_webAudio.html] -skip-if = toolkit == 'gonk' # b2g (Bug 1059867) # Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases [test_zmedia_cleanup.html] diff --git a/dom/media/tests/mochitest/test_peerConnection_webAudio.html b/dom/media/tests/mochitest/test_peerConnection_webAudio.html deleted file mode 100644 index 2ca148827415..000000000000 --- a/dom/media/tests/mochitest/test_peerConnection_webAudio.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - -
-
-
- - diff --git a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp index 1057b8af68c5..741fc046a203 100644 --- a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp +++ b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp @@ -23,21 +23,60 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode) NS_IMPL_ADDREF_INHERITED(MediaStreamAudioDestinationNode, AudioNode) NS_IMPL_RELEASE_INHERITED(MediaStreamAudioDestinationNode, AudioNode) +static const int MEDIA_STREAM_DEST_TRACK_ID = 2; +static_assert(MEDIA_STREAM_DEST_TRACK_ID != AudioNodeStream::AUDIO_TRACK, + "MediaStreamAudioDestinationNode::MEDIA_STREAM_DEST_TRACK_ID must be a different value than AudioNodeStream::AUDIO_TRACK"); + +class MediaStreamDestinationEngine : public AudioNodeEngine { +public: + MediaStreamDestinationEngine(AudioNode* aNode, ProcessedMediaStream* aOutputStream) + : AudioNodeEngine(aNode) + , mOutputStream(aOutputStream) + { + MOZ_ASSERT(mOutputStream); + } + + virtual void ProcessBlock(AudioNodeStream* aStream, + const AudioChunk& aInput, + AudioChunk* aOutput, + bool* aFinished) MOZ_OVERRIDE + { + *aOutput = aInput; + StreamBuffer::Track* track = mOutputStream->EnsureTrack(MEDIA_STREAM_DEST_TRACK_ID); + AudioSegment* segment = track->Get(); + segment->AppendAndConsumeChunk(aOutput); + } + + virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE + { + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); + } + +private: + ProcessedMediaStream* mOutputStream; +}; + +// This callback is used to ensure that only the audio data for this track is audible +static bool FilterAudioNodeStreamTrack(StreamBuffer::Track* aTrack) +{ + return aTrack->GetID() == MEDIA_STREAM_DEST_TRACK_ID; +} + MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* aContext) : AudioNode(aContext, 2, ChannelCountMode::Explicit, ChannelInterpretation::Speakers) - , mDOMStream(DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(), this)) + , mDOMStream(DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(), + this)) { - // Ensure an audio track with the correct ID is exposed to JS - mDOMStream->CreateDOMTrack(AudioNodeStream::AUDIO_TRACK, MediaSegment::AUDIO); + TrackUnionStream* tus = static_cast(mDOMStream->GetStream()); + MOZ_ASSERT(tus == mDOMStream->GetStream()->AsProcessedStream()); + tus->SetTrackIDFilter(FilterAudioNodeStreamTrack); - ProcessedMediaStream* outputStream = mDOMStream->GetStream()->AsProcessedStream(); - MOZ_ASSERT(!!outputStream); - AudioNodeEngine* engine = new AudioNodeEngine(this); - mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM); - mPort = outputStream->AllocateInputPort(mStream); + MediaStreamDestinationEngine* engine = new MediaStreamDestinationEngine(this, tus); + mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM); + mPort = tus->AllocateInputPort(mStream, 0); nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc(); if (doc) { From 751b0c932bfd98aade376be9202a8b760639fe5a Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Sun, 8 Mar 2015 06:49:33 +0000 Subject: [PATCH 38/42] Bug 1140080 - ensure we only create stop frames for gradients. r=dholbert --- layout/base/nsCSSFrameConstructor.cpp | 11 +++++++++++ layout/svg/crashtests/1140080-1.svg | 11 +++++++++++ layout/svg/crashtests/crashtests.list | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 layout/svg/crashtests/1140080-1.svg diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 254312b1813b..4e3f75af3b99 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -5179,6 +5179,17 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement, return &sContainerData; } + // Ensure that a stop frame is a child of a gradient and that gradients + // can only have stop children. + bool parentIsGradient = aParentFrame && + (aParentFrame->GetType() == nsGkAtoms::svgLinearGradientFrame || + aParentFrame->GetType() == nsGkAtoms::svgRadialGradientFrame); + bool stop = (aTag == nsGkAtoms::stop); + if ((parentIsGradient && !stop) || + (!parentIsGradient && stop)) { + return &sSuppressData; + } + // Prevent bad frame types being children of filters or parents of filter // primitives. If aParentFrame is null, we know that the frame that will // be created will be an nsInlineFrame, so it can never be a filter. diff --git a/layout/svg/crashtests/1140080-1.svg b/layout/svg/crashtests/1140080-1.svg new file mode 100644 index 000000000000..d42456246807 --- /dev/null +++ b/layout/svg/crashtests/1140080-1.svg @@ -0,0 +1,11 @@ + + + + diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list index 48bfa27ad8f6..a9453667cbe1 100644 --- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -188,4 +188,4 @@ load 979407-2.svg load 993443.svg load 1016145.svg load 1028512.svg - +load 1140080-1.svg From d4289c7714dce87967dbc717104e59ef9ccfb514 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Sun, 8 Mar 2015 18:43:22 +1100 Subject: [PATCH 39/42] Bug 1139283 - Move some properties from nsStyleDisplay to nsStylePosition. r=dbaron The moved properties are: * clip * transform-style * transform-origin * backface-visibility * perspective * perspective-origin * will-change --HG-- extra : source : 42bbf0328b450d1094250159fe9f7f0d07622290 --- layout/base/ActiveLayerTracker.cpp | 5 +- layout/base/RestyleManager.cpp | 6 +- layout/base/nsCSSFrameConstructor.cpp | 15 +- layout/base/nsDisplayList.cpp | 50 +-- layout/base/nsLayoutDebugger.cpp | 7 +- layout/generic/nsFrame.cpp | 72 ++-- layout/generic/nsGfxScrollFrame.cpp | 14 +- layout/generic/nsIFrame.h | 3 +- layout/style/StyleAnimationValue.cpp | 42 +- layout/style/generate-stylestructlist.py | 2 +- layout/style/nsCSSPropList.h | 24 +- layout/style/nsComputedDOMStyle.cpp | 55 ++- layout/style/nsRuleNode.cpp | 502 +++++++++++------------ layout/style/nsStyleConsts.h | 2 + layout/style/nsStyleStruct.cpp | 240 +++++------ layout/style/nsStyleStruct.h | 97 ++--- layout/style/nsStyleStructInlines.h | 32 +- layout/svg/nsSVGUtils.cpp | 11 +- 18 files changed, 606 insertions(+), 573 deletions(-) diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index 00fce77fc46b..c797c5ab8ee4 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -265,12 +265,13 @@ ActiveLayerTracker::IsStyleAnimated(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsCSSProperty aProperty) { // TODO: Add some abuse restrictions - if ((aFrame->StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && + auto willChangeBitField = aFrame->StylePosition()->mWillChangeBitField; + if ((willChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && aProperty == eCSSProperty_transform && (!aBuilder || aBuilder->IsInWillChangeBudget(aFrame))) { return true; } - if ((aFrame->StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && + if ((willChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && aProperty == eCSSProperty_opacity && (!aBuilder || aBuilder->IsInWillChangeBudget(aFrame))) { return true; diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 7f1e1a515b80..77ce3e3c6aaa 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -332,12 +332,12 @@ ApplyRenderingChangeToTree(nsPresContext* aPresContext, nsIFrame* aFrame, nsChangeHint aChange) { - // We check StyleDisplay()->HasTransformStyle() in addition to checking + // We check StylePosition()->HasTransformStyle() in addition to checking // IsTransformed() since we can get here for some frames that don't support // CSS transforms. NS_ASSERTION(!(aChange & nsChangeHint_UpdateTransformLayer) || aFrame->IsTransformed() || - aFrame->StyleDisplay()->HasTransformStyle(), + aFrame->StylePosition()->HasTransformStyle(), "Unexpected UpdateTransformLayer hint"); nsIPresShell *shell = aPresContext->PresShell(); @@ -2605,7 +2605,7 @@ ElementRestyler::AddLayerChangesForAnimation() // nsChangeHint_UpdateTransformLayer, ApplyRenderingChangeToTree would // complain that we're updating a transform layer without a transform). if (layerInfo[i].mLayerType == nsDisplayItem::TYPE_TRANSFORM && - !mFrame->StyleDisplay()->HasTransformStyle()) { + !mFrame->StylePosition()->HasTransformStyle()) { continue; } NS_UpdateHint(hint, layerInfo[i].mChangeHint); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 4e3f75af3b99..059a793fa55f 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1059,8 +1059,8 @@ nsFrameConstructorState::PushAbsoluteContainingBlock(nsContainerFrame* aNewAbsol * we're a transformed element. */ mFixedPosIsAbsPos = aPositionedFrame && - (aPositionedFrame->StyleDisplay()->HasTransform(aPositionedFrame) || - aPositionedFrame->StyleDisplay()->HasPerspectiveStyle()); + (aPositionedFrame->StylePosition()->HasTransform(aPositionedFrame) || + aPositionedFrame->StylePosition()->HasPerspectiveStyle()); if (aNewAbsoluteContainingBlock) { aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock(); @@ -3788,7 +3788,9 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt // If we need to create a block formatting context to wrap our // kids, do it now. + const nsStylePosition* position = styleContext->StylePosition(); const nsStyleDisplay* maybeAbsoluteContainingBlockDisplay = display; + const nsStylePosition* maybeAbsoluteContainingBlockPosition = position; nsIFrame* maybeAbsoluteContainingBlock = newFrame; nsIFrame* possiblyLeafFrame = newFrame; if (bits & FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS) { @@ -3814,6 +3816,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt const nsStyleDisplay* blockDisplay = blockContext->StyleDisplay(); if (blockDisplay->IsPositioned(blockFrame)) { maybeAbsoluteContainingBlockDisplay = blockDisplay; + maybeAbsoluteContainingBlockPosition = blockContext->StylePosition(); maybeAbsoluteContainingBlock = blockFrame; } @@ -3854,9 +3857,9 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt // make the inner the containing block. if ((maybeAbsoluteContainingBlockDisplay->IsAbsolutelyPositionedStyle() || maybeAbsoluteContainingBlockDisplay->IsRelativelyPositionedStyle() || - (maybeAbsoluteContainingBlockDisplay->HasTransformStyle() && + (maybeAbsoluteContainingBlockPosition->HasTransformStyle() && cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) || - maybeAbsoluteContainingBlockDisplay->HasPerspectiveStyle()) && + maybeAbsoluteContainingBlockPosition->HasPerspectiveStyle()) && !cb->IsSVGText()) { nsContainerFrame* cf = static_cast(cb); aState.PushAbsoluteContainingBlock(cf, cf, absoluteSaveState); @@ -5983,8 +5986,8 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame, // not transformed, skip it. if (!frame->IsPositioned() || (aType == FIXED_POS && - !frame->StyleDisplay()->HasTransform(frame) && - !frame->StyleDisplay()->HasPerspectiveStyle())) { + !frame->StylePosition()->HasTransform(frame) && + !frame->StylePosition()->HasPerspectiveStyle())) { continue; } nsIFrame* absPosCBCandidate = frame; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 48338a68c70f..a452cdd55c38 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -522,9 +522,9 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer, nscoord perspective = 0.0; nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent(); if (parentStyleContext) { - const nsStyleDisplay* disp = parentStyleContext->StyleDisplay(); - if (disp && disp->mChildPerspective.GetUnit() == eStyleUnit_Coord) { - perspective = disp->mChildPerspective.GetCoordValue(); + const nsStylePosition* pos = parentStyleContext->StylePosition(); + if (pos && pos->mChildPerspective.GetUnit() == eStyleUnit_Coord) { + perspective = pos->mChildPerspective.GetCoordValue(); } } nsPoint origin; @@ -5027,8 +5027,8 @@ nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder) mStoredList.SetVisibleRect(mChildrenVisibleRect); mMaybePrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame); - const nsStyleDisplay* disp = mFrame->StyleDisplay(); - if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { + const nsStylePosition* pos = mFrame->StylePosition(); + if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { // We will only pre-render if this will-change is on budget. mMaybePrerender = true; } @@ -5082,7 +5082,8 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, const nsRect* aBoundsOverride) { NS_PRECONDITION(aFrame, "Can't get delta for a null frame!"); - NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(), + NS_PRECONDITION(aFrame->IsTransformed() || + aFrame->StylePosition()->BackfaceIsHidden(), "Shouldn't get a delta for an untransformed frame!"); if (!aFrame->IsTransformed()) { @@ -5093,7 +5094,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, * percentage, it's relative to the size of the frame. Otherwise, if it's * a distance, it's already computed for us! */ - const nsStyleDisplay* display = aFrame->StyleDisplay(); + const nsStylePosition* pos = aFrame->StylePosition(); nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride : nsDisplayTransform::GetFrameBoundsForTransform(aFrame)); @@ -5106,7 +5107,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, /* If the -moz-transform-origin specifies a percentage, take the percentage * of the size of the box. */ - const nsStyleCoord &coord = display->mTransformOrigin[index]; + const nsStyleCoord &coord = pos->mTransformOrigin[index]; if (coord.GetUnit() == eStyleUnit_Calc) { const nsStyleCoord::Calc *calc = coord.GetCalcValue(); coords[index] = @@ -5132,7 +5133,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, } } - coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(), + coords[2] = NSAppUnitsToFloatPixels(pos->mTransformOrigin[2].GetCoordValue(), aAppUnitsPerPixel); /* Adjust based on the origin of the rectangle. */ coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel); @@ -5151,7 +5152,8 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, float aAppUnitsPerPixel) { NS_PRECONDITION(aFrame, "Can't get delta for a null frame!"); - NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(), + NS_PRECONDITION(aFrame->IsTransformed() || + aFrame->StylePosition()->BackfaceIsHidden(), "Shouldn't get a delta for an untransformed frame!"); if (!aFrame->IsTransformed()) { @@ -5176,7 +5178,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, return Point3D(); } } - const nsStyleDisplay* display = psc->StyleDisplay(); + const nsStylePosition* pos = psc->StylePosition(); nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent); /* Allows us to access named variables by index. */ @@ -5190,7 +5192,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, /* If the -moz-transform-origin specifies a percentage, take the percentage * of the size of the box. */ - const nsStyleCoord &coord = display->mPerspectiveOrigin[index]; + const nsStyleCoord &coord = pos->mPerspectiveOrigin[index]; if (coord.GetUnit() == eStyleUnit_Calc) { const nsStyleCoord::Calc *calc = coord.GetCalcValue(); *coords[index] = @@ -5221,18 +5223,18 @@ nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsI float aAppUnitsPerPixel, const nsRect* aBoundsOverride) : mFrame(aFrame) - , mTransformList(aFrame->StyleDisplay()->mSpecifiedTransform) + , mTransformList(aFrame->StylePosition()->mSpecifiedTransform) , mToTransformOrigin(GetDeltaToTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride)) , mToPerspectiveOrigin(GetDeltaToPerspectiveOrigin(aFrame, aAppUnitsPerPixel)) , mChildPerspective(0) { - const nsStyleDisplay* parentDisp = nullptr; + const nsStylePosition* parentPos = nullptr; nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent(); if (parentStyleContext) { - parentDisp = parentStyleContext->StyleDisplay(); + parentPos = parentStyleContext->StylePosition(); } - if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) { - mChildPerspective = parentDisp->mChildPerspective.GetCoordValue(); + if (parentPos && parentPos->mChildPerspective.GetUnit() == eStyleUnit_Coord) { + mChildPerspective = parentPos->mChildPerspective.GetCoordValue(); } } @@ -5412,8 +5414,8 @@ nsDisplayTransform::ShouldPrerender(nsDisplayListBuilder* aBuilder) { return true; } - const nsStyleDisplay* disp = mFrame->StyleDisplay(); - if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && + const nsStylePosition* pos = mFrame->StylePosition(); + if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && aBuilder->IsInWillChangeBudget(mFrame)) { return true; } @@ -5502,7 +5504,8 @@ static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix) if (aMatrix.IsSingular()) { return false; } - if (aFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && + const nsStylePosition* pos = aFrame->StylePosition(); + if (pos->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && aMatrix.IsBackfaceVisible()) { return false; } @@ -5550,7 +5553,8 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu { const Matrix4x4& newTransformMatrix = GetTransform(); - if (mFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && + const nsStylePosition* pos = mFrame->StylePosition(); + if (pos->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && newTransformMatrix.IsBackfaceVisible()) { return nullptr; } @@ -5609,8 +5613,8 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder, } } - const nsStyleDisplay* disp = mFrame->StyleDisplay(); - if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { + const nsStylePosition* pos = mFrame->StylePosition(); + if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { return LAYER_ACTIVE; } diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index ced64b1df90c..c85ca8704f99 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -184,13 +184,14 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, aStream << " fixed"; } - if (aItem->Frame()->StyleDisplay()->mWillChange.Length() > 0) { + const nsStylePosition* pos = aItem->Frame()->StylePosition(); + if (pos->mWillChange.Length() > 0) { aStream << " (will-change="; - for (size_t i = 0; i < aItem->Frame()->StyleDisplay()->mWillChange.Length(); i++) { + for (size_t i = 0; i < pos->mWillChange.Length(); i++) { if (i > 0) { aStream << ","; } - aStream << NS_LossyConvertUTF16toASCII(aItem->Frame()->StyleDisplay()->mWillChange[i]).get(); + aStream << NS_LossyConvertUTF16toASCII(pos->mWillChange[i]).get(); } aStream << ")"; } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index ab8fb3ed4cbe..f96ef2fe8e4d 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -546,12 +546,13 @@ nsFrame::Init(nsIContent* aContent, NS_FRAME_IN_POPUP | NS_FRAME_IS_NONDISPLAY); } - const nsStyleDisplay *disp = StyleDisplay(); - if (disp->HasTransform(this)) { + const nsStylePosition* pos = StylePosition(); + if (pos->HasTransform(this)) { // The frame gets reconstructed if we toggle the -moz-transform // property, so we can set this bit here and then ignore it. mState |= NS_FRAME_MAY_BE_TRANSFORMED; } + const nsStyleDisplay *disp = StyleDisplay(); if (disp->mPosition == NS_STYLE_POSITION_STICKY && !aPrevInFlow && !(mState & NS_FRAME_IS_NONDISPLAY) && @@ -1075,7 +1076,7 @@ bool nsIFrame::IsTransformed() const { return ((mState & NS_FRAME_MAY_BE_TRANSFORMED) && - (StyleDisplay()->HasTransform(this) || + (StylePosition()->HasTransform(this) || IsSVGTransformed() || (mContent && nsLayoutUtils::HasAnimationsForCompositor(mContent, @@ -1088,9 +1089,9 @@ bool nsIFrame::HasOpacityInternal(float aThreshold) const { MOZ_ASSERT(0.0 <= aThreshold && aThreshold <= 1.0, "Invalid argument"); - const nsStyleDisplay* displayStyle = StyleDisplay(); + const nsStylePosition* pos = StylePosition(); return StyleDisplay()->mOpacity < aThreshold || - (displayStyle->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) || + (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) || (mContent && nsLayoutUtils::HasAnimationsForCompositor(mContent, eCSSProperty_opacity) && @@ -1107,8 +1108,8 @@ nsIFrame::IsSVGTransformed(gfx::Matrix *aOwnTransforms, bool nsIFrame::Preserves3DChildren() const { - const nsStyleDisplay* disp = StyleDisplay(); - if (disp->mTransformStyle != NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || + const nsStylePosition* pos = StylePosition(); + if (pos->mTransformStyle != NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || !IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) { return false; } @@ -1119,8 +1120,8 @@ nsIFrame::Preserves3DChildren() const } nsRect temp; - return !nsFrame::ShouldApplyOverflowClipping(this, disp) && - !GetClipPropClipRect(disp, &temp, GetSize()) && + return !nsFrame::ShouldApplyOverflowClipping(this, StyleDisplay()) && + !GetClipPropClipRect(&temp, GetSize()) && !nsSVGIntegrationUtils::UsingEffectsForFrame(this); } @@ -1130,7 +1131,8 @@ nsIFrame::Preserves3D() const if (!GetParent() || !GetParent()->Preserves3DChildren()) { return false; } - return StyleDisplay()->HasTransform(this) || StyleDisplay()->BackfaceIsHidden(); + const nsStylePosition* pos = StylePosition(); + return pos->HasTransform(this) || pos->BackfaceIsHidden(); } bool @@ -1143,14 +1145,14 @@ nsIFrame::HasPerspective() const if (!parentStyleContext) { return false; } - const nsStyleDisplay* parentDisp = parentStyleContext->StyleDisplay(); - return parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord; + const nsStylePosition* parentPos = parentStyleContext->StylePosition(); + return parentPos->mChildPerspective.GetUnit() == eStyleUnit_Coord; } bool nsIFrame::ChildrenHavePerspective() const { - return StyleDisplay()->HasPerspectiveStyle(); + return StylePosition()->HasPerspectiveStyle(); } nsRect @@ -1643,17 +1645,18 @@ inline static bool IsSVGContentWithCSSClip(const nsIFrame *aFrame) } bool -nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect, - const nsSize& aSize) const +nsIFrame::GetClipPropClipRect(nsRect* aRect, const nsSize& aSize) const { NS_PRECONDITION(aRect, "Must have aRect out parameter"); - if (!(aDisp->mClipFlags & NS_STYLE_CLIP_RECT) || - !(aDisp->IsAbsolutelyPositioned(this) || IsSVGContentWithCSSClip(this))) { + const nsStylePosition* pos = StylePosition(); + if (!(pos->mClipFlags & NS_STYLE_CLIP_RECT) || + !(StyleDisplay()->IsAbsolutelyPositioned(this) || + IsSVGContentWithCSSClip(this))) { return false; } - *aRect = aDisp->mClip; + *aRect = pos->mClip; if (MOZ_LIKELY(StyleBorder()->mBoxDecorationBreak == NS_STYLE_BOX_DECORATION_BREAK_SLICE)) { // The clip applies to the joined boxes so it's relative the first @@ -1665,10 +1668,10 @@ nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect, aRect->MoveBy(nsPoint(0, -y)); } - if (NS_STYLE_CLIP_RIGHT_AUTO & aDisp->mClipFlags) { + if (NS_STYLE_CLIP_RIGHT_AUTO & pos->mClipFlags) { aRect->width = aSize.width - aRect->x; } - if (NS_STYLE_CLIP_BOTTOM_AUTO & aDisp->mClipFlags) { + if (NS_STYLE_CLIP_BOTTOM_AUTO & pos->mClipFlags) { aRect->height = aSize.height - aRect->y; } return true; @@ -1683,11 +1686,10 @@ nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect, static bool ApplyClipPropClipping(nsDisplayListBuilder* aBuilder, const nsIFrame* aFrame, - const nsStyleDisplay* aDisp, nsRect* aRect, DisplayListClipState::AutoSaveRestore& aClipState) { - if (!aFrame->GetClipPropClipRect(aDisp, aRect, aFrame->GetSize())) + if (!aFrame->GetClipPropClipRect(aRect, aFrame->GetSize())) return false; nsRect clipRect = *aRect + aBuilder->ToReferenceFrame(aFrame); @@ -1842,7 +1844,7 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, break; } default: { - if (childFrame->StyleDisplay()->BackfaceIsHidden()) { + if (childFrame->StylePosition()->BackfaceIsHidden()) { if (!aTemp->IsEmpty()) { aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++)); @@ -1933,6 +1935,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, return; const nsStyleDisplay* disp = StyleDisplay(); + const nsStylePosition* pos = StylePosition(); // We can stop right away if this is a zero-opacity stacking context and // we're painting, and we're not animating opacity. Don't do this // if we're going to compute plugin geometry, since opacity-0 plugins @@ -1941,13 +1944,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, StyleVisibility()->GetEffectivePointerEvents(this) != NS_STYLE_POINTER_EVENTS_NONE; if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() && !aBuilder->WillComputePluginGeometry() && - !(disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && + !(pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && !nsLayoutUtils::HasAnimations(mContent, eCSSProperty_opacity) && !needEventRegions) { return; } - if (disp->mWillChangeBitField != 0) { + if (pos->mWillChangeBitField != 0) { aBuilder->AddToWillChangeBudget(this, GetSize()); } @@ -2027,7 +2030,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, CheckForApzAwareEventHandlers(aBuilder, this); nsRect clipPropClip; - if (ApplyClipPropClipping(aBuilder, this, disp, &clipPropClip, + if (ApplyClipPropClipping(aBuilder, this, &clipPropClip, nestedClipState)) { dirtyRect.IntersectRect(dirtyRect, clipPropClip); } @@ -2349,7 +2352,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, || child->IsTransformed() // strictly speaking, 'perspective' doesn't require visual atomicity, // but the spec says it acts like the rest of these - || disp->mChildPerspective.GetUnit() == eStyleUnit_Coord + || pos->mChildPerspective.GetUnit() == eStyleUnit_Coord || disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL || nsSVGIntegrationUtils::UsingEffectsForFrame(child) || (child->GetStateBits() & NS_FRAME_HAS_VR_CONTENT); @@ -2358,15 +2361,15 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, bool isStackingContext = (isPositioned && (disp->mPosition == NS_STYLE_POSITION_STICKY || pos->mZIndex.GetUnit() == eStyleUnit_Integer)) || - (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) || + (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) || disp->mIsolation != NS_STYLE_ISOLATION_AUTO || isVisuallyAtomic || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT); if (isVisuallyAtomic || isPositioned || (!isSVG && disp->IsFloating(child)) || - ((disp->mClipFlags & NS_STYLE_CLIP_RECT) && + ((pos->mClipFlags & NS_STYLE_CLIP_RECT) && IsSVGContentWithCSSClip(child)) || disp->mIsolation != NS_STYLE_ISOLATION_AUTO || - (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) || + (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) { // If you change this, also change IsPseudoStackingContextFromStyle() pseudoStackingContext = true; @@ -2410,7 +2413,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, aBuilder->DisplayCaret(child, dirty, &list); } else { nsRect clipRect; - if (ApplyClipPropClipping(aBuilder, child, disp, &clipRect, clipState)) { + if (ApplyClipPropClipping(aBuilder, child, &clipRect, clipState)) { // clipRect is in builder-reference-frame coordinates, // dirty/clippedDirtyRect are in child coordinates dirty.IntersectRect(dirty, clipRect); @@ -7282,7 +7285,7 @@ UnionBorderBoxes(nsIFrame* aFrame, bool aApplyTransform, nsRect clipPropClipRect; bool hasClipPropClip = - aFrame->GetClipPropClipRect(disp, &clipPropClipRect, bounds.Size()); + aFrame->GetClipPropClipRect(&clipPropClipRect, bounds.Size()); // Iterate over all children except pop-ups. const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList | @@ -7524,7 +7527,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, // Absolute position clipping nsRect clipPropClipRect; - bool hasClipPropClip = GetClipPropClipRect(disp, &clipPropClipRect, aNewSize); + bool hasClipPropClip = GetClipPropClipRect(&clipPropClipRect, aNewSize); if (hasClipPropClip) { NS_FOR_FRAME_OVERFLOW_TYPES(otype) { nsRect& o = aOverflowAreas.Overflow(otype); @@ -8801,7 +8804,8 @@ nsIFrame::IsPseudoStackingContextFromStyle() { return disp->mOpacity != 1.0f || disp->IsPositioned(this) || disp->IsFloating(this) || - (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT); + (StylePosition()->mWillChangeBitField & + NS_STYLE_WILL_CHANGE_STACKING_CONTEXT); } Element* diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 3f2fafc521b7..b2c263cd5488 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3011,8 +3011,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, dirtyRect = ExpandRectToNearlyVisible(dirtyRect); } - const nsStyleDisplay* disp = mOuter->StyleDisplay(); - if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) { + const nsStylePosition* pos = mOuter->StylePosition(); + if (pos && (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) { aBuilder->AddToWillChangeBudget(mOuter, GetScrollPositionClampingScrollPortSize()); } @@ -4360,8 +4360,8 @@ ScrollFrameHelper::IsScrollbarOnRight() const bool ScrollFrameHelper::IsMaybeScrollingActive() const { - const nsStyleDisplay* disp = mOuter->StyleDisplay(); - if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) { + const nsStylePosition* pos = mOuter->StylePosition(); + if (pos && (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) { return true; } @@ -4373,9 +4373,9 @@ ScrollFrameHelper::IsMaybeScrollingActive() const bool ScrollFrameHelper::IsScrollingActive(nsDisplayListBuilder* aBuilder) const { - const nsStyleDisplay* disp = mOuter->StyleDisplay(); - if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL) && - aBuilder->IsInWillChangeBudget(mOuter)) { + const nsStylePosition* pos = mOuter->StylePosition(); + if (pos && (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL) && + aBuilder->IsInWillChangeBudget(mOuter)) { return true; } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 7a94bd49cab3..c6c37aaba948 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2631,8 +2631,7 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty())) * rect, with coordinates relative to this frame's origin. aRect must not be * null! */ - bool GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect, - const nsSize& aSize) const; + bool GetClipPropClipRect(nsRect* aRect, const nsSize& aSize) const; /** * Check if this frame is focusable and in the current tab order. diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index 8736ba47dacb..d57d85c296af 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -3025,14 +3025,14 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_transform_origin: { - const nsStyleDisplay *styleDisplay = - static_cast(styleStruct); + const nsStylePosition *stylePosition = + static_cast(styleStruct); nsAutoPtr triplet(new nsCSSValueTriplet); - if (!StyleCoordToCSSValue(styleDisplay->mTransformOrigin[0], + if (!StyleCoordToCSSValue(stylePosition->mTransformOrigin[0], triplet->mXValue) || - !StyleCoordToCSSValue(styleDisplay->mTransformOrigin[1], + !StyleCoordToCSSValue(stylePosition->mTransformOrigin[1], triplet->mYValue) || - !StyleCoordToCSSValue(styleDisplay->mTransformOrigin[2], + !StyleCoordToCSSValue(stylePosition->mTransformOrigin[2], triplet->mZValue)) { return false; } @@ -3042,12 +3042,12 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_perspective_origin: { - const nsStyleDisplay *styleDisplay = - static_cast(styleStruct); + const nsStylePosition *stylePosition = + static_cast(styleStruct); nsAutoPtr pair(new nsCSSValuePair); - if (!StyleCoordToCSSValue(styleDisplay->mPerspectiveOrigin[0], + if (!StyleCoordToCSSValue(stylePosition->mPerspectiveOrigin[0], pair->mXValue) || - !StyleCoordToCSSValue(styleDisplay->mPerspectiveOrigin[1], + !StyleCoordToCSSValue(stylePosition->mPerspectiveOrigin[1], pair->mYValue)) { return false; } @@ -3147,29 +3147,29 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_clip: { - const nsStyleDisplay *display = - static_cast(styleStruct); - if (!(display->mClipFlags & NS_STYLE_CLIP_RECT)) { + const nsStylePosition* pos = + static_cast(styleStruct); + if (!(pos->mClipFlags & NS_STYLE_CLIP_RECT)) { aComputedValue.SetAutoValue(); } else { nsCSSRect *vrect = new nsCSSRect; - const nsRect &srect = display->mClip; - if (display->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { + const nsRect &srect = pos->mClip; + if (pos->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { vrect->mTop.SetAutoValue(); } else { nscoordToCSSValue(srect.y, vrect->mTop); } - if (display->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { vrect->mRight.SetAutoValue(); } else { nscoordToCSSValue(srect.XMost(), vrect->mRight); } - if (display->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { vrect->mBottom.SetAutoValue(); } else { nscoordToCSSValue(srect.YMost(), vrect->mBottom); } - if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { vrect->mLeft.SetAutoValue(); } else { nscoordToCSSValue(srect.x, vrect->mLeft); @@ -3339,13 +3339,13 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_transform: { - const nsStyleDisplay *display = - static_cast(styleStruct); + const nsStylePosition* pos = + static_cast(styleStruct); nsAutoPtr result; - if (display->mSpecifiedTransform) { + if (pos->mSpecifiedTransform) { // Clone, and convert all lengths (not percents) to pixels. nsCSSValueList **resultTail = getter_Transfers(result); - for (const nsCSSValueList *l = display->mSpecifiedTransform->mHead; + for (const nsCSSValueList *l = pos->mSpecifiedTransform->mHead; l; l = l->mNext) { nsCSSValueList *clone = new nsCSSValueList; *resultTail = clone; diff --git a/layout/style/generate-stylestructlist.py b/layout/style/generate-stylestructlist.py index 33239a3ad05a..3d4d271c081a 100755 --- a/layout/style/generate-stylestructlist.py +++ b/layout/style/generate-stylestructlist.py @@ -64,7 +64,7 @@ STYLE_STRUCTS = [("INHERITED",) + x for x in [ ("Background", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), ("Position", "nullptr", NORMAL_DEP + LENGTH_DEP), ("TextReset", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), - ("Display", "nullptr", NORMAL_DEP + LENGTH_DEP), + ("Display", "nullptr", NORMAL_DEP), ("Content", "nullptr", NORMAL_DEP + LENGTH_DEP), ("UIReset", "nullptr", NORMAL_DEP), ("Table", "nullptr", NORMAL_DEP), diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 8582718740cf..fcfa02a41d75 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1373,7 +1373,7 @@ CSS_PROP_DISPLAY( kClearKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( clip, clip, Clip, @@ -1382,7 +1382,7 @@ CSS_PROP_DISPLAY( "", 0, nullptr, - offsetof(nsStyleDisplay, mClip), + offsetof(nsStylePosition, mClip), eStyleAnimType_Custom) CSS_PROP_COLOR( color, @@ -3305,7 +3305,7 @@ CSS_PROP_TEXT( kTextTransformKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( transform, transform, Transform, @@ -3315,9 +3315,9 @@ CSS_PROP_DISPLAY( "", 0, nullptr, - offsetof(nsStyleDisplay, mSpecifiedTransform), + offsetof(nsStylePosition, mSpecifiedTransform), eStyleAnimType_Custom) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( transform-origin, transform_origin, TransformOrigin, @@ -3329,7 +3329,7 @@ CSS_PROP_DISPLAY( kBackgroundPositionKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( perspective-origin, perspective_origin, PerspectiveOrigin, @@ -3341,7 +3341,7 @@ CSS_PROP_DISPLAY( kBackgroundPositionKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( perspective, perspective, Perspective, @@ -3350,9 +3350,9 @@ CSS_PROP_DISPLAY( "", VARIANT_NONE | VARIANT_INHERIT | VARIANT_LENGTH | VARIANT_POSITIVE_DIMENSION, nullptr, - offsetof(nsStyleDisplay, mChildPerspective), + offsetof(nsStylePosition, mChildPerspective), eStyleAnimType_Coord) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( transform-style, transform_style, TransformStyle, @@ -3363,7 +3363,7 @@ CSS_PROP_DISPLAY( kTransformStyleKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( backface-visibility, backface_visibility, BackfaceVisibility, @@ -3371,7 +3371,7 @@ CSS_PROP_DISPLAY( "", VARIANT_HK, kBackfaceVisibilityKTable, - offsetof(nsStyleDisplay, mBackfaceVisibility), + offsetof(nsStylePosition, mBackfaceVisibility), eStyleAnimType_None) CSS_PROP_POSITION( top, @@ -4122,7 +4122,7 @@ CSS_PROP_SVGRESET( offsetof(nsStyleSVGReset, mVectorEffect), eStyleAnimType_EnumU8) -CSS_PROP_DISPLAY( +CSS_PROP_POSITION( will-change, will_change, WillChange, diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 0a81953e7607..bc7c480baffd 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1148,23 +1148,22 @@ nsComputedDOMStyle::DoGetTransformOrigin() nsDOMCSSValueList* valueList = GetROCSSValueList(false); /* Now, get the values. */ - const nsStyleDisplay* display = StyleDisplay(); + const nsStylePosition* pos = StylePosition(); nsROCSSPrimitiveValue* width = new nsROCSSPrimitiveValue; - SetValueToCoord(width, display->mTransformOrigin[0], false, + SetValueToCoord(width, pos->mTransformOrigin[0], false, &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); valueList->AppendCSSValue(width); nsROCSSPrimitiveValue* height = new nsROCSSPrimitiveValue; - SetValueToCoord(height, display->mTransformOrigin[1], false, + SetValueToCoord(height, pos->mTransformOrigin[1], false, &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); valueList->AppendCSSValue(height); - if (display->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || - display->mTransformOrigin[2].GetCoordValue() != 0) { + if (pos->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || + pos->mTransformOrigin[2].GetCoordValue() != 0) { nsROCSSPrimitiveValue* depth = new nsROCSSPrimitiveValue; - SetValueToCoord(depth, display->mTransformOrigin[2], false, - nullptr); + SetValueToCoord(depth, pos->mTransformOrigin[2], false, nullptr); valueList->AppendCSSValue(depth); } @@ -1185,15 +1184,15 @@ nsComputedDOMStyle::DoGetPerspectiveOrigin() nsDOMCSSValueList* valueList = GetROCSSValueList(false); /* Now, get the values. */ - const nsStyleDisplay* display = StyleDisplay(); + const nsStylePosition* pos = StylePosition(); nsROCSSPrimitiveValue* width = new nsROCSSPrimitiveValue; - SetValueToCoord(width, display->mPerspectiveOrigin[0], false, + SetValueToCoord(width, pos->mPerspectiveOrigin[0], false, &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); valueList->AppendCSSValue(width); nsROCSSPrimitiveValue* height = new nsROCSSPrimitiveValue; - SetValueToCoord(height, display->mPerspectiveOrigin[1], false, + SetValueToCoord(height, pos->mPerspectiveOrigin[1], false, &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); valueList->AppendCSSValue(height); @@ -1204,7 +1203,7 @@ CSSValue* nsComputedDOMStyle::DoGetPerspective() { nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; - SetValueToCoord(val, StyleDisplay()->mChildPerspective, false); + SetValueToCoord(val, StylePosition()->mChildPerspective, false); return val; } @@ -1213,7 +1212,7 @@ nsComputedDOMStyle::DoGetBackfaceVisibility() { nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; val->SetIdent( - nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility, + nsCSSProps::ValueToKeywordEnum(StylePosition()->mBackfaceVisibility, nsCSSProps::kBackfaceVisibilityKTable)); return val; } @@ -1223,7 +1222,7 @@ nsComputedDOMStyle::DoGetTransformStyle() { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; val->SetIdent( - nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle, + nsCSSProps::ValueToKeywordEnum(StylePosition()->mTransformStyle, nsCSSProps::kTransformStyleKTable)); return val; } @@ -1235,13 +1234,13 @@ nsComputedDOMStyle::DoGetTransformStyle() CSSValue* nsComputedDOMStyle::DoGetTransform() { - /* First, get the display data. We'll need it. */ - const nsStyleDisplay* display = StyleDisplay(); + /* First, get the position data. We'll need it. */ + const nsStylePosition* pos = StylePosition(); /* If there are no transforms, then we should construct a single-element * entry and hand it back. */ - if (!display->mSpecifiedTransform) { + if (!pos->mSpecifiedTransform) { nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; /* Set it to "none." */ @@ -1268,7 +1267,7 @@ nsComputedDOMStyle::DoGetTransform() bool dummy; gfx3DMatrix matrix = - nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead, + nsStyleTransformMatrix::ReadTransforms(pos->mSpecifiedTransform->mHead, mStyleContextHolder, mStyleContextHolder->PresContext(), dummy, @@ -4006,9 +4005,9 @@ nsComputedDOMStyle::DoGetClip() { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; - const nsStyleDisplay* display = StyleDisplay(); + const nsStylePosition* pos = StylePosition(); - if (display->mClipFlags == NS_STYLE_CLIP_AUTO) { + if (pos->mClipFlags == NS_STYLE_CLIP_AUTO) { val->SetIdent(eCSSKeyword_auto); } else { // create the cssvalues for the sides, stick them in the rect object @@ -4018,28 +4017,28 @@ nsComputedDOMStyle::DoGetClip() nsROCSSPrimitiveValue *leftVal = new nsROCSSPrimitiveValue; nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal, bottomVal, leftVal); - if (display->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { topVal->SetIdent(eCSSKeyword_auto); } else { - topVal->SetAppUnits(display->mClip.y); + topVal->SetAppUnits(pos->mClip.y); } - if (display->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { rightVal->SetIdent(eCSSKeyword_auto); } else { - rightVal->SetAppUnits(display->mClip.width + display->mClip.x); + rightVal->SetAppUnits(pos->mClip.width + pos->mClip.x); } - if (display->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { bottomVal->SetIdent(eCSSKeyword_auto); } else { - bottomVal->SetAppUnits(display->mClip.height + display->mClip.y); + bottomVal->SetAppUnits(pos->mClip.height + pos->mClip.y); } - if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { + if (pos->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { leftVal->SetIdent(eCSSKeyword_auto); } else { - leftVal->SetAppUnits(display->mClip.x); + leftVal->SetAppUnits(pos->mClip.x); } val->SetRect(domRect); } @@ -4050,7 +4049,7 @@ nsComputedDOMStyle::DoGetClip() CSSValue* nsComputedDOMStyle::DoGetWillChange() { - const nsTArray& willChange = StyleDisplay()->mWillChange; + const nsTArray& willChange = StylePosition()->mWillChange; if (willChange.IsEmpty()) { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index bea1a607b33a..cf17300cf630 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -5564,80 +5564,6 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, parentDisplay->mResize, NS_STYLE_RESIZE_NONE, 0, 0, 0, 0); - // clip property: length, auto, inherit - const nsCSSValue* clipValue = aRuleData->ValueForClip(); - switch (clipValue->GetUnit()) { - case eCSSUnit_Inherit: - canStoreInRuleTree = false; - display->mClipFlags = parentDisplay->mClipFlags; - display->mClip = parentDisplay->mClip; - break; - - case eCSSUnit_Initial: - case eCSSUnit_Unset: - case eCSSUnit_Auto: - display->mClipFlags = NS_STYLE_CLIP_AUTO; - display->mClip.SetRect(0,0,0,0); - break; - - case eCSSUnit_Null: - break; - - case eCSSUnit_Rect: { - const nsCSSRect& clipRect = clipValue->GetRectValue(); - - display->mClipFlags = NS_STYLE_CLIP_RECT; - - if (clipRect.mTop.GetUnit() == eCSSUnit_Auto) { - display->mClip.y = 0; - display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; - } - else if (clipRect.mTop.IsLengthUnit()) { - display->mClip.y = CalcLength(clipRect.mTop, aContext, - mPresContext, canStoreInRuleTree); - } - - if (clipRect.mBottom.GetUnit() == eCSSUnit_Auto) { - // Setting to NS_MAXSIZE for the 'auto' case ensures that - // the clip rect is nonempty. It is important that mClip be - // nonempty if the actual clip rect could be nonempty. - display->mClip.height = NS_MAXSIZE; - display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; - } - else if (clipRect.mBottom.IsLengthUnit()) { - display->mClip.height = CalcLength(clipRect.mBottom, aContext, - mPresContext, canStoreInRuleTree) - - display->mClip.y; - } - - if (clipRect.mLeft.GetUnit() == eCSSUnit_Auto) { - display->mClip.x = 0; - display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; - } - else if (clipRect.mLeft.IsLengthUnit()) { - display->mClip.x = CalcLength(clipRect.mLeft, aContext, - mPresContext, canStoreInRuleTree); - } - - if (clipRect.mRight.GetUnit() == eCSSUnit_Auto) { - // Setting to NS_MAXSIZE for the 'auto' case ensures that - // the clip rect is nonempty. It is important that mClip be - // nonempty if the actual clip rect could be nonempty. - display->mClip.width = NS_MAXSIZE; - display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; - } - else if (clipRect.mRight.IsLengthUnit()) { - display->mClip.width = CalcLength(clipRect.mRight, aContext, - mPresContext, canStoreInRuleTree) - - display->mClip.x; - } - break; - } - - default: - MOZ_ASSERT(false, "unrecognized clip unit"); - } - if (display->mDisplay != NS_STYLE_DISPLAY_NONE) { // CSS2 9.7 specifies display type corrections dealing with 'float' // and 'position'. Since generated content can't be floated or @@ -5696,183 +5622,6 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, } - /* Convert the nsCSSValueList into an nsTArray. */ - const nsCSSValue* transformValue = aRuleData->ValueForTransform(); - switch (transformValue->GetUnit()) { - case eCSSUnit_Null: - break; - - case eCSSUnit_Initial: - case eCSSUnit_Unset: - case eCSSUnit_None: - display->mSpecifiedTransform = nullptr; - break; - - case eCSSUnit_Inherit: - display->mSpecifiedTransform = parentDisplay->mSpecifiedTransform; - canStoreInRuleTree = false; - break; - - case eCSSUnit_SharedList: { - nsCSSValueSharedList* list = transformValue->GetSharedListValue(); - nsCSSValueList* head = list->mHead; - MOZ_ASSERT(head, "transform list must have at least one item"); - // can get a _None in here from transform animation - if (head->mValue.GetUnit() == eCSSUnit_None) { - MOZ_ASSERT(head->mNext == nullptr, "none must be alone"); - display->mSpecifiedTransform = nullptr; - } else { - display->mSpecifiedTransform = list; - } - break; - } - - default: - MOZ_ASSERT(false, "unrecognized transform unit"); - } - - /* Convert the nsCSSValueList into a will-change bitfield for fast lookup */ - const nsCSSValue* willChangeValue = aRuleData->ValueForWillChange(); - switch (willChangeValue->GetUnit()) { - case eCSSUnit_Null: - break; - - case eCSSUnit_List: - case eCSSUnit_ListDep: { - display->mWillChange.Clear(); - display->mWillChangeBitField = 0; - for (const nsCSSValueList* item = willChangeValue->GetListValue(); - item; item = item->mNext) - { - if (item->mValue.UnitHasStringValue()) { - nsAutoString buffer; - item->mValue.GetStringValue(buffer); - display->mWillChange.AppendElement(buffer); - - if (buffer.EqualsLiteral("transform")) { - display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_TRANSFORM; - } - if (buffer.EqualsLiteral("opacity")) { - display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_OPACITY; - } - if (buffer.EqualsLiteral("scroll-position")) { - display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_SCROLL; - } - - nsCSSProperty prop = - nsCSSProps::LookupProperty(buffer, - nsCSSProps::eEnabledForAllContent); - if (prop != eCSSProperty_UNKNOWN && - nsCSSProps::PropHasFlags(prop, - CSS_PROPERTY_CREATES_STACKING_CONTEXT)) - { - display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT; - } - } - } - break; - } - - case eCSSUnit_Inherit: - display->mWillChange = parentDisplay->mWillChange; - display->mWillChangeBitField = parentDisplay->mWillChangeBitField; - canStoreInRuleTree = false; - break; - - case eCSSUnit_Initial: - case eCSSUnit_Unset: - case eCSSUnit_Auto: - display->mWillChange.Clear(); - display->mWillChangeBitField = 0; - break; - - default: - MOZ_ASSERT(false, "unrecognized will-change unit"); - } - - /* Convert -moz-transform-origin. */ - const nsCSSValue* transformOriginValue = - aRuleData->ValueForTransformOrigin(); - if (transformOriginValue->GetUnit() != eCSSUnit_Null) { - const nsCSSValue& valX = - transformOriginValue->GetUnit() == eCSSUnit_Triplet ? - transformOriginValue->GetTripletValue().mXValue : *transformOriginValue; - const nsCSSValue& valY = - transformOriginValue->GetUnit() == eCSSUnit_Triplet ? - transformOriginValue->GetTripletValue().mYValue : *transformOriginValue; - const nsCSSValue& valZ = - transformOriginValue->GetUnit() == eCSSUnit_Triplet ? - transformOriginValue->GetTripletValue().mZValue : *transformOriginValue; - - mozilla::DebugOnly cX = - SetCoord(valX, display->mTransformOrigin[0], - parentDisplay->mTransformOrigin[0], - SETCOORD_LPH | SETCOORD_INITIAL_HALF | - SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - - mozilla::DebugOnly cY = - SetCoord(valY, display->mTransformOrigin[1], - parentDisplay->mTransformOrigin[1], - SETCOORD_LPH | SETCOORD_INITIAL_HALF | - SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - - if (valZ.GetUnit() == eCSSUnit_Null) { - // Null for the z component means a 0 translation, not - // unspecified, as we have already checked the triplet - // value for Null. - display->mTransformOrigin[2].SetCoordValue(0); - } else { - mozilla::DebugOnly cZ = - SetCoord(valZ, display->mTransformOrigin[2], - parentDisplay->mTransformOrigin[2], - SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - MOZ_ASSERT(cY == cZ, "changed one but not the other"); - } - MOZ_ASSERT(cX == cY, "changed one but not the other"); - NS_ASSERTION(cX, "Malformed -moz-transform-origin parse!"); - } - - const nsCSSValue* perspectiveOriginValue = - aRuleData->ValueForPerspectiveOrigin(); - if (perspectiveOriginValue->GetUnit() != eCSSUnit_Null) { - mozilla::DebugOnly result = - SetPairCoords(*perspectiveOriginValue, - display->mPerspectiveOrigin[0], - display->mPerspectiveOrigin[1], - parentDisplay->mPerspectiveOrigin[0], - parentDisplay->mPerspectiveOrigin[1], - SETCOORD_LPH | SETCOORD_INITIAL_HALF | - SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - NS_ASSERTION(result, "Malformed -moz-perspective-origin parse!"); - } - - SetCoord(*aRuleData->ValueForPerspective(), - display->mChildPerspective, parentDisplay->mChildPerspective, - SETCOORD_LAH | SETCOORD_INITIAL_NONE | SETCOORD_NONE | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - - SetDiscrete(*aRuleData->ValueForBackfaceVisibility(), - display->mBackfaceVisibility, canStoreInRuleTree, - SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, - parentDisplay->mBackfaceVisibility, - NS_STYLE_BACKFACE_VISIBILITY_VISIBLE, 0, 0, 0, 0); - - // transform-style: enum, inherit, initial - SetDiscrete(*aRuleData->ValueForTransformStyle(), - display->mTransformStyle, canStoreInRuleTree, - SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, - parentDisplay->mTransformStyle, - NS_STYLE_TRANSFORM_STYLE_FLAT, 0, 0, 0, 0); - // orient: enum, inherit, initial SetDiscrete(*aRuleData->ValueForOrient(), display->mOrient, canStoreInRuleTree, @@ -7696,6 +7445,80 @@ nsRuleNode::ComputePositionData(void* aStartStruct, 0, 0, 0, 0); } + // clip property: length, auto, inherit + const nsCSSValue* clipValue = aRuleData->ValueForClip(); + switch (clipValue->GetUnit()) { + case eCSSUnit_Inherit: + canStoreInRuleTree = false; + pos->mClipFlags = parentPos->mClipFlags; + pos->mClip = parentPos->mClip; + break; + + case eCSSUnit_Initial: + case eCSSUnit_Unset: + case eCSSUnit_Auto: + pos->mClipFlags = NS_STYLE_CLIP_AUTO; + pos->mClip.SetRect(0,0,0,0); + break; + + case eCSSUnit_Null: + break; + + case eCSSUnit_Rect: { + const nsCSSRect& clipRect = clipValue->GetRectValue(); + + pos->mClipFlags = NS_STYLE_CLIP_RECT; + + if (clipRect.mTop.GetUnit() == eCSSUnit_Auto) { + pos->mClip.y = 0; + pos->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; + } + else if (clipRect.mTop.IsLengthUnit()) { + pos->mClip.y = CalcLength(clipRect.mTop, aContext, + mPresContext, canStoreInRuleTree); + } + + if (clipRect.mBottom.GetUnit() == eCSSUnit_Auto) { + // Setting to NS_MAXSIZE for the 'auto' case ensures that + // the clip rect is nonempty. It is important that mClip be + // nonempty if the actual clip rect could be nonempty. + pos->mClip.height = NS_MAXSIZE; + pos->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; + } + else if (clipRect.mBottom.IsLengthUnit()) { + pos->mClip.height = CalcLength(clipRect.mBottom, aContext, + mPresContext, canStoreInRuleTree) - + pos->mClip.y; + } + + if (clipRect.mLeft.GetUnit() == eCSSUnit_Auto) { + pos->mClip.x = 0; + pos->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; + } + else if (clipRect.mLeft.IsLengthUnit()) { + pos->mClip.x = CalcLength(clipRect.mLeft, aContext, + mPresContext, canStoreInRuleTree); + } + + if (clipRect.mRight.GetUnit() == eCSSUnit_Auto) { + // Setting to NS_MAXSIZE for the 'auto' case ensures that + // the clip rect is nonempty. It is important that mClip be + // nonempty if the actual clip rect could be nonempty. + pos->mClip.width = NS_MAXSIZE; + pos->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; + } + else if (clipRect.mRight.IsLengthUnit()) { + pos->mClip.width = CalcLength(clipRect.mRight, aContext, + mPresContext, canStoreInRuleTree) - + pos->mClip.x; + } + break; + } + + default: + MOZ_ASSERT(false, "unrecognized clip unit"); + } + // flex-basis: auto, length, percent, enum, calc, inherit, initial // (Note: The flags here should match those used for 'width' property above.) SetCoord(*aRuleData->ValueForFlexBasis(), pos->mFlexBasis, parentPos->mFlexBasis, @@ -7843,6 +7666,183 @@ nsRuleNode::ComputePositionData(void* aStartStruct, parentPos->mGridRowEnd, canStoreInRuleTree); + /* Convert the nsCSSValueList into an nsTArray. */ + const nsCSSValue* transformValue = aRuleData->ValueForTransform(); + switch (transformValue->GetUnit()) { + case eCSSUnit_Null: + break; + + case eCSSUnit_Initial: + case eCSSUnit_Unset: + case eCSSUnit_None: + pos->mSpecifiedTransform = nullptr; + break; + + case eCSSUnit_Inherit: + pos->mSpecifiedTransform = parentPos->mSpecifiedTransform; + canStoreInRuleTree = false; + break; + + case eCSSUnit_SharedList: { + nsCSSValueSharedList* list = transformValue->GetSharedListValue(); + nsCSSValueList* head = list->mHead; + MOZ_ASSERT(head, "transform list must have at least one item"); + // can get a _None in here from transform animation + if (head->mValue.GetUnit() == eCSSUnit_None) { + MOZ_ASSERT(head->mNext == nullptr, "none must be alone"); + pos->mSpecifiedTransform = nullptr; + } else { + pos->mSpecifiedTransform = list; + } + break; + } + + default: + MOZ_ASSERT(false, "unrecognized transform unit"); + } + + /* Convert -moz-transform-origin. */ + const nsCSSValue* transformOriginValue = + aRuleData->ValueForTransformOrigin(); + if (transformOriginValue->GetUnit() != eCSSUnit_Null) { + const nsCSSValue& valX = + transformOriginValue->GetUnit() == eCSSUnit_Triplet ? + transformOriginValue->GetTripletValue().mXValue : *transformOriginValue; + const nsCSSValue& valY = + transformOriginValue->GetUnit() == eCSSUnit_Triplet ? + transformOriginValue->GetTripletValue().mYValue : *transformOriginValue; + const nsCSSValue& valZ = + transformOriginValue->GetUnit() == eCSSUnit_Triplet ? + transformOriginValue->GetTripletValue().mZValue : *transformOriginValue; + + mozilla::DebugOnly cX = + SetCoord(valX, pos->mTransformOrigin[0], + parentPos->mTransformOrigin[0], + SETCOORD_LPH | SETCOORD_INITIAL_HALF | + SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + + mozilla::DebugOnly cY = + SetCoord(valY, pos->mTransformOrigin[1], + parentPos->mTransformOrigin[1], + SETCOORD_LPH | SETCOORD_INITIAL_HALF | + SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + + if (valZ.GetUnit() == eCSSUnit_Null) { + // Null for the z component means a 0 translation, not + // unspecified, as we have already checked the triplet + // value for Null. + pos->mTransformOrigin[2].SetCoordValue(0); + } else { + mozilla::DebugOnly cZ = + SetCoord(valZ, pos->mTransformOrigin[2], + parentPos->mTransformOrigin[2], + SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + MOZ_ASSERT(cY == cZ, "changed one but not the other"); + } + MOZ_ASSERT(cX == cY, "changed one but not the other"); + NS_ASSERTION(cX, "Malformed -moz-transform-origin parse!"); + } + + const nsCSSValue* perspectiveOriginValue = + aRuleData->ValueForPerspectiveOrigin(); + if (perspectiveOriginValue->GetUnit() != eCSSUnit_Null) { + mozilla::DebugOnly result = + SetPairCoords(*perspectiveOriginValue, + pos->mPerspectiveOrigin[0], + pos->mPerspectiveOrigin[1], + parentPos->mPerspectiveOrigin[0], + parentPos->mPerspectiveOrigin[1], + SETCOORD_LPH | SETCOORD_INITIAL_HALF | + SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + NS_ASSERTION(result, "Malformed -moz-perspective-origin parse!"); + } + + SetCoord(*aRuleData->ValueForPerspective(), + pos->mChildPerspective, parentPos->mChildPerspective, + SETCOORD_LAH | SETCOORD_INITIAL_NONE | SETCOORD_NONE | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + + SetDiscrete(*aRuleData->ValueForBackfaceVisibility(), + pos->mBackfaceVisibility, canStoreInRuleTree, + SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, + parentPos->mBackfaceVisibility, + NS_STYLE_BACKFACE_VISIBILITY_VISIBLE, 0, 0, 0, 0); + + // transform-style: enum, inherit, initial + SetDiscrete(*aRuleData->ValueForTransformStyle(), + pos->mTransformStyle, canStoreInRuleTree, + SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, + parentPos->mTransformStyle, + NS_STYLE_TRANSFORM_STYLE_FLAT, 0, 0, 0, 0); + + /* Convert the nsCSSValueList into a will-change bitfield for fast lookup */ + const nsCSSValue* willChangeValue = aRuleData->ValueForWillChange(); + switch (willChangeValue->GetUnit()) { + case eCSSUnit_Null: + break; + + case eCSSUnit_List: + case eCSSUnit_ListDep: { + pos->mWillChange.Clear(); + pos->mWillChangeBitField = 0; + for (const nsCSSValueList* item = willChangeValue->GetListValue(); + item; item = item->mNext) + { + if (item->mValue.UnitHasStringValue()) { + nsAutoString buffer; + item->mValue.GetStringValue(buffer); + pos->mWillChange.AppendElement(buffer); + + if (buffer.EqualsLiteral("transform")) { + pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_TRANSFORM; + } + if (buffer.EqualsLiteral("opacity")) { + pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_OPACITY; + } + if (buffer.EqualsLiteral("scroll-position")) { + pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_SCROLL; + } + + nsCSSProperty prop = + nsCSSProps::LookupProperty(buffer, + nsCSSProps::eEnabledForAllContent); + if (prop != eCSSProperty_UNKNOWN && + nsCSSProps::PropHasFlags(prop, + CSS_PROPERTY_CREATES_STACKING_CONTEXT)) + { + pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT; + } + } + } + break; + } + + case eCSSUnit_Inherit: + pos->mWillChange = parentPos->mWillChange; + pos->mWillChangeBitField = parentPos->mWillChangeBitField; + canStoreInRuleTree = false; + break; + + case eCSSUnit_Initial: + case eCSSUnit_Unset: + case eCSSUnit_Auto: + pos->mWillChange.Clear(); + pos->mWillChangeBitField = 0; + break; + + default: + MOZ_ASSERT(false, "unrecognized will-change unit"); + } + // z-index const nsCSSValue* zIndexValue = aRuleData->ValueForZIndex(); if (! SetCoord(*zIndexValue, pos->mZIndex, parentPos->mZIndex, diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 460e76d427f0..763893f12424 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -1020,10 +1020,12 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_VECTOR_EFFECT_NONE 0 #define NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE 1 +// backface-visibility // 3d Transforms - Backface visibility #define NS_STYLE_BACKFACE_VISIBILITY_VISIBLE 1 #define NS_STYLE_BACKFACE_VISIBILITY_HIDDEN 0 +// transform-style #define NS_STYLE_TRANSFORM_STYLE_FLAT 0 #define NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D 1 diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 832e4f105f76..e24e5e2ea020 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1379,12 +1379,14 @@ bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const // nsStylePosition // nsStylePosition::nsStylePosition(void) + : mWillChangeBitField(0) { MOZ_COUNT_CTOR(nsStylePosition); // positioning values not inherited mObjectPosition.SetInitialPercentValues(0.5f); + mClip.SetRect(0,0,0,0); nsStyleCoord autoCoord(eStyleUnit_Auto); mOffset.SetLeft(autoCoord); @@ -1410,6 +1412,13 @@ nsStylePosition::nsStylePosition(void) mGridAutoRowsMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT, eStyleUnit_Enumerated); + mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin + mTransformOrigin[1].SetPercentValue(0.5f); + mTransformOrigin[2].SetCoordValue(0); + mChildPerspective.SetNoneValue(); + mPerspectiveOrigin[0].SetPercentValue(0.5f); + mPerspectiveOrigin[1].SetPercentValue(0.5f); + mGridAutoFlow = NS_STYLE_GRID_AUTO_FLOW_ROW; mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT; mAlignContent = NS_STYLE_ALIGN_CONTENT_STRETCH; @@ -1419,10 +1428,14 @@ nsStylePosition::nsStylePosition(void) mFlexWrap = NS_STYLE_FLEX_WRAP_NOWRAP; mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START; mObjectFit = NS_STYLE_OBJECT_FIT_FILL; + mClipFlags = NS_STYLE_CLIP_AUTO; + mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE; + mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT; mOrder = NS_STYLE_ORDER_INITIAL; mFlexGrow = 0.0f; mFlexShrink = 1.0f; mZIndex.SetAutoValue(); + mSpecifiedTransform = nullptr; // Other members get their default constructors // which initialize them to representations of their respective initial value. // mGridTemplateAreas: nullptr for 'none' @@ -1437,6 +1450,7 @@ nsStylePosition::~nsStylePosition(void) nsStylePosition::nsStylePosition(const nsStylePosition& aSource) : mObjectPosition(aSource.mObjectPosition) + , mClip(aSource.mClip) , mOffset(aSource.mOffset) , mWidth(aSource.mWidth) , mMinWidth(aSource.mMinWidth) @@ -1449,6 +1463,7 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mGridAutoColumnsMax(aSource.mGridAutoColumnsMax) , mGridAutoRowsMin(aSource.mGridAutoRowsMin) , mGridAutoRowsMax(aSource.mGridAutoRowsMax) + , mChildPerspective(aSource.mChildPerspective) , mGridAutoFlow(aSource.mGridAutoFlow) , mBoxSizing(aSource.mBoxSizing) , mAlignContent(aSource.mAlignContent) @@ -1458,6 +1473,10 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mFlexWrap(aSource.mFlexWrap) , mJustifyContent(aSource.mJustifyContent) , mObjectFit(aSource.mObjectFit) + , mClipFlags(aSource.mClipFlags) + , mBackfaceVisibility(aSource.mBackfaceVisibility) + , mTransformStyle(aSource.mTransformStyle) + , mWillChangeBitField(aSource.mWillChangeBitField) , mOrder(aSource.mOrder) , mFlexGrow(aSource.mFlexGrow) , mFlexShrink(aSource.mFlexShrink) @@ -1469,8 +1488,17 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mGridColumnEnd(aSource.mGridColumnEnd) , mGridRowStart(aSource.mGridRowStart) , mGridRowEnd(aSource.mGridRowEnd) + , mSpecifiedTransform(aSource.mSpecifiedTransform) + , mWillChange(aSource.mWillChange) { MOZ_COUNT_CTOR(nsStylePosition); + + /* Copy over transform origin. */ + mTransformOrigin[0] = aSource.mTransformOrigin[0]; + mTransformOrigin[1] = aSource.mTransformOrigin[1]; + mTransformOrigin[2] = aSource.mTransformOrigin[2]; + mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0]; + mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1]; } static bool @@ -1503,6 +1531,96 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons nsChangeHint_NeedReflow)); } + if (mClipFlags != aOther.mClipFlags) { + NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AllReflowHints, + nsChangeHint_RepaintFrame)); + } + + if (!mClip.IsEqualInterior(aOther.mClip)) { + // If the clip has changed, we just need to update overflow areas. DLBI + // will handle the invalidation. + NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow, + nsChangeHint_SchedulePaint)); + } + + /* If we've added or removed the transform property, we need to reconstruct the frame to add + * or remove the view object, and also to handle abs-pos and fixed-pos containers. + */ + if (HasTransformStyle() != aOther.HasTransformStyle()) { + // We do not need to apply nsChangeHint_UpdateTransformLayer since + // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and + // ensure layers are rebuilt (or removed). + NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AddOrRemoveTransform, + NS_CombineHint(nsChangeHint_UpdateOverflow, + nsChangeHint_RepaintFrame))); + } else { + /* Otherwise, if we've kept the property lying around and we already had a + * transform, we need to see whether or not we've changed the transform. + * If so, we need to recompute its overflow rect (which probably changed + * if the transform changed) and to redraw within the bounds of that new + * overflow rect. + * + * If the property isn't present in either style struct, we still do the + * comparisons but turn all the resulting change hints into + * nsChangeHint_NeutralChange. + */ + nsChangeHint transformHint = nsChangeHint(0); + + if (!mSpecifiedTransform != !aOther.mSpecifiedTransform || + (mSpecifiedTransform && + *mSpecifiedTransform != *aOther.mSpecifiedTransform)) { + NS_UpdateHint(transformHint, nsChangeHint_UpdateTransformLayer); + + if (mSpecifiedTransform && + aOther.mSpecifiedTransform) { + NS_UpdateHint(transformHint, nsChangeHint_UpdatePostTransformOverflow); + } else { + NS_UpdateHint(transformHint, nsChangeHint_UpdateOverflow); + } + } + + const nsChangeHint kUpdateOverflowAndRepaintHint = + NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame); + for (uint8_t index = 0; index < 3; ++index) + if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) { + NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); + break; + } + + for (uint8_t index = 0; index < 2; ++index) + if (mPerspectiveOrigin[index] != aOther.mPerspectiveOrigin[index]) { + NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); + break; + } + + if (mChildPerspective != aOther.mChildPerspective || + mTransformStyle != aOther.mTransformStyle) + NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); + + if (mBackfaceVisibility != aOther.mBackfaceVisibility) + NS_UpdateHint(transformHint, nsChangeHint_RepaintFrame); + + if (transformHint) { + if (HasTransformStyle()) { + NS_UpdateHint(hint, transformHint); + } else { + NS_UpdateHint(hint, nsChangeHint_NeutralChange); + } + } + } + + // Note that the HasTransformStyle() != aOther.HasTransformStyle() + // test above handles relevant changes in the + // NS_STYLE_WILL_CHANGE_TRANSFORM bit, which in turn handles frame + // reconstruction for changes in the containing block of + // fixed-positioned elements. Other than that, all changes to + // 'will-change' can be handled by a repaint. + uint8_t willChangeBitsChanged = + mWillChangeBitField ^ aOther.mWillChangeBitField; + if (willChangeBitsChanged) { + NS_UpdateHint(hint, nsChangeHint_RepaintFrame); + } + if (mOrder != aOther.mOrder) { // "order" impacts both layout order and stacking order, so we need both a // reflow and a repaint when it changes. (Technically, we only need a @@ -1623,6 +1741,10 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons return NS_CombineHint(hint, nsChangeHint_AllReflowHints); } } + + if (!hint && !mClip.IsEqualEdges(aOther.mClip)) { + return nsChangeHint_NeutralChange; + } return hint; } @@ -2567,7 +2689,6 @@ mozilla::StyleAnimation::operator==(const mozilla::StyleAnimation& aOther) const } nsStyleDisplay::nsStyleDisplay() - : mWillChangeBitField(0) { MOZ_COUNT_CTOR(nsStyleDisplay); mAppearance = NS_THEME_NONE; @@ -2584,18 +2705,7 @@ nsStyleDisplay::nsStyleDisplay() mOverflowY = NS_STYLE_OVERFLOW_VISIBLE; mOverflowClipBox = NS_STYLE_OVERFLOW_CLIP_BOX_PADDING_BOX; mResize = NS_STYLE_RESIZE_NONE; - mClipFlags = NS_STYLE_CLIP_AUTO; - mClip.SetRect(0,0,0,0); mOpacity = 1.0f; - mSpecifiedTransform = nullptr; - mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin - mTransformOrigin[1].SetPercentValue(0.5f); - mTransformOrigin[2].SetCoordValue(0); - mPerspectiveOrigin[0].SetPercentValue(0.5f); - mPerspectiveOrigin[1].SetPercentValue(0.5f); - mChildPerspective.SetNoneValue(); - mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE; - mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT; mOrient = NS_STYLE_ORIENT_AUTO; mMixBlendMode = NS_STYLE_BLEND_NORMAL; mIsolation = NS_STYLE_ISOLATION_AUTO; @@ -2633,7 +2743,6 @@ nsStyleDisplay::nsStyleDisplay() nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) : mBinding(aSource.mBinding) - , mClip(aSource.mClip) , mOpacity(aSource.mOpacity) , mDisplay(aSource.mDisplay) , mOriginalDisplay(aSource.mOriginalDisplay) @@ -2649,12 +2758,9 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mOverflowY(aSource.mOverflowY) , mOverflowClipBox(aSource.mOverflowClipBox) , mResize(aSource.mResize) - , mClipFlags(aSource.mClipFlags) , mOrient(aSource.mOrient) , mMixBlendMode(aSource.mMixBlendMode) , mIsolation(aSource.mIsolation) - , mWillChangeBitField(aSource.mWillChangeBitField) - , mWillChange(aSource.mWillChange) , mTouchAction(aSource.mTouchAction) , mScrollBehavior(aSource.mScrollBehavior) , mScrollSnapTypeX(aSource.mScrollSnapTypeX) @@ -2663,10 +2769,6 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mScrollSnapPointsY(aSource.mScrollSnapPointsY) , mScrollSnapDestination(aSource.mScrollSnapDestination) , mScrollSnapCoordinate(aSource.mScrollSnapCoordinate) - , mBackfaceVisibility(aSource.mBackfaceVisibility) - , mTransformStyle(aSource.mTransformStyle) - , mSpecifiedTransform(aSource.mSpecifiedTransform) - , mChildPerspective(aSource.mChildPerspective) , mTransitions(aSource.mTransitions) , mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount) , mTransitionDurationCount(aSource.mTransitionDurationCount) @@ -2683,13 +2785,6 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mAnimationIterationCountCount(aSource.mAnimationIterationCountCount) { MOZ_COUNT_CTOR(nsStyleDisplay); - - /* Copy over transform origin. */ - mTransformOrigin[0] = aSource.mTransformOrigin[0]; - mTransformOrigin[1] = aSource.mTransformOrigin[1]; - mTransformOrigin[2] = aSource.mTransformOrigin[2]; - mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0]; - mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1]; } nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const @@ -2752,18 +2847,10 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const || mBreakAfter != aOther.mBreakAfter || mAppearance != aOther.mAppearance || mOrient != aOther.mOrient - || mOverflowClipBox != aOther.mOverflowClipBox - || mClipFlags != aOther.mClipFlags) + || mOverflowClipBox != aOther.mOverflowClipBox) NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AllReflowHints, nsChangeHint_RepaintFrame)); - if (!mClip.IsEqualInterior(aOther.mClip)) { - // If the clip has changed, we just need to update overflow areas. DLBI - // will handle the invalidation. - NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow, - nsChangeHint_SchedulePaint)); - } - if (mOpacity != aOther.mOpacity) { // If we're going from the optimized >=0.99 opacity value to 1.0 or back, then // repaint the frame because DLBI will not catch the invalidation. Otherwise, @@ -2781,84 +2868,6 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const NS_UpdateHint(hint, nsChangeHint_RepaintFrame); } - /* If we've added or removed the transform property, we need to reconstruct the frame to add - * or remove the view object, and also to handle abs-pos and fixed-pos containers. - */ - if (HasTransformStyle() != aOther.HasTransformStyle()) { - // We do not need to apply nsChangeHint_UpdateTransformLayer since - // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and - // ensure layers are rebuilt (or removed). - NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AddOrRemoveTransform, - NS_CombineHint(nsChangeHint_UpdateOverflow, - nsChangeHint_RepaintFrame))); - } else { - /* Otherwise, if we've kept the property lying around and we already had a - * transform, we need to see whether or not we've changed the transform. - * If so, we need to recompute its overflow rect (which probably changed - * if the transform changed) and to redraw within the bounds of that new - * overflow rect. - * - * If the property isn't present in either style struct, we still do the - * comparisons but turn all the resulting change hints into - * nsChangeHint_NeutralChange. - */ - nsChangeHint transformHint = nsChangeHint(0); - - if (!mSpecifiedTransform != !aOther.mSpecifiedTransform || - (mSpecifiedTransform && - *mSpecifiedTransform != *aOther.mSpecifiedTransform)) { - NS_UpdateHint(transformHint, nsChangeHint_UpdateTransformLayer); - - if (mSpecifiedTransform && - aOther.mSpecifiedTransform) { - NS_UpdateHint(transformHint, nsChangeHint_UpdatePostTransformOverflow); - } else { - NS_UpdateHint(transformHint, nsChangeHint_UpdateOverflow); - } - } - - const nsChangeHint kUpdateOverflowAndRepaintHint = - NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame); - for (uint8_t index = 0; index < 3; ++index) - if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) { - NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); - break; - } - - for (uint8_t index = 0; index < 2; ++index) - if (mPerspectiveOrigin[index] != aOther.mPerspectiveOrigin[index]) { - NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); - break; - } - - if (mChildPerspective != aOther.mChildPerspective || - mTransformStyle != aOther.mTransformStyle) - NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); - - if (mBackfaceVisibility != aOther.mBackfaceVisibility) - NS_UpdateHint(transformHint, nsChangeHint_RepaintFrame); - - if (transformHint) { - if (HasTransformStyle()) { - NS_UpdateHint(hint, transformHint); - } else { - NS_UpdateHint(hint, nsChangeHint_NeutralChange); - } - } - } - - // Note that the HasTransformStyle() != aOther.HasTransformStyle() - // test above handles relevant changes in the - // NS_STYLE_WILL_CHANGE_TRANSFORM bit, which in turn handles frame - // reconstruction for changes in the containing block of - // fixed-positioned elements. Other than that, all changes to - // 'will-change' can be handled by a repaint. - uint8_t willChangeBitsChanged = - mWillChangeBitField ^ aOther.mWillChangeBitField; - if (willChangeBitsChanged) { - NS_UpdateHint(hint, nsChangeHint_RepaintFrame); - } - // Note: Our current behavior for handling changes to the // transition-duration, transition-delay, and transition-timing-function // properties is to do nothing. In other words, the transition @@ -2877,8 +2886,7 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const // properties, since some data did change in the style struct. if (!hint && - (!mClip.IsEqualEdges(aOther.mClip) || - mOriginalDisplay != aOther.mOriginalDisplay || + (mOriginalDisplay != aOther.mOriginalDisplay || mOriginalFloats != aOther.mOriginalFloats || mTransitions != aOther.mTransitions || mTransitionTimingFunctionCount != diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 71a63da88121..d4459bda89e4 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1333,9 +1333,14 @@ struct nsStylePosition { nsChangeHint CalcDifference(const nsStylePosition& aOther) const; static nsChangeHint MaxDifference() { - return NS_CombineHint(NS_STYLE_HINT_REFLOW, - nsChangeHint(nsChangeHint_RecomputePosition | - nsChangeHint_UpdateParentOverflow)); + return nsChangeHint(NS_STYLE_HINT_REFLOW | + nsChangeHint_RecomputePosition | + nsChangeHint_UpdateTransformLayer | + nsChangeHint_UpdateOverflow | + nsChangeHint_UpdateParentOverflow | + nsChangeHint_UpdatePostTransformOverflow | + nsChangeHint_AddOrRemoveTransform | + nsChangeHint_NeutralChange); } static nsChangeHint MaxDifferenceNeverInherited() { // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and @@ -1348,6 +1353,7 @@ struct nsStylePosition { typedef nsStyleBackground::Position Position; Position mObjectPosition; // [reset] + nsRect mClip; // [reset] offsets from upper-left border edge nsStyleSides mOffset; // [reset] coord, percent, calc, auto nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc @@ -1360,6 +1366,9 @@ struct nsStylePosition { nsStyleCoord mGridAutoColumnsMax; // [reset] coord, percent, enum, calc, flex nsStyleCoord mGridAutoRowsMin; // [reset] coord, percent, enum, calc, flex nsStyleCoord mGridAutoRowsMax; // [reset] coord, percent, enum, calc, flex + nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only + nsStyleCoord mChildPerspective; // [reset] coord + nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h uint8_t mBoxSizing; // [reset] see nsStyleConsts.h uint8_t mAlignContent; // [reset] see nsStyleConsts.h @@ -1369,6 +1378,15 @@ struct nsStylePosition { uint8_t mFlexWrap; // [reset] see nsStyleConsts.h uint8_t mJustifyContent; // [reset] see nsStyleConsts.h uint8_t mObjectFit; // [reset] see nsStyleConsts.h + uint8_t mClipFlags; // [reset] see nsStyleConsts.h + uint8_t mBackfaceVisibility; // [reset] see nsStyleConsts.h + uint8_t mTransformStyle; // [reset] see nsStyleConsts.h + uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a + // bitfield representation of the properties + // that are frequently queried. This should + // match mWillChange. Also tracks if any of the + // properties in the will-change list require + // a stacking context. int32_t mOrder; // [reset] integer float mFlexGrow; // [reset] float float mFlexShrink; // [reset] float @@ -1384,6 +1402,14 @@ struct nsStylePosition { nsStyleGridLine mGridRowStart; nsStyleGridLine mGridRowEnd; + // mSpecifiedTransform is the list of transform functions as + // specified, or null to indicate there is no transform. (inherit or + // initial are replaced by an actual list of transform functions, or + // null, as appropriate.) + nsRefPtr mSpecifiedTransform; // [reset] + + nsAutoTArray mWillChange; // see mWillChangeBitField + bool WidthDependsOnContainer() const { return mWidth.GetUnit() == eStyleUnit_Auto || @@ -1427,6 +1453,27 @@ struct nsStylePosition { return mOffset.Get(aSide).HasPercent(); } + /* Returns whether the element has the -moz-transform property + * or a related property. */ + bool HasTransformStyle() const { + return mSpecifiedTransform != nullptr || + mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || + (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM); + } + + bool HasPerspectiveStyle() const { + return mChildPerspective.GetUnit() == eStyleUnit_Coord; + } + + bool BackfaceIsHidden() const { + return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN; + } + + // This method is defined in nsStyleStructInlines.h. + /* Returns whether the element has the -moz-transform property + * or a related property, and supports CSS transforms. */ + inline bool HasTransform(const nsIFrame* aContextFrame) const; + private: static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord); static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord) @@ -2003,10 +2050,6 @@ struct nsStyleDisplay { // All the parts of FRAMECHANGE are present in CalcDifference. return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE | nsChangeHint_UpdateOpacityLayer | - nsChangeHint_UpdateTransformLayer | - nsChangeHint_UpdateOverflow | - nsChangeHint_UpdatePostTransformOverflow | - nsChangeHint_AddOrRemoveTransform | nsChangeHint_NeutralChange); } static nsChangeHint MaxDifferenceNeverInherited() { @@ -2023,7 +2066,6 @@ struct nsStyleDisplay { // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and // mBinding->mOriginPrincipal. nsRefPtr mBinding; // [reset] - nsRect mClip; // [reset] offsets from upper-left border edge float mOpacity; // [reset] uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_* uint8_t mOriginalDisplay; // [reset] saved mDisplay for position:absolute/fixed @@ -2042,17 +2084,9 @@ struct nsStyleDisplay { uint8_t mOverflowY; // [reset] see nsStyleConsts.h uint8_t mOverflowClipBox; // [reset] see nsStyleConsts.h uint8_t mResize; // [reset] see nsStyleConsts.h - uint8_t mClipFlags; // [reset] see nsStyleConsts.h uint8_t mOrient; // [reset] see nsStyleConsts.h uint8_t mMixBlendMode; // [reset] see nsStyleConsts.h uint8_t mIsolation; // [reset] see nsStyleConsts.h - uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a - // bitfield representation of the properties - // that are frequently queried. This should - // match mWillChange. Also tracks if any of the - // properties in the will-change list require - // a stacking context. - nsAutoTArray mWillChange; uint8_t mTouchAction; // [reset] see nsStyleConsts.h uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_* @@ -2063,17 +2097,6 @@ struct nsStyleDisplay { Position mScrollSnapDestination; // [reset] nsTArray mScrollSnapCoordinate; // [reset] - // mSpecifiedTransform is the list of transform functions as - // specified, or null to indicate there is no transform. (inherit or - // initial are replaced by an actual list of transform functions, or - // null, as appropriate.) - uint8_t mBackfaceVisibility; - uint8_t mTransformStyle; - nsRefPtr mSpecifiedTransform; // [reset] - nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only - nsStyleCoord mChildPerspective; // [reset] coord - nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc - nsAutoTArray mTransitions; // [reset] // The number of elements in mTransitions that are not from repeating // a list due to another property being longer. @@ -2192,22 +2215,6 @@ struct nsStyleDisplay { mOverflowX != NS_STYLE_OVERFLOW_CLIP; } - /* Returns whether the element has the -moz-transform property - * or a related property. */ - bool HasTransformStyle() const { - return mSpecifiedTransform != nullptr || - mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || - (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM); - } - - bool HasPerspectiveStyle() const { - return mChildPerspective.GetUnit() == eStyleUnit_Coord; - } - - bool BackfaceIsHidden() const { - return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN; - } - // These are defined in nsStyleStructInlines.h. // The aContextFrame argument on each of these is the frame this @@ -2223,10 +2230,6 @@ struct nsStyleDisplay { inline bool IsPositioned(const nsIFrame* aContextFrame) const; inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const; inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const; - - /* Returns whether the element has the -moz-transform property - * or a related property, and supports CSS transforms. */ - inline bool HasTransform(const nsIFrame* aContextFrame) const; }; struct nsStyleTable { diff --git a/layout/style/nsStyleStructInlines.h b/layout/style/nsStyleStructInlines.h index c6410621dbad..1360c0baae8b 100644 --- a/layout/style/nsStyleStructInlines.h +++ b/layout/style/nsStyleStructInlines.h @@ -30,6 +30,13 @@ nsStyleImage::GetSubImage(uint8_t aIndex) const return subImage; } +bool +nsStylePosition::HasTransform(const nsIFrame* aContextFrame) const +{ + NS_ASSERTION(aContextFrame->StylePosition() == this, "unexpected aContextFrame"); + return HasTransformStyle() && aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms); +} + bool nsStyleText::HasTextShadow() const { @@ -116,23 +123,24 @@ nsStyleDisplay::IsFloating(const nsIFrame* aContextFrame) const return IsFloatingStyle() && !aContextFrame->IsSVGText(); } -bool -nsStyleDisplay::HasTransform(const nsIFrame* aContextFrame) const -{ - NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame"); - return HasTransformStyle() && aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms); -} - bool nsStyleDisplay::IsPositioned(const nsIFrame* aContextFrame) const { NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame"); - return (IsAbsolutelyPositionedStyle() || - IsRelativelyPositionedStyle() || - HasTransform(aContextFrame) || - HasPerspectiveStyle()) && - !aContextFrame->IsSVGText(); + if (aContextFrame->IsSVGText()) { + return false; + } + if (IsAbsolutelyPositionedStyle() || + IsRelativelyPositionedStyle()) { + return true; + } + const nsStylePosition* position = aContextFrame->StylePosition(); + if (position->HasTransform(aContextFrame) || + position->HasPerspectiveStyle()) { + return true; + } + return false; } bool diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 5b0b6b0e272e..4b93cc726eca 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -827,9 +827,10 @@ nsSVGUtils::GetClipRectForFrame(nsIFrame *aFrame, float aX, float aY, float aWidth, float aHeight) { const nsStyleDisplay* disp = aFrame->StyleDisplay(); + const nsStylePosition* pos = aFrame->StylePosition(); - if (!(disp->mClipFlags & NS_STYLE_CLIP_RECT)) { - NS_ASSERTION(disp->mClipFlags == NS_STYLE_CLIP_AUTO, + if (!(pos->mClipFlags & NS_STYLE_CLIP_RECT)) { + NS_ASSERTION(pos->mClipFlags == NS_STYLE_CLIP_AUTO, "We don't know about this type of clip."); return gfxRect(aX, aY, aWidth, aHeight); } @@ -838,14 +839,14 @@ nsSVGUtils::GetClipRectForFrame(nsIFrame *aFrame, disp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) { nsIntRect clipPxRect = - disp->mClip.ToOutsidePixels(aFrame->PresContext()->AppUnitsPerDevPixel()); + pos->mClip.ToOutsidePixels(aFrame->PresContext()->AppUnitsPerDevPixel()); gfxRect clipRect = gfxRect(clipPxRect.x, clipPxRect.y, clipPxRect.width, clipPxRect.height); - if (NS_STYLE_CLIP_RIGHT_AUTO & disp->mClipFlags) { + if (NS_STYLE_CLIP_RIGHT_AUTO & pos->mClipFlags) { clipRect.width = aWidth - clipRect.X(); } - if (NS_STYLE_CLIP_BOTTOM_AUTO & disp->mClipFlags) { + if (NS_STYLE_CLIP_BOTTOM_AUTO & pos->mClipFlags) { clipRect.height = aHeight - clipRect.Y(); } From d0ed313df72e2f9db79995921baefe684fdb858f Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Sun, 8 Mar 2015 04:33:57 +0200 Subject: [PATCH 40/42] Bug 1140499 - IPC Proxy for text/char bounds, r=tbsaunde --HG-- extra : rebase_source : 0921a3d535e09469a31ca1752be082ffb80851a4 --- accessible/atk/nsMaiInterfaceText.cpp | 70 ++++++++++++++++++--------- accessible/ipc/DocAccessibleChild.cpp | 29 +++++++++++ accessible/ipc/DocAccessibleChild.h | 10 ++++ accessible/ipc/PDocAccessible.ipdl | 8 +++ accessible/ipc/ProxyAccessible.cpp | 19 ++++++++ accessible/ipc/ProxyAccessible.h | 6 +++ 6 files changed, 118 insertions(+), 24 deletions(-) diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index 1f6ccf4441f5..042c4c71761d 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -338,21 +338,32 @@ getCharacterExtentsCB(AtkText *aText, gint aOffset, gint *aWidth, gint *aHeight, AtkCoordType aCoords) { + if(!aX || !aY || !aWidth || !aHeight) { + return; + } + + nsIntRect rect; + uint32_t geckoCoordType; + if (aCoords == ATK_XY_SCREEN) { + geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; + } else { + geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; + } + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if(!accWrap || !aX || !aY || !aWidth || !aHeight) + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return; + } + + rect = text->CharBounds(aOffset, geckoCoordType); + } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + rect = proxy->CharBounds(aOffset, geckoCoordType); + } else { return; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return; - - uint32_t geckoCoordType; - if (aCoords == ATK_XY_SCREEN) - geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; - else - geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; - - nsIntRect rect = text->CharBounds(aOffset, geckoCoordType); *aX = rect.x; *aY = rect.y; *aWidth = rect.width; @@ -363,21 +374,32 @@ static void getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset, AtkCoordType aCoords, AtkTextRectangle *aRect) { + if (!aRect) { + return; + } + + nsIntRect rect; + uint32_t geckoCoordType; + if (aCoords == ATK_XY_SCREEN) { + geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; + } else { + geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; + } + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if(!accWrap || !aRect) + if(accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return; + } + + rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType); + } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + rect = proxy->TextBounds(aStartOffset, aEndOffset, geckoCoordType); + } else { return; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return; - - uint32_t geckoCoordType; - if (aCoords == ATK_XY_SCREEN) - geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; - else - geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; - - nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType); aRect->x = rect.x; aRect->y = rect.y; aRect->width = rect.width; diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index f1b2772a9b8d..0d54bf7c796e 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -363,5 +363,34 @@ DocAccessibleChild::RecvDefaultTextAttributes(const uint64_t& aID, return PersistentPropertiesToArray(props, aAttributes); } +bool +DocAccessibleChild::RecvTextBounds(const uint64_t& aID, + const int32_t& aStartOffset, + const int32_t& aEndOffset, + const uint32_t& aCoordType, + nsIntRect* aRetVal) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + if (acc && acc->IsTextRole()) { + *aRetVal = acc->TextBounds(aStartOffset, aEndOffset, aCoordType); + } + + return true; +} + +bool +DocAccessibleChild::RecvCharBounds(const uint64_t& aID, + const int32_t& aOffset, + const uint32_t& aCoordType, + nsIntRect* aRetVal) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + if (acc && acc->IsTextRole()) { + *aRetVal = acc->CharBounds(aOffset, aCoordType); + } + + return true; +} + } } diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 3b14e098259f..9b55c0034216 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -111,6 +111,16 @@ public: nsTArray* aAttributes) MOZ_OVERRIDE; + virtual bool RecvTextBounds(const uint64_t& aID, + const int32_t& aStartOffset, + const int32_t& aEndOffset, + const uint32_t& aCoordType, + nsIntRect* aRetVal) MOZ_OVERRIDE; + + virtual bool RecvCharBounds(const uint64_t& aID, + const int32_t& aOffset, + const uint32_t& aCoordType, + nsIntRect* aRetVal) MOZ_OVERRIDE; private: bool PersistentPropertiesToArray(nsIPersistentProperties* aProps, nsTArray* aAttributes); diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 0ca22193a6b4..fe8e24012214 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -6,6 +6,8 @@ include protocol PContent; +using struct nsIntRect from "nsRect.h"; + namespace mozilla { namespace a11y { @@ -83,6 +85,12 @@ child: prio(high) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset) returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset); prio(high) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes); + + prio(high) sync TextBounds(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset, + uint32_t aCoordType) + returns(nsIntRect aRetVal); + prio(high) sync CharBounds(uint64_t aID, int32_t aOffset, uint32_t aCoordType) + returns(nsIntRect aRetVal); }; } diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index e3d20e2732b3..9666604b886a 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -243,5 +243,24 @@ ProxyAccessible::DefaultTextAttributes(nsTArray* aAttrs) unused << mDoc->SendDefaultTextAttributes(mID, aAttrs); } +nsIntRect +ProxyAccessible::TextBounds(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aCoordType) +{ + nsIntRect rect; + unused << + mDoc->SendTextBounds(mID, aStartOffset, aEndOffset, aCoordType, &rect); + return rect; +} + +nsIntRect +ProxyAccessible::CharBounds(int32_t aOffset, uint32_t aCoordType) +{ + nsIntRect rect; + unused << + mDoc->SendCharBounds(mID, aOffset, aCoordType, &rect); + return rect; +} + } } diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index 771105620f18..000e34414c16 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -11,6 +11,7 @@ #include "nsIAccessibleText.h" #include "nsString.h" #include "nsTArray.h" +#include "nsRect.h" namespace mozilla { namespace a11y { @@ -132,6 +133,11 @@ public: int32_t* aEndOffset); void DefaultTextAttributes(nsTArray* aAttrs); + nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aCoordType); + + nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType); + /** * Allow the platform to store a pointers worth of data on us. */ From 3d554f3389e6cc6b2ecde4d0228dbda35ed37c48 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Sun, 8 Mar 2015 14:05:55 +0200 Subject: [PATCH 41/42] Bug 1140534 - IPC Proxy for offsetAtPoint, r=tbsaunde --- accessible/atk/nsMaiInterfaceText.cpp | 30 ++++++++++++++++++--------- accessible/ipc/DocAccessibleChild.cpp | 15 ++++++++++++++ accessible/ipc/DocAccessibleChild.h | 6 ++++++ accessible/ipc/PDocAccessible.ipdl | 3 +++ accessible/ipc/ProxyAccessible.cpp | 8 +++++++ accessible/ipc/ProxyAccessible.h | 2 ++ 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index 042c4c71761d..1c1bcaf5b16a 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -429,18 +429,28 @@ getOffsetAtPointCB(AtkText *aText, AtkCoordType aCoords) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return -1; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return -1; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return -1; + return static_cast( + text->OffsetAtPoint(aX, aY, + (aCoords == ATK_XY_SCREEN ? + nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : + nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE))); + } - return static_cast( - text->OffsetAtPoint(aX, aY, - (aCoords == ATK_XY_SCREEN ? - nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : - nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE))); + if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + return static_cast( + proxy->OffsetAtPoint(aX, aY, + (aCoords == ATK_XY_SCREEN ? + nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : + nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE))); + } + + return -1; } static gint diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index 0d54bf7c796e..ce2a730ac04e 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -392,5 +392,20 @@ DocAccessibleChild::RecvCharBounds(const uint64_t& aID, return true; } +bool +DocAccessibleChild::RecvOffsetAtPoint(const uint64_t& aID, + const int32_t& aX, + const int32_t& aY, + const uint32_t& aCoordType, + int32_t* aRetVal) +{ + *aRetVal = -1; + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + if (acc && acc->IsTextRole()) { + *aRetVal = acc->OffsetAtPoint(aX, aY, aCoordType); + } + return true; +} + } } diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 9b55c0034216..d9597d08c4d0 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -121,6 +121,12 @@ public: const int32_t& aOffset, const uint32_t& aCoordType, nsIntRect* aRetVal) MOZ_OVERRIDE; + + virtual bool RecvOffsetAtPoint(const uint64_t& aID, + const int32_t& aX, + const int32_t& aY, + const uint32_t& aCoordType, + int32_t* aRetVal) MOZ_OVERRIDE; private: bool PersistentPropertiesToArray(nsIPersistentProperties* aProps, nsTArray* aAttributes); diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index fe8e24012214..48a0a1fd7a49 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -91,6 +91,9 @@ child: returns(nsIntRect aRetVal); prio(high) sync CharBounds(uint64_t aID, int32_t aOffset, uint32_t aCoordType) returns(nsIntRect aRetVal); + + prio(high) sync OffsetAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aCoordType) + returns(int32_t aRetVal); }; } diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index 9666604b886a..23603cfe2ade 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -262,5 +262,13 @@ ProxyAccessible::CharBounds(int32_t aOffset, uint32_t aCoordType) return rect; } +int32_t +ProxyAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType) +{ + int32_t retVal = -1; + unused << mDoc->SendOffsetAtPoint(mID, aX, aY, aCoordType, &retVal); + return retVal; +} + } } diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index 000e34414c16..6986f6c62c66 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -138,6 +138,8 @@ public: nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType); + int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType); + /** * Allow the platform to store a pointers worth of data on us. */ From b0cd98035b23eaed89e923800aeab9e093b4c19e Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Sun, 8 Mar 2015 13:16:32 +0000 Subject: [PATCH 42/42] Bug 1106941 - Part 1. Firefox Hello doesn't work properly when no video camera is installed - fix rooms and outgoing conversations. r=mikedeboer --- .../loop/content/js/conversation.js | 3 + .../loop/content/js/conversation.jsx | 3 + .../loop/content/shared/js/activeRoomStore.js | 17 +++++ .../content/shared/js/conversationStore.js | 19 +++++- .../loop/content/shared/js/otSdkDriver.js | 52 +++++++++++++++ .../loop/content/shared/js/utils.js | 1 + .../loop/test/shared/activeRoomStore_test.js | 21 ++++++ .../test/shared/conversationStore_test.js | 24 ++++++- .../loop/test/shared/otSdkDriver_test.js | 66 ++++++++++++++++++- 9 files changed, 203 insertions(+), 3 deletions(-) diff --git a/browser/components/loop/content/js/conversation.js b/browser/components/loop/content/js/conversation.js index 3377b3eae395..c29e1f88acf2 100644 --- a/browser/components/loop/content/js/conversation.js +++ b/browser/components/loop/content/js/conversation.js @@ -118,6 +118,7 @@ loop.conversation = (function(mozL10n) { var dispatcher = new loop.Dispatcher(); var client = new loop.Client(); var sdkDriver = new loop.OTSdkDriver({ + isDesktop: true, dispatcher: dispatcher, sdk: OT }); @@ -137,10 +138,12 @@ loop.conversation = (function(mozL10n) { }); var conversationStore = new loop.store.ConversationStore(dispatcher, { client: client, + isDesktop: true, mozLoop: navigator.mozLoop, sdkDriver: sdkDriver }); var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, { + isDesktop: true, mozLoop: navigator.mozLoop, sdkDriver: sdkDriver }); diff --git a/browser/components/loop/content/js/conversation.jsx b/browser/components/loop/content/js/conversation.jsx index 19ba0eb7da81..27a8560560a8 100644 --- a/browser/components/loop/content/js/conversation.jsx +++ b/browser/components/loop/content/js/conversation.jsx @@ -118,6 +118,7 @@ loop.conversation = (function(mozL10n) { var dispatcher = new loop.Dispatcher(); var client = new loop.Client(); var sdkDriver = new loop.OTSdkDriver({ + isDesktop: true, dispatcher: dispatcher, sdk: OT }); @@ -137,10 +138,12 @@ loop.conversation = (function(mozL10n) { }); var conversationStore = new loop.store.ConversationStore(dispatcher, { client: client, + isDesktop: true, mozLoop: navigator.mozLoop, sdkDriver: sdkDriver }); var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, { + isDesktop: true, mozLoop: navigator.mozLoop, sdkDriver: sdkDriver }); diff --git a/browser/components/loop/content/shared/js/activeRoomStore.js b/browser/components/loop/content/shared/js/activeRoomStore.js index 0ddced145370..717861106059 100644 --- a/browser/components/loop/content/shared/js/activeRoomStore.js +++ b/browser/components/loop/content/shared/js/activeRoomStore.js @@ -55,6 +55,8 @@ loop.store.ActiveRoomStore = (function() { throw new Error("Missing option sdkDriver"); } this._sdkDriver = options.sdkDriver; + + this._isDesktop = options.isDesktop || false; }, /** @@ -356,6 +358,21 @@ loop.store.ActiveRoomStore = (function() { * @param {sharedActions.ConnectionFailure} actionData */ connectionFailure: function(actionData) { + /** + * XXX This is a workaround for desktop machines that do not have a + * camera installed. As we don't yet have device enumeration, when + * we do, this can be removed (bug 1138851), and the sdk should handle it. + */ + if (this._isDesktop && + actionData.reason === FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA && + this.getStoreState().videoMuted === false) { + // We failed to publish with media, so due to the bug, we try again without + // video. + this.setStoreState({videoMuted: true}); + this._sdkDriver.retryPublishWithoutVideo(); + return; + } + // Treat all reasons as something failed. In theory, clientDisconnected // could be a success case, but there's no way we should be intentionally // sending that and still have the window open. diff --git a/browser/components/loop/content/shared/js/conversationStore.js b/browser/components/loop/content/shared/js/conversationStore.js index e66f9513ad19..e41c4b85b29e 100644 --- a/browser/components/loop/content/shared/js/conversationStore.js +++ b/browser/components/loop/content/shared/js/conversationStore.js @@ -10,8 +10,9 @@ loop.store = loop.store || {}; (function() { var sharedActions = loop.shared.actions; var CALL_TYPES = loop.shared.utils.CALL_TYPES; - var REST_ERRNOS = loop.shared.utils.REST_ERRNOS; + var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS; + /** * Websocket states taken from: * https://docs.services.mozilla.com/loop/apis.html#call-progress-state-change-progress @@ -132,6 +133,7 @@ loop.store = loop.store || {}; this.client = options.client; this.sdkDriver = options.sdkDriver; this.mozLoop = options.mozLoop; + this._isDesktop = options.isDesktop || false; }, /** @@ -141,6 +143,21 @@ loop.store = loop.store || {}; * @param {sharedActions.ConnectionFailure} actionData The action data. */ connectionFailure: function(actionData) { + /** + * XXX This is a workaround for desktop machines that do not have a + * camera installed. As we don't yet have device enumeration, when + * we do, this can be removed (bug 1138851), and the sdk should handle it. + */ + if (this._isDesktop && + actionData.reason === FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA && + this.getStoreState().videoMuted === false) { + // We failed to publish with media, so due to the bug, we try again without + // video. + this.setStoreState({videoMuted: true}); + this.sdkDriver.retryPublishWithoutVideo(); + return; + } + this._endSession(); this.setStoreState({ callState: CALL_STATES.TERMINATED, diff --git a/browser/components/loop/content/shared/js/otSdkDriver.js b/browser/components/loop/content/shared/js/otSdkDriver.js index e3328b710234..24060adb584c 100644 --- a/browser/components/loop/content/shared/js/otSdkDriver.js +++ b/browser/components/loop/content/shared/js/otSdkDriver.js @@ -33,6 +33,21 @@ loop.OTSdkDriver = (function() { "setupStreamElements", "setMute" ]); + + /** + * XXX This is a workaround for desktop machines that do not have a + * camera installed. As we don't yet have device enumeration, when + * we do, this can be removed (bug 1138851), and the sdk should handle it. + */ + if ("isDesktop" in options && options.isDesktop && + !window.MediaStreamTrack.getSources) { + // If there's no getSources function, the sdk defines its own and caches + // the result. So here we define the "normal" one which doesn't get cached, so + // we can change it later. + window.MediaStreamTrack.getSources = function(callback) { + callback([{kind: "audio"}, {kind: "video"}]); + }; + } }; OTSdkDriver.prototype = { @@ -57,9 +72,19 @@ loop.OTSdkDriver = (function() { this.getRemoteElement = actionData.getRemoteElementFunc; this.publisherConfig = actionData.publisherConfig; + this.sdk.on("exception", this._onOTException.bind(this)); + // At this state we init the publisher, even though we might be waiting for // the initial connect of the session. This saves time when setting up // the media. + this._publishLocalStreams(); + }, + + /** + * Internal function to publish a local stream. + * XXX This can be simplified when bug 1138851 is actioned. + */ + _publishLocalStreams: function() { this.publisher = this.sdk.initPublisher(this.getLocalElement(), this._getCopyPublisherConfig()); this.publisher.on("streamCreated", this._onLocalStreamCreated.bind(this)); @@ -69,6 +94,17 @@ loop.OTSdkDriver = (function() { this._onAccessDialogOpened.bind(this)); }, + /** + * Forces the sdk into not using video, and starts publishing again. + * XXX This is part of the work around that will be removed by bug 1138851. + */ + retryPublishWithoutVideo: function() { + window.MediaStreamTrack.getSources = function(callback) { + callback([{kind: "audio"}]); + }; + this._publishLocalStreams(); + }, + /** * Handles the setMute action. Informs the published stream to mute * or unmute audio as appropriate. @@ -436,6 +472,22 @@ loop.OTSdkDriver = (function() { })); }, + _onOTException: function(event) { + if (event.code === OT.ExceptionCodes.UNABLE_TO_PUBLISH && + event.message === "GetUserMedia") { + // We free up the publisher here in case the store wants to try + // grabbing the media again. + if (this.publisher) { + this.publisher.off("accessAllowed accessDenied accessDialogOpened streamCreated"); + this.publisher.destroy(); + delete this.publisher; + } + this.dispatcher.dispatch(new sharedActions.ConnectionFailure({ + reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA + })); + } + }, + /** * Handles publishing of property changes to a stream. */ diff --git a/browser/components/loop/content/shared/js/utils.js b/browser/components/loop/content/shared/js/utils.js index 454628906404..7a49e2ea7cbe 100644 --- a/browser/components/loop/content/shared/js/utils.js +++ b/browser/components/loop/content/shared/js/utils.js @@ -36,6 +36,7 @@ loop.shared.utils = (function(mozL10n) { var FAILURE_DETAILS = { MEDIA_DENIED: "reason-media-denied", + UNABLE_TO_PUBLISH_MEDIA: "unable-to-publish-media", COULD_NOT_CONNECT: "reason-could-not-connect", NETWORK_DISCONNECTED: "reason-network-disconnected", EXPIRED_OR_INVALID: "reason-expired-or-invalid", diff --git a/browser/components/loop/test/shared/activeRoomStore_test.js b/browser/components/loop/test/shared/activeRoomStore_test.js index fa36c1e311ac..260d9b428b2c 100644 --- a/browser/components/loop/test/shared/activeRoomStore_test.js +++ b/browser/components/loop/test/shared/activeRoomStore_test.js @@ -41,6 +41,7 @@ describe("loop.store.ActiveRoomStore", function () { connectSession: sinon.stub(), disconnectSession: sinon.stub(), forceDisconnectAll: sinon.stub().callsArg(0), + retryPublishWithoutVideo: sinon.stub(), startScreenShare: sinon.stub(), switchAcquiredWindow: sinon.stub(), endScreenShare: sinon.stub().returns(true) @@ -609,6 +610,26 @@ describe("loop.store.ActiveRoomStore", function () { }); }); + it("should retry publishing if on desktop, and in the videoMuted state", function() { + store._isDesktop = true; + + store.connectionFailure(new sharedActions.ConnectionFailure({ + reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA + })); + + sinon.assert.calledOnce(fakeSdkDriver.retryPublishWithoutVideo); + }); + + it("should set videoMuted to try when retrying publishing", function() { + store._isDesktop = true; + + store.connectionFailure(new sharedActions.ConnectionFailure({ + reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA + })); + + expect(store.getStoreState().videoMuted).eql(true); + }); + it("should store the failure reason", function() { store.connectionFailure(connectionFailureAction); diff --git a/browser/components/loop/test/shared/conversationStore_test.js b/browser/components/loop/test/shared/conversationStore_test.js index 3f41cce07034..31b935af007e 100644 --- a/browser/components/loop/test/shared/conversationStore_test.js +++ b/browser/components/loop/test/shared/conversationStore_test.js @@ -9,6 +9,7 @@ describe("loop.store.ConversationStore", function () { var CALL_STATES = loop.store.CALL_STATES; var WS_STATES = loop.store.WS_STATES; var WEBSOCKET_REASONS = loop.shared.utils.WEBSOCKET_REASONS; + var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS; var sharedActions = loop.shared.actions; var sharedUtils = loop.shared.utils; var sandbox, dispatcher, client, store, fakeSessionData, sdkDriver; @@ -56,7 +57,8 @@ describe("loop.store.ConversationStore", function () { }; sdkDriver = { connectSession: sinon.stub(), - disconnectSession: sinon.stub() + disconnectSession: sinon.stub(), + retryPublishWithoutVideo: sinon.stub() }; wsCancelSpy = sinon.spy(); @@ -135,6 +137,26 @@ describe("loop.store.ConversationStore", function () { store.setStoreState({windowId: "42"}); }); + it("should retry publishing if on desktop, and in the videoMuted state", function() { + store._isDesktop = true; + + store.connectionFailure(new sharedActions.ConnectionFailure({ + reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA + })); + + sinon.assert.calledOnce(sdkDriver.retryPublishWithoutVideo); + }); + + it("should set videoMuted to try when retrying publishing", function() { + store._isDesktop = true; + + store.connectionFailure(new sharedActions.ConnectionFailure({ + reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA + })); + + expect(store.getStoreState().videoMuted).eql(true); + }); + it("should disconnect the session", function() { store.connectionFailure( new sharedActions.ConnectionFailure({reason: "fake"})); diff --git a/browser/components/loop/test/shared/otSdkDriver_test.js b/browser/components/loop/test/shared/otSdkDriver_test.js index 7c8e48f6e846..4ef943a0a61d 100644 --- a/browser/components/loop/test/shared/otSdkDriver_test.js +++ b/browser/components/loop/test/shared/otSdkDriver_test.js @@ -10,6 +10,7 @@ describe("loop.OTSdkDriver", function () { var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS; var STREAM_PROPERTIES = loop.shared.utils.STREAM_PROPERTIES; var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES; + var sandbox; var dispatcher, driver, publisher, sdk, session, sessionData; var fakeLocalElement, fakeRemoteElement, fakeScreenElement; @@ -52,9 +53,15 @@ describe("loop.OTSdkDriver", function () { } }, Backbone.Events); - sdk = { + sdk = _.extend({ initPublisher: sinon.stub().returns(publisher), initSession: sinon.stub().returns(session) + }, Backbone.Events); + + window.OT = { + ExceptionCodes: { + UNABLE_TO_PUBLISH: 1500 + } }; driver = new loop.OTSdkDriver({ @@ -94,6 +101,37 @@ describe("loop.OTSdkDriver", function () { }); }); + describe("#retryPublishWithoutVideo", function() { + beforeEach(function() { + sdk.initPublisher.returns(publisher); + + driver.setupStreamElements(new sharedActions.SetupStreamElements({ + getLocalElementFunc: function() {return fakeLocalElement;}, + getRemoteElementFunc: function() {return fakeRemoteElement;}, + publisherConfig: publisherConfig + })); + }); + + it("should make MediaStreamTrack.getSources return without a video source", function(done) { + driver.retryPublishWithoutVideo(); + + window.MediaStreamTrack.getSources(function(sources) { + expect(sources.some(function(src) { + return src.kind === "video"; + })).eql(false); + + done(); + }); + }); + + it("should call initPublisher", function() { + driver.retryPublishWithoutVideo(); + + sinon.assert.calledTwice(sdk.initPublisher); + sinon.assert.calledWith(sdk.initPublisher, fakeLocalElement, publisherConfig); + }); + }); + describe("#setMute", function() { beforeEach(function() { sdk.initPublisher.returns(publisher); @@ -627,6 +665,32 @@ describe("loop.OTSdkDriver", function () { sinon.assert.calledOnce(fakeEvent.preventDefault); }); }); + + describe("exception", function() { + describe("Unable to publish (GetUserMedia)", function() { + it("should destroy the publisher", function() { + sdk.trigger("exception", { + code: OT.ExceptionCodes.UNABLE_TO_PUBLISH, + message: "GetUserMedia" + }); + + sinon.assert.calledOnce(publisher.destroy); + }); + + it("should dispatch a ConnectionFailure action", function() { + sdk.trigger("exception", { + code: OT.ExceptionCodes.UNABLE_TO_PUBLISH, + message: "GetUserMedia" + }); + + sinon.assert.calledOnce(dispatcher.dispatch); + sinon.assert.calledWithExactly(dispatcher.dispatch, + new sharedActions.ConnectionFailure({ + reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA + })); + }); + }); + }); }); describe("Events (screenshare)", function() {