diff --git a/.gn b/.gn index 1b870bc..c85878a3 100644 --- a/.gn +++ b/.gn
@@ -102,13 +102,10 @@ "//extensions/browser/api/hid:*", # 12 errors "//extensions/browser/api/idle:*", # 4 errors "//extensions/browser/api/management:*", # 19 errors - "//extensions/browser/api/messaging:*", # 1 error "//extensions/browser/api/metrics_private:*", # 3 errors "//extensions/browser/api/mime_handler_private:*", # 1 error "//extensions/browser/api/networking_private:*", # 14 errors "//extensions/browser/api/power:*", # 3 errors - "//extensions/browser/api/printer_provider:*", # 7 errors - "//extensions/browser/api/printer_provider_internal:*", # 3 errors "//extensions/browser/api/runtime:*", # 6 errors "//extensions/browser/api/serial:*", # 10 errors "//extensions/browser/api/socket:*", # 11 errors
diff --git a/DEPS b/DEPS index d225f6d..8a47fca 100644 --- a/DEPS +++ b/DEPS
@@ -199,11 +199,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'e2c0504c27a280a63db4453abf457b3b00739f03', + 'skia_revision': '9e189aab1ec7cea9ba876100025c106308fc682a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '53720ace941d84ac17ae67a94166a363dcf0cacf', + 'v8_revision': '0a1abebf1e7887b0277c2cb1261734b814e47bd6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -270,7 +270,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '73a0597ed6870d9061816c371710ff190520b1b4', + 'catapult_revision': '5c5a2976d525ca07cb873a74a5c26c98707fec6f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -278,7 +278,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'a3ee39b0f50e14f6d3a4bb0103d26436c6e9d37c', + 'devtools_frontend_revision': '15761863557d7f800af607f52a29152d279ce795', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -318,11 +318,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '040f140e5f3b4c6fa82835185b8d9e42a628bfd6', + 'dawn_revision': 'd5a0728b67c8328edaed3d9cfee7ee44fcb893e8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '869e4344aea2b3cb16b81b73b37ecc5e201adffa', + 'quiche_revision': '9e4ce274decced673f3a9a7581c6ce94ee474490', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -342,7 +342,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libavif # and whatever else without interference from each other. - 'libavif_revision': '93d5bf907aec1dec842b4b1dc81c44972129c411', + 'libavif_revision': '723881f4bbb6972d057f9fa8ffa33d4da825fed3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. @@ -357,7 +357,7 @@ 'ukey2_revision': '0275885d8e6038c39b8a8ca55e75d1d4d1727f47', # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'tint_revision': 'c694d43c75f497195374336a5ed3391939137b94', + 'tint_revision': 'b17aea159c328764238f0550d327bb531cf9bcf8', # TODO(crbug.com/941824): The values below need to be kept in sync # between //DEPS and //buildtools/DEPS, so if you're updating one, @@ -678,7 +678,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '3GRMk878gb4_w69FpkytItdValBJSnCiRix7DdYgaCsC', + 'version': 'QgJ9xxAjtz6Xk7mWP7iyaViWFNUzkkpOGmFmaX9XquMC', }, ], 'condition': 'checkout_android', @@ -905,7 +905,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6dc9cc301f553f1a50608b579083997e63b16e14', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '680a6c37a0fbb29292576f142431f162cb3d814e', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1045,7 +1045,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'df304fa5705b9a2b85fc5937c493e49412364046', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '70dd9a65bf5b764ced1a0f1a60e82d233d45f63e', 'src/third_party/icu4j': { 'packages': [ @@ -1167,7 +1167,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '576e0801f9281fd54e2c69ad5be5fef7af656011', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '61edec1efbea1c02d71857e2aff9426d9cd2df4e', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + '51ca718c3adf0ddedacd7df25fe45f67dc5a9ce1', @@ -1506,7 +1506,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '66460536ee975a3e98931b7b40a661a63fd9cd57', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '14cad9fa35dd9260e83c5af261836b58a7137edd', + Var('webrtc_git') + '/src.git' + '@' + '1d71fd9c61db8f1dcf30b5d0625e514b91200926', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1544,7 +1544,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': 'bndDOcFTE8fhEv3eYMFfXRk-9u1_2cE7UtJANTXxnKsC', + 'version': '6LF5F6aXrWP5GXP59OtHK-18DPO1aPrWT-5XYQEaYBMC', }, ], 'dep_type': 'cipd', @@ -1554,7 +1554,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'VKdCj6PUrZFaxbpwkU_ZBfi__KMY28BcRPUy2Kig7EUC', + 'version': 'pUKrWuFOfyPuNAzRy9gRHv-8dvvUOzMEHO9KvF9dRMIC', }, ], 'dep_type': 'cipd', @@ -1564,7 +1564,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': 'wURoizH_SOJXQLqhoZ0Zz9ZsYd19jwbG4jNVfTSvizwC', + 'version': 'wKJl4xmBqSYjy0jV-1mXCtsx-D8if80AIBo9uiP-nrEC', }, ], 'dep_type': 'cipd', @@ -1578,7 +1578,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@198fe4cf98e6681a0347dc8809c456501f8890f5', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@aca4961a9ccd94323ba4f6aad58d43f537c83046', 'condition': 'checkout_src_internal', },
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 887e880..b9dc6b8 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -159,10 +159,6 @@ const base::Feature kBluetoothPhoneFilter{"BluetoothPhoneFilter", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enable or disables running the Camera App as a System Web App. -const base::Feature kCameraSystemWebApp{"CameraSystemWebApp", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables or disables the preference of using constant frame rate for camera // when streaming. const base::Feature kPreferConstantFrameRate{"PreferConstantFrameRate",
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 05ca402..71c35420 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -86,8 +86,6 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kBluetoothPhoneFilter; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) -extern const base::Feature kCameraSystemWebApp; -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kPreferConstantFrameRate; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCdmFactoryDaemon;
diff --git a/base/allocator/partition_allocator/pcscan.cc b/base/allocator/partition_allocator/pcscan.cc index 192e92e4..f600fbf 100644 --- a/base/allocator/partition_allocator/pcscan.cc +++ b/base/allocator/partition_allocator/pcscan.cc
@@ -459,10 +459,14 @@ PA_DCHECK( !((reinterpret_cast<char*>(end) - reinterpret_cast<char*>(begin)) % kAlignmentRequirement)); - - const __m128i vbase = _mm_set1_epi64x(normal_bucket_pool_base_); - const __m128d cage_mask = - _mm_set1_epi64x(PartitionAddressSpace::NormalBucketPoolBaseMask()); + // For SSE3, since some integer instructions are not yet available (e.g. + // _mm_cmpeq_epi64), use packed doubles (not integers). Sticking to doubles + // helps to avoid latency caused by "domain crossing penalties" (see bypass + // delays in https://agner.org/optimize/microarchitecture.pdf). + const __m128d vbase = + _mm_castsi128_pd(_mm_set1_epi64x(normal_bucket_pool_base_)); + const __m128d cage_mask = _mm_castsi128_pd( + _mm_set1_epi64x(PartitionAddressSpace::NormalBucketPoolBaseMask())); size_t quarantine_size = 0; for (uintptr_t* payload = begin; payload < end; payload += kWordsInVector) { @@ -478,14 +482,15 @@ if (mask & 0b01) { quarantine_size += pcscan_task_.TryMarkObjectInNormalBucketPool<BitmapLookupPolicy>( - _mm_cvtsi128_si64(maybe_ptrs)); + _mm_cvtsi128_si64(_mm_castpd_si128(maybe_ptrs))); } if (mask & 0b10) { // Extraction intrinsics for qwords are only supported in SSE4.1, so // instead we reshuffle dwords with pshufd. The mask is used to move the // 4th and 3rd dwords into the second and first position. static constexpr int kSecondWordMask = (3 << 2) | (2 << 0); - const __m128i shuffled = _mm_shuffle_epi32(maybe_ptrs, kSecondWordMask); + const __m128i shuffled = + _mm_shuffle_epi32(_mm_castpd_si128(maybe_ptrs), kSecondWordMask); quarantine_size += pcscan_task_.TryMarkObjectInNormalBucketPool<BitmapLookupPolicy>( _mm_cvtsi128_si64(shuffled)); @@ -499,7 +504,10 @@ static constexpr size_t kAlignmentRequirement = 32; static constexpr size_t kWordsInVector = 4; PA_DCHECK(!(reinterpret_cast<uintptr_t>(begin) % kAlignmentRequirement)); - + // For AVX2, stick to integer instructions. This brings slightly better + // throughput. For example, according to the Intel docs, on Broadwell and + // Haswell the CPI of vmovdqa (_mm256_load_si256) is twice smaller (0.25) + // than that of vmovapd (_mm256_load_pd). const __m256i vbase = _mm256_set1_epi64x(normal_bucket_pool_base_); const __m256i cage_mask = _mm256_set1_epi64x(PartitionAddressSpace::NormalBucketPoolBaseMask()); @@ -507,11 +515,11 @@ size_t quarantine_size = 0; uintptr_t* payload = begin; for (; payload < (end - kWordsInVector); payload += kWordsInVector) { - const __m256d maybe_ptrs = - _mm256_load_pd(reinterpret_cast<double*>(payload)); - const __m256d vand = _mm256_and_pd(maybe_ptrs, cage_mask); + const __m256i maybe_ptrs = + _mm256_load_si256(reinterpret_cast<__m256i*>(payload)); + const __m256i vand = _mm256_and_si256(maybe_ptrs, cage_mask); const __m256i vcmp = _mm256_cmpeq_epi64(vand, vbase); - const int mask = _mm256_movemask_pd(vcmp); + const int mask = _mm256_movemask_pd(_mm256_castsi256_pd(vcmp)); if (LIKELY(!mask)) continue; // It's important to extract pointers from the already loaded vector to
diff --git a/base/android/library_loader/library_prefetcher.cc b/base/android/library_loader/library_prefetcher.cc index a56e613a..73ef3f51 100644 --- a/base/android/library_loader/library_prefetcher.cc +++ b/base/android/library_loader/library_prefetcher.cc
@@ -68,7 +68,7 @@ // Set the end to the page on which the beginning of the last symbol is. The // actual symbol may spill into the next page by a few bytes, but this is // outside of the executable code range anyway. - size_t end_page = base::bits::Align(kEndOfText, kPageSize); + size_t end_page = base::bits::AlignUp(kEndOfText, kPageSize); return {start_page, end_page}; } @@ -78,7 +78,7 @@ size_t start_page = kStartOfOrderedText - kStartOfOrderedText % kPageSize; // kEndOfUnorderedText is not considered ordered, but the byte immediately // before is considered ordered and so can not be contained in the start page. - size_t end_page = base::bits::Align(kEndOfOrderedText, kPageSize); + size_t end_page = base::bits::AlignUp(kEndOfOrderedText, kPageSize); return {start_page, end_page}; }
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc index 32075b8..a6d967e4 100644 --- a/base/debug/activity_tracker.cc +++ b/base/debug/activity_tracker.cc
@@ -468,9 +468,9 @@ // following field will be aligned properly. size_t name_size = name.length(); size_t name_extent = - bits::Align(sizeof(FieldHeader) + name_size, kMemoryAlignment) - + bits::AlignUp(sizeof(FieldHeader) + name_size, kMemoryAlignment) - sizeof(FieldHeader); - size_t value_extent = bits::Align(size, kMemoryAlignment); + size_t value_extent = bits::AlignUp(size, kMemoryAlignment); // The "base size" is the size of the header and (padded) string key. Stop // now if there's not room enough for even this. @@ -566,8 +566,8 @@ if (header->record_size > available_) return; - size_t value_offset = - bits::Align(sizeof(FieldHeader) + header->name_size, kMemoryAlignment); + size_t value_offset = bits::AlignUp(sizeof(FieldHeader) + header->name_size, + kMemoryAlignment); if (header->record_size == value_offset && header->value_size.load(std::memory_order_relaxed) == 1) { value_offset -= 1;
diff --git a/base/debug/elf_reader.cc b/base/debug/elf_reader.cc index 0389c44d3..a3b4684 100644 --- a/base/debug/elf_reader.cc +++ b/base/debug/elf_reader.cc
@@ -85,8 +85,8 @@ } } - size_t section_size = bits::Align(current_note->n_namesz, 4) + - bits::Align(current_note->n_descsz, 4) + + size_t section_size = bits::AlignUp(current_note->n_namesz, 4) + + bits::AlignUp(current_note->n_descsz, 4) + sizeof(Nhdr); if (section_size > static_cast<size_t>(section_end - current_section)) return 0; @@ -104,7 +104,7 @@ // Write out the build ID as a null-terminated hex string. const uint8_t* build_id_raw = reinterpret_cast<const uint8_t*>(current_note) + sizeof(Nhdr) + - bits::Align(current_note->n_namesz, 4); + bits::AlignUp(current_note->n_namesz, 4); size_t i = 0; for (i = 0; i < current_note->n_descsz; ++i) { strings::SafeSNPrintf(&build_id[i * 2], 3, (uppercase ? "%02X" : "%02x"),
diff --git a/base/debug/test_elf_image_builder.cc b/base/debug/test_elf_image_builder.cc index ee4164d..60a1a3e 100644 --- a/base/debug/test_elf_image_builder.cc +++ b/base/debug/test_elf_image_builder.cc
@@ -65,8 +65,8 @@ span<const uint8_t> desc) { const size_t name_with_null_size = name.size() + 1; std::vector<uint8_t> buffer(sizeof(Nhdr) + - bits::Align(name_with_null_size, 4) + - bits::Align(desc.size(), 4), + bits::AlignUp(name_with_null_size, 4) + + bits::AlignUp(desc.size(), 4), '\0'); uint8_t* loc = &buffer.front(); Nhdr* nhdr = reinterpret_cast<Nhdr*>(loc); @@ -77,10 +77,10 @@ memcpy(loc, name.data(), name.size()); *(loc + name.size()) = '\0'; - loc += bits::Align(name_with_null_size, 4); + loc += bits::AlignUp(name_with_null_size, 4); memcpy(loc, &desc.front(), desc.size()); - loc += bits::Align(desc.size(), 4); + loc += bits::AlignUp(desc.size(), 4); DCHECK_EQ(&buffer.front() + buffer.size(), loc); @@ -135,13 +135,13 @@ size_t offset = sizeof(Ehdr); // Add space for the program header table. - offset = bits::Align(offset, kPhdrAlign); + offset = bits::AlignUp(offset, kPhdrAlign); offset += sizeof(Phdr) * measures.phdrs_required; // Add space for the notes. measures.note_start = offset; if (!note_contents_.empty()) - offset = bits::Align(offset, kNoteAlign); + offset = bits::AlignUp(offset, kNoteAlign); for (const std::vector<uint8_t>& contents : note_contents_) offset += contents.size(); measures.note_size = offset - measures.note_start; @@ -155,7 +155,7 @@ size = offset + it->size; measures.load_segment_start.push_back(0); } else { - offset = bits::Align(offset, kLoadAlign); + offset = bits::AlignUp(offset, kLoadAlign); size = it->size; measures.load_segment_start.push_back(offset); } @@ -163,7 +163,7 @@ } // Add space for the dynamic segment. - measures.dynamic_start = bits::Align(offset, kDynamicAlign); + measures.dynamic_start = bits::AlignUp(offset, kDynamicAlign); offset += sizeof(Dyn) * (soname_ ? 2 : 1); measures.strtab_start = offset; @@ -188,14 +188,14 @@ std::vector<uint8_t> buffer(load_bias + (kPageSize - 1) + measures.total_size, '\0'); uint8_t* const elf_start = - bits::Align(&buffer.front() + load_bias, kPageSize); + bits::AlignUp(&buffer.front() + load_bias, kPageSize); uint8_t* loc = elf_start; // Add the ELF header. loc = AppendHdr(CreateEhdr(measures.phdrs_required), loc); // Add the program header table. - loc = bits::Align(loc, kPhdrAlign); + loc = bits::AlignUp(loc, kPhdrAlign); loc = AppendHdr( CreatePhdr(PT_PHDR, PF_R, kPhdrAlign, loc - elf_start, GetVirtualAddressForOffset(loc - elf_start, elf_start), @@ -232,7 +232,7 @@ } // Add the notes. - loc = bits::Align(loc, kNoteAlign); + loc = bits::AlignUp(loc, kNoteAlign); for (const std::vector<uint8_t>& contents : note_contents_) { memcpy(loc, &contents.front(), contents.size()); loc += contents.size(); @@ -241,12 +241,12 @@ // Add the load segments. for (auto it = load_segments_.begin(); it != load_segments_.end(); ++it) { if (it != load_segments_.begin()) - loc = bits::Align(loc, kLoadAlign); + loc = bits::AlignUp(loc, kLoadAlign); memset(loc, 0, it->size); loc += it->size; } - loc = bits::Align(loc, kDynamicAlign); + loc = bits::AlignUp(loc, kDynamicAlign); // Add the soname state. if (soname_) {
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index c5e9b05..d8f2b98 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -952,7 +952,7 @@ // Write starting at the next block boundary after the old file length. const int64_t extension_start = - base::bits::Align(original_file_len, block_size); + base::bits::AlignUp(original_file_len, block_size); for (int64_t i = extension_start; i < new_file_len; i += block_size) { char existing_byte; if (HANDLE_EINTR(pread(file->GetPlatformFile(), &existing_byte, 1, i)) !=
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc index 453f29ea..49c00097 100644 --- a/base/memory/discardable_shared_memory.cc +++ b/base/memory/discardable_shared_memory.cc
@@ -119,7 +119,7 @@ // Round up |size| to a multiple of page size. size_t AlignToPageSize(size_t size) { - return bits::Align(size, base::GetPageSize()); + return bits::AlignUp(size, base::GetPageSize()); } #if defined(OS_ANDROID)
diff --git a/base/memory/platform_shared_memory_region_android.cc b/base/memory/platform_shared_memory_region_android.cc index b862a11..f9b08b3 100644 --- a/base/memory/platform_shared_memory_region_android.cc +++ b/base/memory/platform_shared_memory_region_android.cc
@@ -146,7 +146,7 @@ // Align size as required by ashmem_create_region() API documentation. This // operation may overflow so check that the result doesn't decrease. - size_t rounded_size = bits::Align(size, GetPageSize()); + size_t rounded_size = bits::AlignUp(size, GetPageSize()); if (rounded_size < size || rounded_size > static_cast<size_t>(std::numeric_limits<int>::max())) { return {};
diff --git a/base/memory/platform_shared_memory_region_fuchsia.cc b/base/memory/platform_shared_memory_region_fuchsia.cc index 602e01d0..1f91ee8 100644 --- a/base/memory/platform_shared_memory_region_fuchsia.cc +++ b/base/memory/platform_shared_memory_region_fuchsia.cc
@@ -121,7 +121,7 @@ return {}; // Aligning may overflow so check that the result doesn't decrease. - size_t rounded_size = bits::Align(size, GetPageSize()); + size_t rounded_size = bits::AlignUp(size, GetPageSize()); if (rounded_size < size || rounded_size > static_cast<size_t>(std::numeric_limits<int>::max())) { return {};
diff --git a/base/memory/platform_shared_memory_region_win.cc b/base/memory/platform_shared_memory_region_win.cc index c58731a..1af811da 100644 --- a/base/memory/platform_shared_memory_region_win.cc +++ b/base/memory/platform_shared_memory_region_win.cc
@@ -227,7 +227,7 @@ } // Aligning may overflow so check that the result doesn't decrease. - size_t rounded_size = bits::Align(size, kSectionSize); + size_t rounded_size = bits::AlignUp(size, kSectionSize); if (rounded_size < size || rounded_size > static_cast<size_t>(std::numeric_limits<int>::max())) { return {};
diff --git a/base/memory/shared_memory_security_policy.cc b/base/memory/shared_memory_security_policy.cc index 7075b15..9d711ff 100644 --- a/base/memory/shared_memory_security_policy.cc +++ b/base/memory/shared_memory_security_policy.cc
@@ -40,7 +40,7 @@ #else const size_t page_size = GetPageSize(); #endif // defined(OS_WIN) - size_t rounded_size = bits::Align(size, page_size); + size_t rounded_size = bits::AlignUp(size, page_size); // Fail on overflow. if (rounded_size < size)
diff --git a/base/pickle.cc b/base/pickle.cc index 41318184..764fe67 100644 --- a/base/pickle.cc +++ b/base/pickle.cc
@@ -41,7 +41,7 @@ } inline void PickleIterator::Advance(size_t size) { - size_t aligned_size = bits::Align(size, sizeof(uint32_t)); + size_t aligned_size = bits::AlignUp(size, sizeof(uint32_t)); if (end_index_ - read_index_ < aligned_size) { read_index_ = end_index_; } else { @@ -237,7 +237,7 @@ Pickle::Pickle(int header_size) : header_(nullptr), - header_size_(bits::Align(header_size, sizeof(uint32_t))), + header_size_(bits::AlignUp(header_size, sizeof(uint32_t))), capacity_after_header_(0), write_offset_(0) { DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); @@ -257,7 +257,7 @@ if (header_size_ > static_cast<unsigned int>(data_len)) header_size_ = 0; - if (header_size_ != bits::Align(header_size_, sizeof(uint32_t))) + if (header_size_ != bits::AlignUp(header_size_, sizeof(uint32_t))) header_size_ = 0; // If there is anything wrong with the data, we're not going to use it. @@ -320,7 +320,7 @@ } void Pickle::Reserve(size_t length) { - size_t data_len = bits::Align(length, sizeof(uint32_t)); + size_t data_len = bits::AlignUp(length, sizeof(uint32_t)); DCHECK_GE(data_len, length); #ifdef ARCH_CPU_64_BITS DCHECK_LE(data_len, std::numeric_limits<uint32_t>::max()); @@ -346,7 +346,7 @@ void Pickle::Resize(size_t new_capacity) { CHECK_NE(capacity_after_header_, kCapacityReadOnly); - capacity_after_header_ = bits::Align(new_capacity, kPayloadUnit); + capacity_after_header_ = bits::AlignUp(new_capacity, kPayloadUnit); void* p = realloc(header_, GetTotalAllocatedSize()); CHECK(p); header_ = reinterpret_cast<Header*>(p); @@ -384,7 +384,7 @@ const char* start, const char* end, size_t* pickle_size) { - DCHECK_EQ(header_size, bits::Align(header_size, sizeof(uint32_t))); + DCHECK_EQ(header_size, bits::AlignUp(header_size, sizeof(uint32_t))); DCHECK_GE(header_size, sizeof(Header)); DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); @@ -413,7 +413,7 @@ inline void* Pickle::ClaimUninitializedBytesInternal(size_t length) { DCHECK_NE(kCapacityReadOnly, capacity_after_header_) << "oops: pickle is readonly"; - size_t data_len = bits::Align(length, sizeof(uint32_t)); + size_t data_len = bits::AlignUp(length, sizeof(uint32_t)); DCHECK_GE(data_len, length); #ifdef ARCH_CPU_64_BITS DCHECK_LE(data_len, std::numeric_limits<uint32_t>::max()); @@ -423,8 +423,10 @@ if (new_size > capacity_after_header_) { size_t new_capacity = capacity_after_header_ * 2; const size_t kPickleHeapAlign = 4096; - if (new_capacity > kPickleHeapAlign) - new_capacity = bits::Align(new_capacity, kPickleHeapAlign) - kPayloadUnit; + if (new_capacity > kPickleHeapAlign) { + new_capacity = + bits::AlignUp(new_capacity, kPickleHeapAlign) - kPayloadUnit; + } Resize(std::max(new_capacity, new_size)); }
diff --git a/base/profiler/stack_copier.cc b/base/profiler/stack_copier.cc index a79254e..1abfb09 100644 --- a/base/profiler/stack_copier.cc +++ b/base/profiler/stack_copier.cc
@@ -43,7 +43,7 @@ // RewritePointerIfInOriginalStack(). Bytes before this cannot be a pointer // because they occupy less space than a pointer would. const uint8_t* first_aligned_address = - bits::Align(byte_src, sizeof(uintptr_t)); + bits::AlignUp(byte_src, sizeof(uintptr_t)); // The stack copy bottom, which is offset from |stack_buffer_bottom| by the // same alignment as in the original stack. This guarantees identical
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 9becd7c..8c2d14b 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20210203.2.1 +0.20210204.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 9becd7c..8c2d14b 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20210203.2.1 +0.20210204.0.1
diff --git a/build/linux/strip_binary.gni b/build/linux/strip_binary.gni new file mode 100644 index 0000000..ddc42cc4 --- /dev/null +++ b/build/linux/strip_binary.gni
@@ -0,0 +1,44 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/toolchain/toolchain.gni") + +# Extracts symbols from a binary into a symbol file. +# +# Args: +# binary_input: Path to the binary containing symbols to extract, e.g.: +# "$root_out_dir/chrome" +# symbol_output: Desired output file for symbols, e.g.: +# "$root_out_dir/chrome.debug" +# stripped_binary_output: Desired output file for stripped file, e.g.: +# "$root_out_dir/chrome.stripped" +template("strip_binary") { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + action("${target_name}") { + eu_strip_binary = "//buildtools/third_party/eu-strip/bin/eu-strip" + script = "//build/linux/strip_binary.py" + inputs = [ + invoker.binary_input, + eu_strip_binary, + ] + outputs = [ + invoker.symbol_output, + invoker.stripped_binary_output, + ] + args = [ + "--eu-strip-binary-path", + rebase_path(eu_strip_binary, root_build_dir), + "--symbol-output", + rebase_path(invoker.symbol_output, root_build_dir), + "--stripped-binary-output", + rebase_path(invoker.stripped_binary_output, root_build_dir), + "--binary-input", + rebase_path(invoker.binary_input, root_build_dir), + ] + } +}
diff --git a/build/linux/strip_binary.py b/build/linux/strip_binary.py new file mode 100755 index 0000000..00b4089 --- /dev/null +++ b/build/linux/strip_binary.py
@@ -0,0 +1,32 @@ +#!/usr/bin/env python +# +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import subprocess +import sys + + +def main(): + argparser = argparse.ArgumentParser(description='eu-strip binary.') + + argparser.add_argument('--eu-strip-binary-path', help='eu-strip path.') + argparser.add_argument('--binary-input', help='exe file path.') + argparser.add_argument('--symbol-output', help='debug file path.') + argparser.add_argument('--stripped-binary-output', help='stripped file path.') + args = argparser.parse_args() + + cmd_line = [ + args.eu_strip_binary_path, '-o', args.stripped_binary_output, '-f', + args.symbol_output, args.binary_input + ] + + process = subprocess.Popen(cmd_line) + + return process.returncode + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index fa57158..a65a6ae 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -34,6 +34,7 @@ import("//build/config/android/rules.gni") } else if (is_linux || is_chromeos) { import("//build/linux/extract_symbols.gni") + import("//build/linux/strip_binary.gni") } else if (is_mac) { import("//build/apple/tweak_info_plist.gni") import("//build/compiled_action.gni") @@ -1676,3 +1677,13 @@ outputs = [ "$root_out_dir/{{source_file_part}}" ] } } + +if (is_chromeos_lacros && is_official_build) { + # This will strip chrome binary and produce chrome.debug with symbols. + strip_binary("strip_chrome_binary") { + binary_input = "$root_out_dir/chrome" + symbol_output = "$root_out_dir/chrome.debug" + stripped_binary_output = "$root_out_dir/chrome.stripped" + deps = [ ":chrome" ] + } +}
diff --git a/chrome/VERSION b/chrome/VERSION index 5a7a38b..f5cd3446 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=90 MINOR=0 -BUILD=4408 +BUILD=4409 PATCH=0
diff --git a/chrome/android/features/cablev2_authenticator/java/res/drawable/usb_conn.xml b/chrome/android/features/cablev2_authenticator/java/res/drawable/usb_conn.xml index 7ba812f9..06d6fc79 100644 --- a/chrome/android/features/cablev2_authenticator/java/res/drawable/usb_conn.xml +++ b/chrome/android/features/cablev2_authenticator/java/res/drawable/usb_conn.xml
@@ -7,9 +7,6 @@ a:pathData='M252.515,318.104H26.455A10.367,10.367 0,0 1,16.1 307.749V296.938a2,2 0,0 1,4 0v10.811a6.362,6.362 0,0 0,6.356 6.355h226.06a6.362,6.362 0,0 0,6.356 -6.355v-141.47a6.362,6.362 0,0 0,-6.356 -6.355H192.666a2,2 0,0 1,0 -4h59.849a10.367,10.367 0,0 1,10.356 10.355v141.47A10.367,10.367 0,0 1,252.515 318.104ZM18.1,268.938a2,2 0,0 1,-2 -2V166.279A10.367,10.367 0,0 1,26.455 155.923H162.666a2,2 0,0 1,0 4H26.455a6.362,6.362 0,0 0,-6.356 6.355V266.938a2,2 0,0 1,-2 2z' a:fillColor='#bdc1c6'/> <path - a:pathData='M32.194,171.569h214.583v130.889h-214.583z' - a:fillColor='#ffffff'/> - <path a:pathData='m0,326.692v3.919A8.355,8.355 0,0 0,8.356 338.967h262.259a8.355,8.355 0,0 0,8.356 -8.356v-3.919z' a:fillColor='#bdc1c6'/> <path
diff --git a/chrome/android/java/res/xml/account_management_preferences.xml b/chrome/android/java/res/xml/account_management_preferences.xml index 6dc04a94..e729e3ca 100644 --- a/chrome/android/java/res/xml/account_management_preferences.xml +++ b/chrome/android/java/res/xml/account_management_preferences.xml
@@ -11,8 +11,6 @@ android:key="accounts_category" android:title="@string/account_management_title"/> - <Preference - android:layout="@layout/divider_preference"/> <PreferenceCategory android:key="parental_settings" @@ -28,7 +26,6 @@ android:title="@string/account_management_child_content_title"/> <Preference - android:key="child_content_divider" android:layout="@layout/divider_preference"/> <Preference
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java index 37c415a5..9250ce49 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java
@@ -79,7 +79,6 @@ private static final String PREF_PARENTAL_SETTINGS = "parental_settings"; private static final String PREF_PARENT_ACCOUNTS = "parent_accounts"; private static final String PREF_CHILD_CONTENT = "child_content"; - private static final String PREF_CHILD_CONTENT_DIVIDER = "child_content_divider"; private static final String PREF_SIGN_OUT = "sign_out"; private static final String PREF_SIGN_OUT_DIVIDER = "sign_out_divider"; @@ -272,7 +271,6 @@ prefScreen.removePreference(findPreference(PREF_PARENTAL_SETTINGS)); prefScreen.removePreference(parentAccounts); prefScreen.removePreference(childContent); - prefScreen.removePreference(findPreference(PREF_CHILD_CONTENT_DIVIDER)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java index 9a66bd3f..f2b5c1e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java
@@ -402,9 +402,7 @@ @Override public void signOutComplete() { - if (clearDataProgressDialog.isAdded()) { - clearDataProgressDialog.dismissAllowingStateLoss(); - } + clearDataProgressDialog.dismissAllowingStateLoss(); } }, forceWipeUserData);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java index f8767be..22b967d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java
@@ -20,7 +20,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -44,7 +43,7 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; /** - * Tests for ManageSyncSettings. + * Tests for GoogleServicesSettings. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @@ -111,7 +110,6 @@ @Test @LargeTest @Features.EnableFeatures(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY) - @DisableIf.Build(supported_abis_includes = "x86", message = "https://crbug.com/1142481") public void showSignOutDialogBeforeSigningUserOut() { mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync(); final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings();
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 7ba681b..1611358 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-90.0.4405.2_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-90.0.4406.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 915645a..d4004e84 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -6855,6 +6855,7 @@ "//chromeos/disks", "//chromeos/login/auth", "//components/session_manager/core", + "//extensions/browser/api/messaging", "//ui/base:test_support", "//ui/base/ime/chromeos", ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index bd4e059..dfa1b37c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3975,9 +3975,6 @@ SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchCalibrationSetting)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH) - {"camera-system-web-app", flag_descriptions::kCameraSystemWebAppName, - flag_descriptions::kCameraSystemWebAppDescription, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::features::kCameraSystemWebApp)}, {"prefer-constant-frame-rate", flag_descriptions::kPreferConstantFrameRateName, flag_descriptions::kPreferConstantFrameRateDescription, kOsCrOS,
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index c18fcd3..23798a8 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -667,6 +667,8 @@ "arc/fileapi/arc_content_file_system_file_stream_reader.h", "arc/fileapi/arc_content_file_system_file_stream_writer.cc", "arc/fileapi/arc_content_file_system_file_stream_writer.h", + "arc/fileapi/arc_content_file_system_size_util.cc", + "arc/fileapi/arc_content_file_system_size_util.h", "arc/fileapi/arc_content_file_system_url_util.cc", "arc/fileapi/arc_content_file_system_url_util.h", "arc/fileapi/arc_documents_provider_async_file_util.cc",
diff --git a/chrome/browser/chromeos/arc/arc_util.cc b/chrome/browser/chromeos/arc/arc_util.cc index 9290d9a..1f10ab8 100644 --- a/chrome/browser/chromeos/arc/arc_util.cc +++ b/chrome/browser/chromeos/arc/arc_util.cc
@@ -620,10 +620,6 @@ chromeos::features::ShouldShowPlayStoreInDemoMode(); } -bool IsSecondaryAccountForChildEnabled() { - return base::FeatureList::IsEnabled(kEnableSecondaryAccountsForChild); -} - bool ShouldStartArcSilentlyForManagedProfile(const Profile* profile) { return IsArcPlayStoreEnabledPreferenceManagedForProfile(profile) && (AreArcAllOptInPreferencesIgnorableForProfile(profile) ||
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc index ec42e5c..cfa4da024 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -542,14 +542,6 @@ if (!arc::IsArcProvisioned(profile_)) return; - // For child device accounts do not allow the propagation of secondary - // accounts from Chrome OS Account Manager to ARC unless experimental feature - // is enabled. - if (!arc::IsSecondaryAccountForChildEnabled() && profile_->IsChild() && - !IsPrimaryGaiaAccount(account_info.gaia)) { - return; - } - if (identity_manager_->HasAccountWithRefreshTokenInPersistentErrorState( account_info.account_id)) { VLOG(1) << "Ignoring account update due to lack of a valid token: "
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc index d45180d..46cc3123 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" @@ -18,7 +17,6 @@ #include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/arc/arc_util.h" @@ -196,16 +194,9 @@ DISALLOW_COPY_AND_ASSIGN(FakeAuthInstance); }; -// Features that will be enabled in the given test. -using EnabledFeatures = std::vector<base::Feature>; - -class ArcAuthServiceTest : public InProcessBrowserTest, - public testing::WithParamInterface<EnabledFeatures> { +class ArcAuthServiceTest : public InProcessBrowserTest { protected: - ArcAuthServiceTest() { - scoped_feature_list_.InitWithFeatures(GetParam() /* enabled_features */, - {} /* disabled_features */); - } + ArcAuthServiceTest() = default; // InProcessBrowserTest: ~ArcAuthServiceTest() override = default; @@ -447,7 +438,6 @@ private: std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; base::ScopedTempDir temp_dir_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<TestingProfile> profile_; network::TestURLLoaderFactory test_url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; @@ -466,13 +456,7 @@ DISALLOW_COPY_AND_ASSIGN(ArcAuthServiceTest); }; -INSTANTIATE_TEST_SUITE_P( - All, - ArcAuthServiceTest, - ::testing::Values(EnabledFeatures{}, - EnabledFeatures{kEnableSecondaryAccountsForChild})); - -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, GetPrimaryAccountForGaiaAccounts) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForGaiaAccounts) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); const std::pair<std::string, mojom::ChromeAccountType> primary_account = RequestPrimaryAccount(); @@ -480,7 +464,7 @@ EXPECT_EQ(mojom::ChromeAccountType::USER_ACCOUNT, primary_account.second); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, GetPrimaryAccountForChildAccounts) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForChildAccounts) { SetAccountAndProfile(user_manager::USER_TYPE_CHILD); const std::pair<std::string, mojom::ChromeAccountType> primary_account = RequestPrimaryAccount(); @@ -488,7 +472,7 @@ EXPECT_EQ(mojom::ChromeAccountType::CHILD_ACCOUNT, primary_account.second); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForActiveDirectoryAccounts) { SetAccountAndProfile(user_manager::USER_TYPE_ACTIVE_DIRECTORY); const std::pair<std::string, mojom::ChromeAccountType> @@ -498,7 +482,7 @@ primary_account.second); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, GetPrimaryAccountForPublicAccounts) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForPublicAccounts) { SetAccountAndProfile(user_manager::USER_TYPE_PUBLIC_ACCOUNT); const std::pair<std::string, mojom::ChromeAccountType> primary_account = RequestPrimaryAccount(); @@ -506,7 +490,7 @@ EXPECT_EQ(mojom::ChromeAccountType::ROBOT_ACCOUNT, primary_account.second); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, GetPrimaryAccountForOfflineDemoAccounts) { chromeos::DemoSession::SetDemoConfigForTesting( chromeos::DemoSession::DemoModeConfig::kOffline); @@ -521,7 +505,7 @@ // Tests that when ARC requests account info for a non-managed account, // Chrome supplies the info configured in SetAccountAndProfile() method. -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, SuccessfulBackgroundFetch) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, SuccessfulBackgroundFetch) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); test_url_loader_factory()->AddResponse(arc::kAuthTokenExchangeEndPoint, GetFakeAuthTokenResponse()); @@ -540,7 +524,7 @@ EXPECT_FALSE(auth_instance().account_info()->is_managed); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, ReAuthenticatePrimaryAccountSucceeds) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); test_url_loader_factory()->AddResponse(arc::kAuthTokenExchangeEndPoint, @@ -561,7 +545,7 @@ EXPECT_FALSE(auth_instance().sign_in_persistent_error()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, RetryAuthTokenExchangeRequestOnUnauthorizedError) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); @@ -583,7 +567,7 @@ ASSERT_TRUE(auth_instance().account_info()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, ReAuthenticatePrimaryAccountFailsForInvalidAccount) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); test_url_loader_factory()->AddResponse(arc::kAuthTokenExchangeEndPoint, @@ -599,7 +583,7 @@ auth_instance().auth_code_status()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, FetchSecondaryAccountInfoSucceeds) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchSecondaryAccountInfoSucceeds) { // Add a Secondary Account. SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); SeedAccountInfo(kSecondaryAccountEmail); @@ -622,7 +606,7 @@ EXPECT_FALSE(auth_instance().sign_in_persistent_error()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchSecondaryAccountInfoFailsForInvalidAccounts) { // Add a Secondary Account. SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); @@ -641,7 +625,7 @@ auth_instance().auth_code_status()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchSecondaryAccountInfoInvalidRefreshToken) { const AccountInfo account_info = SetupGaiaAccount(kSecondaryAccountEmail); SetInvalidRefreshTokenForAccount(account_info.account_id); @@ -660,7 +644,7 @@ EXPECT_TRUE(auth_instance().sign_in_persistent_error()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchSecondaryAccountRefreshTokenHasPersistentError) { const AccountInfo account_info = SetupGaiaAccount(kSecondaryAccountEmail); UpdatePersistentErrorOfRefreshTokenForAccount( @@ -680,7 +664,7 @@ EXPECT_TRUE(auth_instance().sign_in_persistent_error()); } -IN_PROC_BROWSER_TEST_P( +IN_PROC_BROWSER_TEST_F( ArcAuthServiceTest, FetchSecondaryAccountInfoReturnsErrorForNotFoundAccounts) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); @@ -697,7 +681,7 @@ EXPECT_TRUE(auth_instance().sign_in_persistent_error()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, FetchGoogleAccountsFromArc) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchGoogleAccountsFromArc) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); EXPECT_FALSE(arc_google_accounts_callback_called()); @@ -711,7 +695,7 @@ arc_google_accounts()[0]->gaia_id); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, FetchGoogleAccountsFromArcWorksAcrossConnectionResets) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); @@ -734,7 +718,7 @@ arc_google_accounts()[0]->gaia_id); } -IN_PROC_BROWSER_TEST_P( +IN_PROC_BROWSER_TEST_F( ArcAuthServiceTest, PrimaryAccountReauthIsNotAttemptedJustAfterProvisioning) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); @@ -749,7 +733,7 @@ EXPECT_EQ(initial_num_calls, auth_instance().num_account_upserted_calls()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, UnAuthenticatedAccountsAreNotPropagated) { const AccountInfo account_info = SetupGaiaAccount(kSecondaryAccountEmail); @@ -761,7 +745,7 @@ EXPECT_EQ(initial_num_calls, auth_instance().num_account_upserted_calls()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, AccountUpdatesArePropagated) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, AccountUpdatesArePropagated) { AccountInfo account_info = SetupGaiaAccount(kSecondaryAccountEmail); SetInvalidRefreshTokenForAccount(account_info.account_id); @@ -776,7 +760,7 @@ EXPECT_EQ(kSecondaryAccountEmail, auth_instance().last_upserted_account()); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, AccountRemovalsArePropagated) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, AccountRemovalsArePropagated) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); SeedAccountInfo(kSecondaryAccountEmail); @@ -856,13 +840,9 @@ DISALLOW_COPY_AND_ASSIGN(ArcRobotAccountAuthServiceTest); }; -INSTANTIATE_TEST_SUITE_P(All, - ArcRobotAccountAuthServiceTest, - ::testing::Values(EnabledFeatures{})); - // Tests that when ARC requests account info for a demo session account, // Chrome supplies the info configured in SetAccountAndProfile() above. -IN_PROC_BROWSER_TEST_P(ArcRobotAccountAuthServiceTest, GetDemoAccount) { +IN_PROC_BROWSER_TEST_F(ArcRobotAccountAuthServiceTest, GetDemoAccount) { chromeos::DemoSession::SetDemoConfigForTesting( chromeos::DemoSession::DemoModeConfig::kOnline); chromeos::DemoSession::StartIfInDemoMode(); @@ -887,7 +867,7 @@ EXPECT_FALSE(auth_instance().account_info()->is_managed); } -IN_PROC_BROWSER_TEST_P(ArcRobotAccountAuthServiceTest, GetOfflineDemoAccount) { +IN_PROC_BROWSER_TEST_F(ArcRobotAccountAuthServiceTest, GetOfflineDemoAccount) { chromeos::DemoSession::SetDemoConfigForTesting( chromeos::DemoSession::DemoModeConfig::kOffline); chromeos::DemoSession::StartIfInDemoMode(); @@ -907,7 +887,7 @@ EXPECT_TRUE(auth_instance().account_info()->is_managed); } -IN_PROC_BROWSER_TEST_P(ArcRobotAccountAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcRobotAccountAuthServiceTest, GetDemoAccountOnAuthTokenFetchFailure) { chromeos::DemoSession::SetDemoConfigForTesting( chromeos::DemoSession::DemoModeConfig::kOnline); @@ -934,7 +914,7 @@ EXPECT_TRUE(auth_instance().account_info()->is_managed); } -IN_PROC_BROWSER_TEST_P(ArcRobotAccountAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcRobotAccountAuthServiceTest, RequestPublicAccountInfo) { SetAccountAndProfile(user_manager::USER_TYPE_PUBLIC_ACCOUNT); profile()->GetProfilePolicyConnector()->OverrideIsManagedForTesting(true); @@ -960,7 +940,7 @@ // Tests that when ARC requests account info for a child account and // Chrome supplies the info configured in SetAccountAndProfile() above. -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, ChildAccountFetch) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, ChildAccountFetch) { SetAccountAndProfile(user_manager::USER_TYPE_CHILD); EXPECT_TRUE(profile()->IsChild()); test_url_loader_factory()->AddResponse(arc::kAuthTokenExchangeEndPoint, @@ -980,7 +960,7 @@ EXPECT_FALSE(auth_instance().account_info()->is_managed); } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, ChildTransition) { +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, ChildTransition) { SetAccountAndProfile(user_manager::USER_TYPE_CHILD); ArcSessionManager* session = ArcSessionManager::Get(); @@ -1087,21 +1067,20 @@ } } -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, RegularUserSecondaryAccountsArePropagated) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR); SeedAccountInfo(kSecondaryAccountEmail); EXPECT_EQ(2, auth_instance().num_account_upserted_calls()); } -// Tests that child account propagation depends on the feature flag. -IN_PROC_BROWSER_TEST_P(ArcAuthServiceTest, +// Tests child account propagation for Family Link user. +IN_PROC_BROWSER_TEST_F(ArcAuthServiceTest, ChildUserSecondaryAccountsPropagation) { SetAccountAndProfile(user_manager::USER_TYPE_CHILD); SeedAccountInfo(kSecondaryAccountEmail); EXPECT_TRUE(profile()->IsChild()); - EXPECT_EQ(arc::IsSecondaryAccountForChildEnabled() ? 2 : 1, - auth_instance().num_account_upserted_calls()); + EXPECT_EQ(2, auth_instance().num_account_upserted_calls()); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc index 7722164..f4a85fc 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc
@@ -15,6 +15,7 @@ #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/scoped_blocking_call.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h" #include "content/public/browser/browser_thread.h" #include "mojo/public/cpp/platform/platform_handle.h" @@ -42,6 +43,13 @@ return result < 0 ? errno : 0; } +void OnGetSizeFromFileHandle(net::Int64CompletionOnceCallback callback, + base::File::Error error, + int64_t size) { + std::move(callback).Run(error == base::File::FILE_OK ? size + : net::ERR_FAILED); +} + } // namespace ArcContentFileSystemFileStreamReader::ArcContentFileSystemFileStreamReader( @@ -114,7 +122,13 @@ net::Int64CompletionOnceCallback callback, int64_t size) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - std::move(callback).Run(size < 0 ? net::ERR_FAILED : size); + if (size == kUnknownFileSize) { + GetFileSizeFromOpenFileOnIOThread( + arc_url_, + base::BindOnce(&OnGetSizeFromFileHandle, std::move(callback))); + } else { + std::move(callback).Run(size < 0 ? net::ERR_FAILED : size); + } } void ArcContentFileSystemFileStreamReader::OnOpenFile(
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc index 6139f94..1ac4cb4a 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
@@ -12,6 +12,7 @@ #include "base/location.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" #include "chrome/test/base/testing_profile.h" #include "components/arc/arc_service_manager.h" @@ -37,6 +38,14 @@ // URL which returns a file descriptor of a pipe's read end. constexpr char kArcUrlPipe[] = "content://org.chromium.foo/pipe"; +// URL which returns a file descriptor of a regular file with unknown size. +constexpr char kArcUrlFileUnknownSize[] = + "content://org.chromium.foo/file-unknown-size"; + +// URL which returns a file descriptor of a pipe's read end with unknown size. +constexpr char kArcUrlPipeUnknownSize[] = + "content://org.chromium.foo/pipe-unknown-size"; + constexpr char kData[] = "abcdefghijklmnopqrstuvwxyz"; constexpr char kMimeType[] = "application/octet-stream"; @@ -77,6 +86,10 @@ File(kArcUrlFile, kData, kMimeType, File::Seekable::YES)); fake_file_system_.AddFile( File(kArcUrlPipe, kData, kMimeType, File::Seekable::NO)); + fake_file_system_.AddFile(File(kArcUrlFileUnknownSize, kData, kMimeType, + File::Seekable::YES, -1)); + fake_file_system_.AddFile( + File(kArcUrlPipeUnknownSize, kData, kMimeType, File::Seekable::NO, -1)); arc_service_manager_ = std::make_unique<ArcServiceManager>(); profile_ = std::make_unique<TestingProfile>(); @@ -153,6 +166,23 @@ callback.GetResult(reader.GetLength(callback.callback()))); } +TEST_F(ArcContentFileSystemFileStreamReaderTest, GetLengthUnknownSizeSeekable) { + ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFileUnknownSize), 0); + + net::TestInt64CompletionCallback callback; + EXPECT_EQ(static_cast<int64_t>(strlen(kData)), + callback.GetResult(reader.GetLength(callback.callback()))); +} + +TEST_F(ArcContentFileSystemFileStreamReaderTest, + GetLengthUnknownSizeNotSeekable) { + ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlPipeUnknownSize), 0); + + net::TestInt64CompletionCallback callback; + EXPECT_EQ(static_cast<int64_t>(net::ERR_FAILED), + callback.GetResult(reader.GetLength(callback.callback()))); +} + TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadError) { ArcContentFileSystemFileStreamReader reader( GURL("content://org.chromium.foo/error"), 0);
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.cc new file mode 100644 index 0000000..2afc772 --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.cc
@@ -0,0 +1,73 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h" + +#include "base/task/thread_pool.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "url/gurl.h" + +using content::BrowserThread; + +namespace arc { + +namespace { + +struct Result { + base::File::Error error; + int64_t size; +}; + +Result GetFileSizeFromFileHandle(mojo::ScopedHandle handle) { + mojo::PlatformHandle platform_handle = + mojo::UnwrapPlatformHandle(std::move(handle)); + if (!platform_handle.is_valid()) { + return {base::File::FILE_ERROR_NOT_FOUND, -1}; + } + base::ScopedPlatformFile file = platform_handle.TakePlatformFile(); + base::stat_wrapper_t info; + if (base::File::Fstat(file.get(), &info) < 0 || !S_ISREG(info.st_mode)) { + return {base::File::FILE_ERROR_FAILED, -1}; + } else { + return {base::File::FILE_OK, info.st_size}; + } +} + +void ReplyWithFileSizeFromHandleResult(GetFileSizeFromOpenFileCallback callback, + Result result) { + std::move(callback).Run(result.error, result.size); +} + +void OnOpenFileToGetSize(GetFileSizeFromOpenFileCallback callback, + mojo::ScopedHandle handle) { + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, + base::BindOnce(&GetFileSizeFromFileHandle, std::move(handle)), + base::BindOnce(&ReplyWithFileSizeFromHandleResult, std::move(callback))); +} + +} // namespace + +void GetFileSizeFromOpenFileOnIOThread( + GURL content_url, + GetFileSizeFromOpenFileCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + file_system_operation_runner_util::OpenFileToReadOnIOThread( + content_url, base::BindOnce(&OnOpenFileToGetSize, std::move(callback))); +} + +void GetFileSizeFromOpenFileOnUIThread( + GURL content_url, + ArcFileSystemOperationRunner* runner, + GetFileSizeFromOpenFileCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + runner->OpenFileToRead( + content_url, base::BindOnce(&OnOpenFileToGetSize, std::move(callback))); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h new file mode 100644 index 0000000..1974940 --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h
@@ -0,0 +1,35 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_SIZE_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_SIZE_UTIL_H_ + +class GURL; + +#include "base/callback.h" +#include "base/files/file.h" + +namespace arc { + +class ArcFileSystemOperationRunner; + +constexpr int64_t kUnknownFileSize = -1; + +using GetFileSizeFromOpenFileCallback = + base::OnceCallback<void(base::File::Error error, int64_t file_size)>; + +// Opens the file and gets the file size from the opened file descriptor. +// It will fail if the file descriptor returned by the open call is not a file. +// Must be run on the IO thread. +void GetFileSizeFromOpenFileOnIOThread( + GURL content_url, + GetFileSizeFromOpenFileCallback callback); +// Same as GetFileSizeFromOpenFileOnIOThread, but must be run on the UI thread. +void GetFileSizeFromOpenFileOnUIThread( + GURL content_url, + ArcFileSystemOperationRunner* runner, + GetFileSizeFromOpenFileCallback callback); +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_SIZE_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc index cbfeba2..b9c00944 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_async_file_util.cc
@@ -106,7 +106,8 @@ } root->GetFileInfo( - path, base::BindOnce(&OnGetFileInfoOnUIThread, std::move(callback))); + path, fields, + base::BindOnce(&OnGetFileInfoOnUIThread, std::move(callback))); } void ReadDirectoryOnUIThread(
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc index 20710557..2efae7b 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
@@ -12,8 +12,10 @@ #include "base/check_op.h" #include "base/files/file.h" #include "base/strings/stringprintf.h" +#include "base/task/thread_pool.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_size_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" #include "content/public/browser/browser_thread.h" #include "net/base/mime_util.h" @@ -29,6 +31,33 @@ // Directory cache will be cleared this duration after it is built. constexpr base::TimeDelta kCacheExpiration = base::TimeDelta::FromSeconds(60); +void OnGetFileSizeFromOpenFile( + ArcDocumentsProviderRoot::GetFileInfoCallback callback, + base::File::Info info, + base::File::Error error, + int64_t size) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (error == base::File::FILE_OK) { + info.size = size; + std::move(callback).Run(error, info); + } else { + std::move(callback).Run(error, base::File::Info()); + } +} + +void OnResolveToContentUrl( + ArcDocumentsProviderRoot::GetFileInfoCallback callback, + ArcFileSystemOperationRunner* runner, + const base::File::Info& info, + const GURL& content_url) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + GetFileSizeFromOpenFileOnUIThread( + content_url, runner, + base::BindOnce(&OnGetFileSizeFromOpenFile, std::move(callback), info)); +} + } // namespace // Represents the status of a document watcher. @@ -95,6 +124,7 @@ } void ArcDocumentsProviderRoot::GetFileInfo(const base::FilePath& path, + int fields, GetFileInfoCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (path.IsAbsolute()) { @@ -117,9 +147,10 @@ return; } - GetDocument(path, base::BindOnce( - &ArcDocumentsProviderRoot::GetFileInfoFromDocument, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + GetDocument( + path, base::BindOnce(&ArcDocumentsProviderRoot::GetFileInfoFromDocument, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + path, fields)); } void ArcDocumentsProviderRoot::ReadDirectory(const base::FilePath& path, @@ -290,6 +321,8 @@ void ArcDocumentsProviderRoot::GetFileInfoFromDocument( GetFileInfoCallback callback, + const base::FilePath& path, + int fields, base::File::Error error, const mojom::DocumentPtr& document) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -300,13 +333,29 @@ DCHECK(document); base::File::Info info; - info.size = document->size; - info.is_directory = document->mime_type == kAndroidDirectoryMimeType; + if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_SIZE) { + info.size = document->size; + } + bool is_directory = document->mime_type == kAndroidDirectoryMimeType; + if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY) { + info.is_directory = is_directory; + } info.is_symbolic_link = false; - info.last_modified = info.last_accessed = info.creation_time = - base::Time::FromJavaTime(document->last_modified); + if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED) { + info.last_modified = info.last_accessed = info.creation_time = + base::Time::FromJavaTime(document->last_modified); + } - std::move(callback).Run(base::File::FILE_OK, info); + if ((fields & storage::FileSystemOperation::GET_METADATA_FIELD_SIZE) && + info.size == kUnknownFileSize && !is_directory) { + // We don't know the size from metadata and the size is requested, find it + // out by opening the file + ResolveToContentUrl( + path, base::BindOnce(&OnResolveToContentUrl, std::move(callback), + runner_, info)); + } else { + std::move(callback).Run(base::File::FILE_OK, info); + } } void ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId(
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h index b220dcef..6781648 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h
@@ -87,8 +87,12 @@ const std::vector<std::string>& mime_types); ~ArcDocumentsProviderRoot() override; - // Queries information of a file just like AsyncFileUtil.GetFileInfo(). - void GetFileInfo(const base::FilePath& path, GetFileInfoCallback callback); + // Queries information of a file just like AsyncFileUtil.GetFileInfo(). If the + // file metadata reports unknown size, it will attempt to open the file and + // read the size from the file descriptor. + void GetFileInfo(const base::FilePath& path, + int fields, + GetFileInfoCallback callback); // Queries a list of files under a directory just like // AsyncFileUtil.ReadDirectory(). @@ -228,6 +232,8 @@ const mojom::DocumentPtr& document)>; void GetFileInfoFromDocument(GetFileInfoCallback callback, + const base::FilePath& path, + int fields, base::File::Error error, const mojom::DocumentPtr& document);
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc index c034231..6347ded5 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -22,12 +22,14 @@ #include "components/arc/test/fake_file_system_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "content/public/test/browser_task_environment.h" +#include "storage/browser/file_system/file_system_operation.h" #include "storage/browser/file_system/watcher_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" using ChangeType = arc::ArcDocumentsProviderRoot::ChangeType; using Document = arc::FakeFileSystemInstance::Document; +using FakeFile = arc::FakeFileSystemInstance::File; using EntryList = storage::AsyncFileUtil::EntryList; namespace arc { @@ -58,6 +60,8 @@ // music.bin audio/mp3 music-id // no-delete.jpg image/jpeg no-delete-id // Non-deletable file // no-rename.jpg image/jpeg no-rename-id // Non-renamable file +// size-file.jpg image/jpeg size-file-id // File with unknown size +// size-pipe.jpg image/jpeg size-pipe-id // Pipe with unknown size // dups/ dir dups-id // dup.mp4 video/mp4 dup1-id // dup.mp4 video/mp4 dup2-id @@ -102,6 +106,26 @@ false, true, true}; +constexpr DocumentSpec kUnknownSizeFileSpec{"size-file-id", + kDirSpec.document_id, + "size-file.jpg", + "image/jpeg", + -1, + 46, + true, + true, + true, + true}; +constexpr DocumentSpec kUnknownSizePipeSpec{"size-pipe-id", + kDirSpec.document_id, + "size-pipe.jpg", + "image/jpeg", + -1, + 46, + true, + true, + true, + true}; constexpr DocumentSpec kDupsSpec{"dups-id", kRootSpec.document_id, "dups", kAndroidDirectoryMimeType, -1, 55, @@ -132,13 +156,28 @@ -1, 56, false, false, false, false}; +constexpr int kAllMetadataFields = + storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY | + storage::FileSystemOperation::GET_METADATA_FIELD_SIZE | + storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED; // The order is intentionally shuffled here so that // FileSystemInstance::GetChildDocuments() returns documents in shuffled order. // See ResolveToContentUrlDups test below. -constexpr DocumentSpec kAllSpecs[] = { - kRootSpec, kDirSpec, kPhotoSpec, kMusicSpec, kNoDeleteSpec, kNoRenameSpec, - kDupsSpec, kDup2Spec, kDup1Spec, kDup4Spec, kDup3Spec, kRoDirSpec}; +constexpr DocumentSpec kAllSpecs[] = {kRootSpec, + kDirSpec, + kPhotoSpec, + kMusicSpec, + kNoDeleteSpec, + kNoRenameSpec, + kUnknownSizeFileSpec, + kUnknownSizePipeSpec, + kDupsSpec, + kDup2Spec, + kDup1Spec, + kDup4Spec, + kDup3Spec, + kRoDirSpec}; Document ToDocument(const DocumentSpec& spec) { return Document( @@ -147,6 +186,15 @@ spec.supports_rename, spec.dir_supports_create, spec.supports_thumbnail); } +std::vector<FakeFile> AllFiles() { + return { + FakeFile("content://org.chromium.test/document/size-file-id", "01234", + "image/jpeg", FakeFile::Seekable::YES, -1), + FakeFile("content://org.chromium.test/document/size-pipe-id", "01234", + "image/jpeg", FakeFile::Seekable::NO, -1), + }; +} + void ExpectMatchesSpec(const base::File::Info& info, const DocumentSpec& spec) { EXPECT_EQ(spec.size, info.size); if (spec.mime_type == kAndroidDirectoryMimeType) { @@ -178,6 +226,9 @@ for (auto spec : kAllSpecs) { fake_file_system_.AddDocument(ToDocument(spec)); } + for (auto file : AllFiles()) { + fake_file_system_.AddFile(file); + } arc_service_manager_ = std::make_unique<ArcServiceManager>(); profile_ = std::make_unique<TestingProfile>(); @@ -232,6 +283,7 @@ TEST_F(ArcDocumentsProviderRootTest, GetFileInfo) { base::RunLoop run_loop; root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), + kAllMetadataFields, base::BindOnce( [](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { @@ -246,6 +298,7 @@ TEST_F(ArcDocumentsProviderRootTest, GetFileInfoDirectory) { base::RunLoop run_loop; root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("dir")), + kAllMetadataFields, base::BindOnce( [](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { @@ -259,7 +312,7 @@ TEST_F(ArcDocumentsProviderRootTest, GetFileInfoRoot) { base::RunLoop run_loop; - root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("")), + root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("")), kAllMetadataFields, base::BindOnce( [](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { @@ -274,6 +327,7 @@ TEST_F(ArcDocumentsProviderRootTest, GetFileInfoNoSuchFile) { base::RunLoop run_loop; root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("dir/missing.jpg")), + kAllMetadataFields, base::BindOnce( [](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { @@ -289,6 +343,7 @@ // "dup (2).mp4" should map to the 3rd instance of "dup.mp4" regardless of the // order returned from FileSystemInstance. root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("dups/dup (2).mp4")), + kAllMetadataFields, base::BindOnce( [](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { @@ -304,7 +359,7 @@ { base::RunLoop run_loop; root_->GetFileInfo( - base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), + base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), kAllMetadataFields, base::BindOnce([](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { run_loop->Quit(); }, &run_loop)); @@ -316,7 +371,7 @@ { base::RunLoop run_loop; root_->GetFileInfo( - base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), + base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), kAllMetadataFields, base::BindOnce([](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { run_loop->Quit(); }, &run_loop)); @@ -334,7 +389,7 @@ { base::RunLoop run_loop; root_->GetFileInfo( - base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), + base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), kAllMetadataFields, base::BindOnce([](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { run_loop->Quit(); }, &run_loop)); @@ -349,7 +404,7 @@ { base::RunLoop run_loop; root_->GetFileInfo( - base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), + base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")), kAllMetadataFields, base::BindOnce([](base::RunLoop* run_loop, base::File::Error error, const base::File::Info& info) { run_loop->Quit(); }, &run_loop)); @@ -361,6 +416,38 @@ EXPECT_EQ(last_count + 2, fake_file_system_.get_child_documents_count()); } +TEST_F(ArcDocumentsProviderRootTest, GetFileInfoUnknownSizeFile) { + base::RunLoop run_loop; + root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("dir/size-file.jpg")), + kAllMetadataFields, + base::BindOnce( + [](base::RunLoop* run_loop, base::File::Error error, + const base::File::Info& info) { + run_loop->Quit(); + EXPECT_EQ(base::File::FILE_OK, error); + auto expected_spec = kUnknownSizeFileSpec; + // size of file content in AllFiles() + expected_spec.size = 5; + ExpectMatchesSpec(info, expected_spec); + }, + &run_loop)); + run_loop.Run(); +} + +TEST_F(ArcDocumentsProviderRootTest, GetFileInfoUnknownSizePipe) { + base::RunLoop run_loop; + root_->GetFileInfo(base::FilePath(FILE_PATH_LITERAL("dir/size-pipe.jpg")), + kAllMetadataFields, + base::BindOnce( + [](base::RunLoop* run_loop, base::File::Error error, + const base::File::Info& info) { + run_loop->Quit(); + EXPECT_EQ(base::File::FILE_ERROR_FAILED, error); + }, + &run_loop)); + run_loop.Run(); +} + TEST_F(ArcDocumentsProviderRootTest, ReadDirectory) { base::RunLoop run_loop; root_->ReadDirectory( @@ -370,7 +457,7 @@ std::vector<ArcDocumentsProviderRoot::ThinFileInfo> file_list) { run_loop->Quit(); EXPECT_EQ(base::File::FILE_OK, error); - ASSERT_EQ(4u, file_list.size()); + ASSERT_EQ(6u, file_list.size()); EXPECT_EQ(FILE_PATH_LITERAL("music.bin.mp3"), file_list[0].name); EXPECT_EQ("music-id", file_list[0].document_id); EXPECT_FALSE(file_list[0].is_directory); @@ -387,6 +474,14 @@ EXPECT_EQ("photo-id", file_list[3].document_id); EXPECT_FALSE(file_list[3].is_directory); EXPECT_EQ(base::Time::FromJavaTime(33), file_list[3].last_modified); + EXPECT_EQ(FILE_PATH_LITERAL("size-file.jpg"), file_list[4].name); + EXPECT_EQ("size-file-id", file_list[4].document_id); + EXPECT_FALSE(file_list[4].is_directory); + EXPECT_EQ(base::Time::FromJavaTime(46), file_list[4].last_modified); + EXPECT_EQ(FILE_PATH_LITERAL("size-pipe.jpg"), file_list[5].name); + EXPECT_EQ("size-pipe-id", file_list[5].document_id); + EXPECT_FALSE(file_list[5].is_directory); + EXPECT_EQ(base::Time::FromJavaTime(46), file_list[5].last_modified); }, &run_loop)); run_loop.Run();
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc index ca84ec1..7f527f9 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
@@ -18,7 +18,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/values.h" -#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/enterprise/cert_store/cert_store_service.h" #include "chrome/browser/chromeos/arc/session/arc_session_manager.h" #include "chrome/browser/chromeos/platform_keys/key_permissions/extension_key_permissions_service.h" @@ -312,8 +311,7 @@ } if (profile->IsSupervised() && - chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile) && - arc::IsSecondaryAccountForChildEnabled()) { + chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile)) { // Adds "playStoreMode" policy. The policy value is used to restrict the // user from being able to toggle between different accounts in ARC++. filtered_policies.SetStringKey("playStoreMode", "SUPERVISED");
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc index 61c9d83..2e943cd 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -12,7 +12,6 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/strings/strcat.h" -#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/chromeos/arc/enterprise/arc_data_snapshotd_delegate.h" #include "chrome/browser/chromeos/arc/enterprise/arc_force_installed_apps_tracker.h" @@ -678,10 +677,6 @@ } TEST_F(ArcPolicyBridgeTest, ManualChildUserPoliciesSet) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - /* enabled_features */ {arc::kEnableSecondaryAccountsForChild}, - /* disabled_features */ {}); // Mark profile as supervised user. profile()->SetSupervisedUserId(::supervised_users::kChildAccountSUID); EXPECT_TRUE(profile()->IsChild());
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index b3405bdb..3d8024c 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -78,6 +78,7 @@ #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_installer.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_installer_factory.h" +#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/chromeos/printing/cups_printers_manager.h" #include "chrome/browser/chromeos/printing/cups_printers_manager_factory.h" @@ -488,6 +489,10 @@ DCHECK(value.is_bool()); } else if (pref_name == prefs::kLanguagePreloadEngines) { DCHECK(value.is_string()); + } else if (pref_name == plugin_vm::prefs::kPluginVmCameraAllowed) { + DCHECK(value.is_bool()); + } else if (pref_name == plugin_vm::prefs::kPluginVmMicAllowed) { + DCHECK(value.is_bool()); } else { return "The pref " + pref_name + " is not whitelisted."; }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 3d57e3f3..4bce58c 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -338,13 +338,16 @@ TestCase("audioRepeatOneModeMultipleFileDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( - OpenImageBacklight, /* open_image_backlight.js */ + OpenImageMediaApp, /* open_image_media_app.js */ FilesAppBrowserTest, ::testing::Values( - TestCase("imageOpenBacklight").MediaSwa().InGuestMode(), - TestCase("imageOpenBacklight").MediaSwa().DisableJsModules(), - TestCase("imageOpenBacklight").MediaSwa())); + TestCase("imageOpenMediaAppDownloads").MediaSwa().InGuestMode(), + TestCase("imageOpenMediaAppDownloads").MediaSwa().DisableJsModules(), + TestCase("imageOpenMediaAppDownloads").MediaSwa(), + TestCase("imageOpenMediaAppDrive").MediaSwa())); +// TODO(crbug/1030935): Remove these tests when removing Gallery, the equivalent +// coverage for MediaApp is provided by the tests above. WRAPPED_INSTANTIATE_TEST_SUITE_P( OpenImageFiles, /* open_image_files.js */ FilesAppBrowserTest, @@ -376,6 +379,7 @@ FilesAppBrowserTest, ::testing::Values(ZipCase("zipFileOpenDownloads").InGuestMode(), ZipCase("zipFileOpenDownloads"), + ZipCase("zipNotifyFileTasks").ZipNoNaCl(), ZipCase("zipFileOpenDownloadsShiftJIS"), ZipCase("zipFileOpenDownloadsMacOs"), ZipCase("zipFileOpenDownloadsWithAbsolutePaths"), @@ -666,11 +670,14 @@ TestCase("driveAvailableOfflineDirectoryGearMenu"), TestCase("driveAvailableOfflineActionBar"), TestCase("driveLinkToDirectory"), - TestCase("driveLinkOpenFileThroughLinkedDirectory"), - TestCase("driveLinkOpenFileThroughTransitiveLink"), + TestCase("driveLinkOpenFileThroughLinkedDirectory").MediaSwa(), + TestCase("driveLinkOpenFileThroughTransitiveLink").MediaSwa(), TestCase("driveWelcomeBanner"), TestCase("driveOfflineInfoBanner").EnableDriveDssPin(), - TestCase("driveOfflineInfoBannerWithoutFlag"))); + TestCase("driveOfflineInfoBannerWithoutFlag"), + TestCase("driveEnableDocsOfflineDialog"), + TestCase("driveEnableDocsOfflineDialogWithoutWindow"), + TestCase("driveEnableDocsOfflineDialogMultipleWindows"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( HoldingSpace, /* holding_space.js */ @@ -992,7 +999,7 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P( LauncherSearch, /* launcher_search.js */ FilesAppBrowserTest, - ::testing::Values(TestCase("launcherOpenSearchResult"), + ::testing::Values(TestCase("launcherOpenSearchResult").MediaSwa(), TestCase("launcherSearch"), TestCase("launcherSearch").DisableJsModules(), TestCase("launcherSearchOffline").Offline()));
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 072dfda4..5ad8fde 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -71,6 +71,7 @@ #include "chrome/common/pref_names.h" #include "chromeos/components/drivefs/drivefs_host.h" #include "chromeos/components/drivefs/fake_drivefs.h" +#include "chromeos/components/drivefs/mojom/drivefs.mojom.h" #include "chromeos/components/smbfs/smbfs_host.h" #include "chromeos/components/smbfs/smbfs_mounter.h" #include "chromeos/constants/chromeos_switches.h" @@ -1164,6 +1165,16 @@ ASSERT_TRUE(UpdateModifiedTime(entry)); } + void DisplayConfirmDialog(drivefs::mojom::DialogReasonPtr reason) { + fake_drivefs_helper_->fake_drivefs().DisplayConfirmDialog( + std::move(reason), base::BindOnce(&DriveFsTestVolume::OnDialogResult, + base::Unretained(this))); + } + + drivefs::mojom::DialogResult last_dialog_result() { + return last_dialog_result_; + } + private: base::RepeatingCallback<std::unique_ptr<drivefs::DriveFsBootstrapListener>()> CreateDriveFsBootstrapListener() { @@ -1259,6 +1270,12 @@ return GetComputerGrandRoot().Append(computer_name); } + void OnDialogResult(drivefs::mojom::DialogResult result) { + last_dialog_result_ = result; + } + + drivefs::mojom::DialogResult last_dialog_result_; + // Profile associated with this volume: not owned. Profile* profile_ = nullptr; // Integration service used for testing: not owned. @@ -2711,6 +2728,21 @@ ->DropFailedPluginVmDirectoryNotShared(); return; } + + if (name == "displayEnableDocsOfflineDialog") { + drive_volume_->DisplayConfirmDialog(drivefs::mojom::DialogReason::New( + drivefs::mojom::DialogReason::Type::kEnableDocsOffline, + base::FilePath())); + return; + } + + if (name == "getLastDriveDialogResult") { + base::JSONWriter::Write( + base::Value(static_cast<int32_t>(drive_volume_->last_dialog_result())), + output); + return; + } + FAIL() << "Unknown test message: " << name; }
diff --git a/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.cc b/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.cc index b9440d1f..5bfba9d 100644 --- a/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.cc +++ b/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/chromeos/login/saml/password_sync_token_fetcher.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chromeos/components/proximity_auth/screenlock_bridge.h" +#include "chromeos/login/auth/extended_authenticator.h" #include "chromeos/login/auth/user_context.h" #include "components/prefs/pref_service.h" #include "components/session_manager/core/session_manager.h" @@ -179,4 +180,31 @@ // re-tried after the next verify interval. } +void InSessionPasswordSyncManager::CheckCredentials( + const UserContext& user_context) { + extended_authenticator_ = ExtendedAuthenticator::Create(this); + extended_authenticator_.get()->AuthenticateToCheck( + user_context, + base::Bind(&InSessionPasswordSyncManager::OnPasswordAuthSuccess, + weak_factory_.GetWeakPtr(), user_context)); +} + +void InSessionPasswordSyncManager::OnPasswordAuthSuccess( + const UserContext& user_context) { + OnAuthSucceeded(user_context); + lock_screen_start_reauth_dialog->Dismiss(); +} + +// TODO(crbug.com/1163777): Add UMA histograms for lockscreen online +// re-authentication. +void InSessionPasswordSyncManager::OnAuthFailure( + const chromeos::AuthFailure& error) { + NOTIMPLEMENTED(); +} + +void InSessionPasswordSyncManager::OnAuthSuccess( + const UserContext& user_context) { + NOTIMPLEMENTED(); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.h b/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.h index 80d82b0..0d91c62 100644 --- a/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.h +++ b/chrome/browser/chromeos/login/saml/in_session_password_sync_manager.h
@@ -15,6 +15,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_dialogs.h" #include "chromeos/components/proximity_auth/screenlock_bridge.h" +#include "chromeos/login/auth/auth_status_consumer.h" #include "components/account_id/account_id.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" @@ -26,6 +27,7 @@ namespace chromeos { class UserContext; +class ExtendedAuthenticator; // Manages SAML password sync for multiple customer devices. Handles online // re-auth requests triggered by online signin policy or by checking validity @@ -37,7 +39,8 @@ class InSessionPasswordSyncManager : public KeyedService, public session_manager::SessionManagerObserver, - public PasswordSyncTokenFetcher::Consumer { + public PasswordSyncTokenFetcher::Consumer, + public AuthStatusConsumer { public: enum class ReauthenticationReason { kNone, @@ -82,6 +85,16 @@ void OnTokenVerified(bool is_valid) override; void OnApiCallFailed(PasswordSyncTokenFetcher::ErrorType error_type) override; + // Used when the user's credentials is correct. + void OnPasswordAuthSuccess(const UserContext& user_context); + + // Checks user's credentials. + void CheckCredentials(const UserContext& user_context); + + // AuthStatusConsumer: + void OnAuthFailure(const chromeos::AuthFailure& error) override; + void OnAuthSuccess(const UserContext& user_context) override; + std::unique_ptr<LockScreenStartReauthDialog> lock_screen_start_reauth_dialog; private: @@ -98,6 +111,9 @@ proximity_auth::ScreenlockBridge* screenlock_bridge_; std::unique_ptr<PasswordSyncTokenFetcher> password_sync_token_fetcher_; + // Used to authenticate the user. + scoped_refptr<ExtendedAuthenticator> extended_authenticator_; + friend class InSessionPasswordSyncManagerTest; friend class InSessionPasswordSyncManagerFactory;
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index fefda20..1c71506 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -155,6 +155,7 @@ kTPMFirmwareUpdateSettings, kUnaffiliatedArcAllowed, kUpdateDisabled, + kUsbDetachableAllowlist, kVariationsRestrictParameter, kVirtualMachinesAllowed, }; @@ -1032,6 +1033,35 @@ } new_values_cache->SetBoolean(kDeviceShowLowDiskSpaceNotification, show_low_disk_space_notification); + + if (policy.has_usb_detachable_allowlist() && + policy.usb_detachable_allowlist().id_size() > 0) { + const em::UsbDetachableAllowlistProto& container = + policy.usb_detachable_allowlist(); + base::Value allowlist(base::Value::Type::LIST); + for (const auto& entry : container.id()) { + base::Value ids(base::Value::Type::DICTIONARY); + if (entry.has_vendor_id() && entry.has_product_id()) { + ids.SetIntKey(kUsbDetachableAllowlistKeyVid, entry.vendor_id()); + ids.SetIntKey(kUsbDetachableAllowlistKeyPid, entry.product_id()); + } + allowlist.Append(std::move(ids)); + } + new_values_cache->SetValue(kUsbDetachableAllowlist, std::move(allowlist)); + } else if (policy.has_usb_detachable_whitelist()) { + const em::UsbDetachableWhitelistProto& container = + policy.usb_detachable_whitelist(); + base::Value allowlist(base::Value::Type::LIST); + for (const auto& entry : container.id()) { + base::Value ids(base::Value::Type::DICTIONARY); + if (entry.has_vendor_id() && entry.has_product_id()) { + ids.SetIntKey(kUsbDetachableAllowlistKeyVid, entry.vendor_id()); + ids.SetIntKey(kUsbDetachableAllowlistKeyPid, entry.product_id()); + } + allowlist.Append(std::move(ids)); + } + new_values_cache->SetValue(kUsbDetachableAllowlist, std::move(allowlist)); + } } void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
diff --git a/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc b/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc index 6833699..50836fb 100644 --- a/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc +++ b/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc
@@ -13,16 +13,7 @@ #include "content/public/test/browser_test.h" #include "content/public/test/test_navigation_observer.h" -class CameraAppIntegrationTest : public SystemWebAppIntegrationTest { - public: - CameraAppIntegrationTest() { - scoped_feature_list_.InitWithFeatures( - {chromeos::features::kCameraSystemWebApp}, {}); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; +using CameraAppIntegrationTest = SystemWebAppIntegrationTest; IN_PROC_BROWSER_TEST_P(CameraAppIntegrationTest, MainUrlNavigation) { WaitForTestSystemAppInstall();
diff --git a/chrome/browser/chromeos/web_applications/eche_app_info.cc b/chrome/browser/chromeos/web_applications/eche_app_info.cc index fa96a96..4d15fe74 100644 --- a/chrome/browser/chromeos/web_applications/eche_app_info.cc +++ b/chrome/browser/chromeos/web_applications/eche_app_info.cc
@@ -22,7 +22,10 @@ // |title| should come from a resource string, but this is the Eche app, and // doesn't have one. info->title = base::UTF8ToUTF16("Eche App"); - // TODO(b/178159012): create icon info for system web app. + web_app::CreateIconInfoForSystemWebApp( + info->start_url, + {{"eche_icon_256.png", 256, IDR_CHROMEOS_ECHE_APP_ECHE_ICON_256_PNG}}, + *info); info->theme_color = 0xFF4285F4; info->background_color = 0xFFFFFFFF; info->display_mode = blink::mojom::DisplayMode::kStandalone;
diff --git a/chrome/browser/complex_tasks/task_tab_helper.cc b/chrome/browser/complex_tasks/task_tab_helper.cc index 35e2dac..22e5353 100644 --- a/chrome/browser/complex_tasks/task_tab_helper.cc +++ b/chrome/browser/complex_tasks/task_tab_helper.cc
@@ -132,16 +132,11 @@ navigation_task_id->set_parent_id(prev_navigation_task_id->id()); navigation_task_id->set_root_id(prev_navigation_task_id->root_id()); } -#if defined(OS_ANDROID) - else { - // Cross-tab navigation - only supported in Android. In this case - // the parent and parent root Task IDs are passed from the Java layer - if (this->GetParentTaskId() != -1) { - navigation_task_id->set_parent_id(this->GetParentTaskId()); - navigation_task_id->set_root_id(this->GetParentRootTaskId()); - } - } -#endif // defined(OS_ANDROID) + } else if (GetParentTaskId() != -1) { + // If the previous_entry_index is -1, this is a new tab. Use the parent + // task-id for the case of cross tab navigations (such as window.open). + navigation_task_id->set_parent_id(GetParentTaskId()); + navigation_task_id->set_root_id(GetParentRootTaskId()); } } else { navigation_task_id->set_root_id(navigation_task_id->id()); @@ -176,19 +171,29 @@ base::UmaHistogramExactLinear(histogram_name, spokes, 100); } -#if defined(OS_ANDROID) int64_t TaskTabHelper::GetParentTaskId() { +#if defined(OS_ANDROID) TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents()); - return Java_TaskTabHelper_getParentTaskId( - base::android::AttachCurrentThread(), tab_android->GetJavaObject()); + return tab_android && Java_TaskTabHelper_getParentTaskId( + base::android::AttachCurrentThread(), + tab_android->GetJavaObject()); +#else + return -1; +#endif } int64_t TaskTabHelper::GetParentRootTaskId() { +#if defined(OS_ANDROID) TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents()); - return Java_TaskTabHelper_getParentRootTaskId( - base::android::AttachCurrentThread(), tab_android->GetJavaObject()); + return tab_android && Java_TaskTabHelper_getParentRootTaskId( + base::android::AttachCurrentThread(), + tab_android->GetJavaObject()); +#else + return -1; +#endif } +#if defined(OS_ANDROID) jlong JNI_TaskTabHelper_GetTaskId(JNIEnv* env, const JavaParamRef<jobject>& jweb_contents) { sessions::NavigationTaskId* navigation_task_id =
diff --git a/chrome/browser/complex_tasks/task_tab_helper.h b/chrome/browser/complex_tasks/task_tab_helper.h index d67c83e..66eb33f 100644 --- a/chrome/browser/complex_tasks/task_tab_helper.h +++ b/chrome/browser/complex_tasks/task_tab_helper.h
@@ -61,10 +61,8 @@ void RecordHubAndSpokeNavigationUsage(int sample); -#if defined(OS_ANDROID) int64_t GetParentTaskId(); int64_t GetParentRootTaskId(); -#endif // defined(OS_ANDROID) int last_pruned_navigation_entry_index_; std::map<int, int> entry_index_to_spoke_count_map_;
diff --git a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc index 639dd03..e920973 100644 --- a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc +++ b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc
@@ -141,7 +141,8 @@ /*product_id=*/0, kDeviceManufacturer, kDeviceModel, - kDeviceSerial), + kDeviceSerial, + std::vector<UsbConfigurationInfoPtr>()), broken_traits_(is_broken) {} bool broken_traits() const { return broken_traits_; }
diff --git a/chrome/browser/error_reporting/chrome_js_error_report_processor.cc b/chrome/browser/error_reporting/chrome_js_error_report_processor.cc index 2233307..ac1414f 100644 --- a/chrome/browser/error_reporting/chrome_js_error_report_processor.cc +++ b/chrome/browser/error_reporting/chrome_js_error_report_processor.cc
@@ -163,6 +163,17 @@ params["os"] = base::SysInfo::OperatingSystemName(); params["os_version"] = GetOsVersion(); #endif + constexpr char kSourceSystemParamName[] = "source_system"; + switch (error_report->source_system) { + case JavaScriptErrorReport::SourceSystem::kUnknown: + break; + case JavaScriptErrorReport::SourceSystem::kCrashReportApi: + params[kSourceSystemParamName] = "crash_report_api"; + break; + case JavaScriptErrorReport::SourceSystem::kWebUIObserver: + params[kSourceSystemParamName] = "webui_observer"; + break; + } params["full_url"] = source.spec(); params["url"] = source.path(); params["src"] = source.spec();
diff --git a/chrome/browser/error_reporting/chrome_js_error_report_processor_unittest.cc b/chrome/browser/error_reporting/chrome_js_error_report_processor_unittest.cc index 0e7ebf61c..4ea67d3 100644 --- a/chrome/browser/error_reporting/chrome_js_error_report_processor_unittest.cc +++ b/chrome/browser/error_reporting/chrome_js_error_report_processor_unittest.cc
@@ -133,6 +133,7 @@ // This is from MockChromeJsErrorReportProcessor::GetOsVersion() EXPECT_THAT(actual_report->query, HasSubstr("os_version=7.20.1")); #endif + EXPECT_THAT(actual_report->query, Not(HasSubstr("source_system="))); // These are from MockCrashEndpoint::Client::GetProductNameAndVersion, which // is only defined for non-MAC POSIX systems. TODO(https://crbug.com/1121816): // Get this info for non-POSIX platforms. @@ -155,6 +156,7 @@ report.stack_trace = "bad_func(1, 2)\nonclick()\n"; report.renderer_process_uptime_ms = 1234; report.window_type = WindowType::kSystemWebApp; + report.source_system = JavaScriptErrorReport::SourceSystem::kWebUIObserver; SendErrorReport(std::move(report)); EXPECT_TRUE(finish_callback_was_called_); @@ -186,6 +188,7 @@ // This is from MockChromeJsErrorReportProcessor::GetOsVersion() EXPECT_THAT(actual_report->query, HasSubstr("os_version=7.20.1")); #endif + EXPECT_THAT(actual_report->query, HasSubstr("source_system=webui_observer")); // These are from MockCrashEndpoint::Client::GetProductNameAndVersion, which // is only defined for non-MAC POSIX systems. TODO(https://crbug.com/1121816): // Get this info for non-POSIX platforms.
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc index b785336..a573fa95 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -68,6 +68,7 @@ #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.h" #include "chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.h" #include "chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.h" @@ -321,6 +322,24 @@ return std::make_unique<ChromeDevicePermissionsPrompt>(web_contents); } +#if BUILDFLAG(IS_CHROMEOS_ASH) +bool ChromeExtensionsAPIClient::ShouldAllowDetachingUsb(int vid, + int pid) const { + const base::ListValue* policy_list; + if (chromeos::CrosSettings::Get()->GetList(chromeos::kUsbDetachableAllowlist, + &policy_list)) { + for (const auto& entry : *policy_list) { + if (entry.FindIntKey(chromeos::kUsbDetachableAllowlistKeyVid) == vid && + entry.FindIntKey(chromeos::kUsbDetachableAllowlistKeyPid) == pid) { + return true; + } + } + } + + return false; +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + std::unique_ptr<VirtualKeyboardDelegate> ChromeExtensionsAPIClient::CreateVirtualKeyboardDelegate( content::BrowserContext* browser_context) const {
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chrome/browser/extensions/api/chrome_extensions_api_client.h index dd7459b..ae948f3 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.h +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.h
@@ -65,6 +65,9 @@ RulesCacheDelegate* cache_delegate) const override; std::unique_ptr<DevicePermissionsPrompt> CreateDevicePermissionsPrompt( content::WebContents* web_contents) const override; +#if BUILDFLAG(IS_CHROMEOS_ASH) + bool ShouldAllowDetachingUsb(int vid, int pid) const override; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate( content::BrowserContext* browser_context) const override; ManagementAPIDelegate* CreateManagementAPIDelegate() const override;
diff --git a/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc b/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc index 4bc657f..bbc2c3d8 100644 --- a/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc +++ b/chrome/browser/extensions/api/crash_report_private/crash_report_private_api.cc
@@ -59,6 +59,8 @@ JavaScriptErrorReport error_report; error_report.message = std::move(params->info.message); error_report.url = std::move(params->info.url); + error_report.source_system = + JavaScriptErrorReport::SourceSystem::kCrashReportApi; if (params->info.product) { error_report.product = std::move(*params->info.product); }
diff --git a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc index 04d813e..56d864f 100644 --- a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc +++ b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
@@ -120,7 +120,8 @@ "version=1.2.3.4&channel=Stable&" "error_message=hi&full_url=http%3A%2F%2Fwww.test.com%2F&" "os=ChromeOS" - "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&src=" + "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&" + "source_system=crash_report_api&src=" "http%3A%2F%2Fwww.test." "com%2F&type=JavascriptError&url=%2F&ver=1.2.3.4")); EXPECT_EQ(report->content, ""); @@ -154,6 +155,7 @@ "&line=123&os=ChromeOS" "&prod=Chrome%2520\\(Chrome%2520OS\\)&renderer_process_" "uptime_ms=\\d+&" + "source_system=crash_report_api&" "src=http%3A%2F%2Fwww.test.com%2Ffoo&" "type=JavascriptError&url=%2Ffoo&ver=1.0.0.0")); EXPECT_EQ(report->content, " at <anonymous>:1:1"); @@ -183,7 +185,8 @@ "3.4&channel=Stable&column=456&" "error_message=hi&full_url=http%3A%2F%2Fwww.test.com%2Ffoo&" "line=123&os=ChromeOS" - "&prod=TestApp&renderer_process_uptime_ms=\\d+&src=http%3A%" + "&prod=TestApp&renderer_process_uptime_ms=\\d+&" + "source_system=crash_report_api&src=http%3A%" "2F%2Fwww.test.com%2Ffoo&type=" "JavascriptError&url=%2Ffoo&ver=1.0.0.0")); EXPECT_EQ(report->content, ""); @@ -215,7 +218,8 @@ "3.4&channel=Stable&column=456&" "error_message=%5BMAC%20OUI%3D06%3A00%3A00%20IFACE%3D1%5D&" "full_url=http%3A%2F%2Fwww.test.com%2Ffoo&line=123&os=ChromeOS" - "&prod=TestApp&renderer_process_uptime_ms=\\d+&src=http%3A%2F%2Fwww." + "&prod=TestApp&renderer_process_uptime_ms=\\d+&" + "source_system=crash_report_api&src=http%3A%2F%2Fwww." "test.com%2Ffoo&type=" "JavascriptError&url=%2Ffoo&ver=1.0.0.0")); EXPECT_EQ(report->content, ""); @@ -285,7 +289,8 @@ "version=1.2.3.4&channel=Stable&" "error_message=hi&full_url=http%3A%2F%2Fwww.test.com%2F&" "os=ChromeOS" - "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&src=" + "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&" + "source_system=crash_report_api&src=" "http%3A%2F%2Fwww.test." "com%2F&type=JavascriptError&url=%2F&ver=1.2.3.4&window_" "type=REGULAR_TABBED")); @@ -335,7 +340,8 @@ "version=1.2.3.4&channel=Stable&" "error_message=hi&full_url=http%3A%2F%2Fwww.test.com%2F&" "os=ChromeOS" - "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&src=" + "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&" + "source_system=crash_report_api&src=" "http%3A%2F%2Fwww.test." "com%2F&type=JavascriptError&url=%2F&ver=1.2.3.4&window_" "type=WEB_APP")); @@ -369,7 +375,8 @@ "version=1.2.3.4&channel=Stable&" "error_message=hi&full_url=http%3A%2F%2Fwww.test.com%2F&" "os=ChromeOS" - "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&src=" + "&prod=Chrome_ChromeOS&renderer_process_uptime_ms=\\d+&" + "source_system=crash_report_api&src=" "http%3A%2F%2Fwww.test." "com%2F&type=JavascriptError&url=%2F&ver=1.2.3.4&window_" "type=SYSTEM_WEB_APP"));
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index 3ef5c9b..f24d3b5 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -407,14 +407,9 @@ } void ComponentLoader::AddChromeCameraApp() { - // TODO(crbug.com/1135280): Remove all the logic here once CCA is fully - // migrated to SWA. - - // If users should use the SWA version of CCA and the status from the platform - // app version is already migrated, there is no need to install the platform - // version of CCA. - if (base::FeatureList::IsEnabled(chromeos::features::kCameraSystemWebApp) && - profile_->GetPrefs()->GetBoolean( + // Only adding the Chrome App version of camera app for migration purpose. + // We should remove this method totally after a few milestones. + if (profile_->GetPrefs()->GetBoolean( chromeos::prefs::kHasCameraAppMigratedToSWA)) { return; }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 18e164d3..28a5fef 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -141,8 +141,8 @@ }, { "name": "arc-custom-tabs-experiment", - "owners": [ "hashimoto" ], - "expiry_milestone": 76 + "owners": [ "hashimoto", "jschettler" ], + "expiry_milestone": 95 }, { "name": "arc-documents-provider", @@ -3458,17 +3458,17 @@ { "name": "nearby-sharing", "owners": [ "vecore@google.com", "cros-system-services@google.com", "cross-device-team@google.com" ], - "expiry_milestone": 90 + "expiry_milestone": 95 }, { "name": "nearby-sharing-device-contacts", "owners": [ "vecore@google.com", "cros-system-services@google.com", "cross-device-team@google.com" ], - "expiry_milestone": 90 + "expiry_milestone": 95 }, { "name": "nearby-sharing-webrtc", "owners": [ "vecore@google.com", "cros-system-services@google.com", "cross-device-team@google.com" ], - "expiry_milestone": 90 + "expiry_milestone": 95 }, { "name": "new-canvas-2d-api",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index e46f755..74b2d6e9 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3839,10 +3839,6 @@ "or fully launched. Only on the few models that Bluetooth WBS is " "still stablizing this flag will take effect."; -const char kCameraSystemWebAppName[] = "Camera System Web App"; -const char kCameraSystemWebAppDescription[] = - "Run the Chrome Camera App as a System Web App."; - const char kDeprecateLowUsageCodecsName[] = "Deprecates low usage media codecs"; const char kDeprecateLowUsageCodecsDescription[] = "Deprecates low usage codecs. Disable this feature to allow playback of "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 8afa4ab3..7865627 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2215,9 +2215,6 @@ extern const char kBluetoothWbsDogfoodName[]; extern const char kBluetoothWbsDogfoodDescription[]; -extern const char kCameraSystemWebAppName[]; -extern const char kCameraSystemWebAppDescription[]; - extern const char kDeprecateLowUsageCodecsName[]; extern const char kDeprecateLowUsageCodecsDescription[];
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc index ff00671..03292e2 100644 --- a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc +++ b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.cc
@@ -135,14 +135,15 @@ const bool read_only, const uint32_t parent_id, const std::string& directory_name, - const MTPDeviceTaskHelper::CreateDirectorySuccessCallback& success_callback, + MTPDeviceTaskHelper::CreateDirectorySuccessCallback success_callback, MTPDeviceTaskHelper::ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); MTPDeviceTaskHelper* task_helper = GetDeviceTaskHelperForStorage(storage_name, read_only); if (!task_helper) return; - task_helper->CreateDirectory(parent_id, directory_name, success_callback, + task_helper->CreateDirectory(parent_id, directory_name, + std::move(success_callback), std::move(error_callback)); } @@ -160,14 +161,14 @@ const std::string& storage_name, const bool read_only, const uint32_t directory_id, - const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, + MTPDeviceTaskHelper::ReadDirectorySuccessCallback success_callback, MTPDeviceTaskHelper::ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); MTPDeviceTaskHelper* task_helper = GetDeviceTaskHelperForStorage(storage_name, read_only); if (!task_helper) return; - task_helper->ReadDirectory(directory_id, success_callback, + task_helper->ReadDirectory(directory_id, std::move(success_callback), std::move(error_callback)); } @@ -279,14 +280,14 @@ const bool read_only, const uint32_t object_id, const std::string& new_name, - const MTPDeviceTaskHelper::RenameObjectSuccessCallback& success_callback, + MTPDeviceTaskHelper::RenameObjectSuccessCallback success_callback, MTPDeviceTaskHelper::ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); MTPDeviceTaskHelper* task_helper = GetDeviceTaskHelperForStorage(storage_name, read_only); if (!task_helper) return; - task_helper->RenameObject(object_id, new_name, success_callback, + task_helper->RenameObject(object_id, new_name, std::move(success_callback), std::move(error_callback)); } @@ -307,17 +308,16 @@ const int source_file_descriptor, const uint32_t parent_id, const std::string& file_name, - const MTPDeviceTaskHelper::CopyFileFromLocalSuccessCallback& - success_callback, + MTPDeviceTaskHelper::CopyFileFromLocalSuccessCallback success_callback, MTPDeviceTaskHelper::ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); MTPDeviceTaskHelper* task_helper = GetDeviceTaskHelperForStorage(storage_name, read_only); if (!task_helper) return; - task_helper->CopyFileFromLocal(storage_name, source_file_descriptor, - parent_id, file_name, success_callback, - std::move(error_callback)); + task_helper->CopyFileFromLocal( + storage_name, source_file_descriptor, parent_id, file_name, + std::move(success_callback), std::move(error_callback)); } // Deletes |object_id|. @@ -334,7 +334,7 @@ const std::string storage_name, const bool read_only, const uint32_t object_id, - const MTPDeviceTaskHelper::DeleteObjectSuccessCallback success_callback, + const MTPDeviceTaskHelper::DeleteObjectSuccessCallback& success_callback, MTPDeviceTaskHelper::ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); MTPDeviceTaskHelper* task_helper = @@ -562,7 +562,7 @@ const base::FilePath& directory_path, const bool exclusive, const bool recursive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!directory_path.empty()); @@ -588,7 +588,7 @@ base::OnceClosure closure = base::BindOnce(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal, weak_ptr_factory_.GetWeakPtr(), components, exclusive, - success_callback, std::move(error_callback)); + std::move(success_callback), std::move(error_callback)); EnsureInitAndRunTask(PendingTaskInfo(directory_path, content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -621,14 +621,14 @@ void MTPDeviceDelegateImplLinux::ReadDirectory( const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!root.empty()); base::OnceClosure closure = base::BindOnce(&MTPDeviceDelegateImplLinux::ReadDirectoryInternal, - weak_ptr_factory_.GetWeakPtr(), root, success_callback, - std::move(error_callback)); + weak_ptr_factory_.GetWeakPtr(), root, + std::move(success_callback), std::move(error_callback)); EnsureInitAndRunTask(PendingTaskInfo(root, content::BrowserThread::IO, FROM_HERE, std::move(closure))); } @@ -636,15 +636,15 @@ void MTPDeviceDelegateImplLinux::CreateSnapshotFile( const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!device_file_path.empty()); DCHECK(!local_path.empty()); - base::OnceClosure closure = - base::BindOnce(&MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal, - weak_ptr_factory_.GetWeakPtr(), device_file_path, - local_path, success_callback, std::move(error_callback)); + base::OnceClosure closure = base::BindOnce( + &MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal, + weak_ptr_factory_.GetWeakPtr(), device_file_path, local_path, + std::move(success_callback), std::move(error_callback)); EnsureInitAndRunTask(PendingTaskInfo(device_file_path, content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -681,7 +681,7 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!source_file_path.empty()); @@ -696,14 +696,15 @@ base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidCreateTemporaryFileToCopyFileLocal, weak_ptr_factory_.GetWeakPtr(), source_file_path, device_file_path, - progress_callback, success_callback, std::move(error_callback))); + progress_callback, std::move(success_callback), + std::move(error_callback))); } void MTPDeviceDelegateImplLinux::MoveFileLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!source_file_path.empty()); @@ -711,10 +712,11 @@ auto repeating_error = MakeErrorCallbackRepeating(std::move(error_callback)); // Get file info to move file on local. - GetFileInfoSuccessCallback success_callback_wrapper = base::BindOnce( - &MTPDeviceDelegateImplLinux::MoveFileLocalInternal, - weak_ptr_factory_.GetWeakPtr(), source_file_path, device_file_path, - create_temporary_file_callback, success_callback, repeating_error); + GetFileInfoSuccessCallback success_callback_wrapper = + base::BindOnce(&MTPDeviceDelegateImplLinux::MoveFileLocalInternal, + weak_ptr_factory_.GetWeakPtr(), source_file_path, + device_file_path, create_temporary_file_callback, + std::move(success_callback), repeating_error); base::OnceClosure closure = base::BindOnce(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, weak_ptr_factory_.GetWeakPtr(), source_file_path, @@ -727,7 +729,7 @@ void MTPDeviceDelegateImplLinux::CopyFileFromLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!source_file_path.empty()); @@ -742,7 +744,7 @@ ErrorCallback error_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::OnGetDestFileInfoErrorToCopyFileFromLocal, weak_ptr_factory_.GetWeakPtr(), source_file_path, device_file_path, - success_callback, repeating_error); + std::move(success_callback), repeating_error); base::OnceClosure closure = base::BindOnce( &MTPDeviceDelegateImplLinux::GetFileInfoInternal, weak_ptr_factory_.GetWeakPtr(), device_file_path, @@ -754,7 +756,7 @@ void MTPDeviceDelegateImplLinux::DeleteFile( const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!file_path.empty()); @@ -763,7 +765,7 @@ GetFileInfoSuccessCallback success_callback_wrapper = base::BindOnce(&MTPDeviceDelegateImplLinux::DeleteFileInternal, weak_ptr_factory_.GetWeakPtr(), file_path, - success_callback, repeating_error); + std::move(success_callback), repeating_error); base::OnceClosure closure = base::BindOnce(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, @@ -775,7 +777,7 @@ void MTPDeviceDelegateImplLinux::DeleteDirectory( const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!file_path.empty()); @@ -784,7 +786,7 @@ GetFileInfoSuccessCallback success_callback_wrapper = base::BindOnce(&MTPDeviceDelegateImplLinux::DeleteDirectoryInternal, weak_ptr_factory_.GetWeakPtr(), file_path, - success_callback, repeating_error); + std::move(success_callback), repeating_error); base::OnceClosure closure = base::BindOnce(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, @@ -902,7 +904,7 @@ void MTPDeviceDelegateImplLinux::CreateDirectoryInternal( const std::vector<base::FilePath>& components, const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -919,7 +921,7 @@ base::OnceClosure closure = base::BindOnce( &MTPDeviceDelegateImplLinux::CreateSingleDirectory, weak_ptr_factory_.GetWeakPtr(), current_component, exclusive, - success_callback, std::move(error_callback)); + std::move(success_callback), std::move(error_callback)); EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -935,7 +937,7 @@ base::OnceClosure closure = base::BindOnce( &MTPDeviceDelegateImplLinux::CreateDirectoryInternal, weak_ptr_factory_.GetWeakPtr(), other_components, exclusive, - success_callback, std::move(error_callback)); + std::move(success_callback), std::move(error_callback)); EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -943,23 +945,22 @@ auto repeating_error = MakeErrorCallbackRepeating(std::move(error_callback)); // If parent directory |current_component| does not exist, create it. - const CreateDirectorySuccessCallback success_callback_wrapper = - base::Bind(&MTPDeviceDelegateImplLinux:: - OnDidCreateParentDirectoryToCreateDirectory, - weak_ptr_factory_.GetWeakPtr(), current_component, - other_components, exclusive, success_callback, - repeating_error); + CreateDirectorySuccessCallback success_callback_wrapper = base::BindOnce( + &MTPDeviceDelegateImplLinux:: + OnDidCreateParentDirectoryToCreateDirectory, + weak_ptr_factory_.GetWeakPtr(), current_component, other_components, + exclusive, std::move(success_callback), repeating_error); // Wraps error callback to return all errors of creating parent // directories as FILE_ERROR_FAILED. ErrorCallback error_callback_wrapper = base::BindOnce(&MTPDeviceDelegateImplLinux:: OnCreateParentDirectoryErrorToCreateDirectory, weak_ptr_factory_.GetWeakPtr(), repeating_error); - base::OnceClosure closure = - base::BindOnce(&MTPDeviceDelegateImplLinux::CreateSingleDirectory, - weak_ptr_factory_.GetWeakPtr(), current_component, - false /* not exclusive */, success_callback_wrapper, - std::move(error_callback_wrapper)); + base::OnceClosure closure = base::BindOnce( + &MTPDeviceDelegateImplLinux::CreateSingleDirectory, + weak_ptr_factory_.GetWeakPtr(), current_component, + false /* not exclusive */, std::move(success_callback_wrapper), + std::move(error_callback_wrapper)); EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -971,7 +972,7 @@ void MTPDeviceDelegateImplLinux::ReadDirectoryInternal( const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(task_in_progress_); @@ -987,7 +988,7 @@ GetFileInfoSuccessCallback success_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory, - weak_ptr_factory_.GetWeakPtr(), *dir_id, success_callback, + weak_ptr_factory_.GetWeakPtr(), *dir_id, std::move(success_callback), repeating_error); ErrorCallback error_callback_wrapper = base::BindOnce(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, @@ -1002,7 +1003,7 @@ void MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal( const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1011,7 +1012,7 @@ auto repeating_error = MakeErrorCallbackRepeating(std::move(error_callback)); auto request_info = std::make_unique<SnapshotRequestInfo>( - *file_id, local_path, success_callback, repeating_error); + *file_id, local_path, std::move(success_callback), repeating_error); GetFileInfoSuccessCallback success_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile, weak_ptr_factory_.GetWeakPtr(), base::Passed(&request_info)); @@ -1065,7 +1066,7 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& source_file_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1080,9 +1081,9 @@ base::Optional<uint32_t> file_id = CachedPathToId(source_file_path); if (file_id) { const MTPDeviceTaskHelper::RenameObjectSuccessCallback - success_callback_wrapper = base::Bind( + success_callback_wrapper = base::BindRepeating( &MTPDeviceDelegateImplLinux::OnDidMoveFileLocalWithRename, - weak_ptr_factory_.GetWeakPtr(), success_callback, + weak_ptr_factory_.GetWeakPtr(), base::Passed(&success_callback), source_file_path, *file_id); MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = base::BindOnce(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, @@ -1104,20 +1105,20 @@ auto repeating_error = MakeErrorCallbackRepeating(std::move(error_callback)); // If a file is moved to a different directory, create a copy to the // destination path, and remove source file. - const CopyFileLocalSuccessCallback& success_callback_wrapper = - base::Bind(&MTPDeviceDelegateImplLinux::DeleteFileInternal, - weak_ptr_factory_.GetWeakPtr(), source_file_path, - success_callback, repeating_error, source_file_info); + CopyFileLocalSuccessCallback success_callback_wrapper = base::BindOnce( + &MTPDeviceDelegateImplLinux::DeleteFileInternal, + weak_ptr_factory_.GetWeakPtr(), source_file_path, + std::move(success_callback), repeating_error, source_file_info); // TODO(yawano): Avoid to call external method from internal code. CopyFileLocal(source_file_path, device_file_path, create_temporary_file_callback, base::Bind(&FakeCopyFileProgressCallback), - success_callback_wrapper, repeating_error); + std::move(success_callback_wrapper), repeating_error); } void MTPDeviceDelegateImplLinux::OnDidOpenFDToCopyFileFromLocal( const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback, const std::pair<int, base::File::Error>& open_fd_result) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1137,10 +1138,11 @@ return; } - CopyFileFromLocalSuccessCallback success_callback_wrapper = - base::Bind(&MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal, - weak_ptr_factory_.GetWeakPtr(), success_callback, - device_file_path, source_file_descriptor); + MTPDeviceTaskHelper::CopyFileFromLocalSuccessCallback + success_callback_wrapper = base::BindRepeating( + &MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal, + weak_ptr_factory_.GetWeakPtr(), base::Passed(&success_callback), + device_file_path, source_file_descriptor); ErrorCallback error_callback_wrapper = base::BindOnce(&MTPDeviceDelegateImplLinux::HandleCopyFileFromLocalError, @@ -1159,7 +1161,7 @@ void MTPDeviceDelegateImplLinux::DeleteFileInternal( const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1175,13 +1177,13 @@ return; } - RunDeleteObjectOnUIThread(file_path, *file_id, success_callback, + RunDeleteObjectOnUIThread(file_path, *file_id, std::move(success_callback), std::move(error_callback)); } void MTPDeviceDelegateImplLinux::DeleteDirectoryInternal( const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1211,18 +1213,17 @@ // Since the directory can contain a file even if the cache returns it as // empty, explicitly check the directory and confirm it is actually empty. MTPDeviceTaskHelper::CheckDirectoryEmptySuccessCallback - success_callback_wrapper = - base::BindOnce(&MTPDeviceDelegateImplLinux:: - OnDidCheckDirectoryEmptyToDeleteDirectory, - weak_ptr_factory_.GetWeakPtr(), file_path, - *directory_id, success_callback, repeating_error); + success_callback_wrapper = base::BindOnce( + &MTPDeviceDelegateImplLinux:: + OnDidCheckDirectoryEmptyToDeleteDirectory, + weak_ptr_factory_.GetWeakPtr(), file_path, *directory_id, + std::move(success_callback), repeating_error); MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::HandleDeviceFileError, weak_ptr_factory_.GetWeakPtr(), repeating_error, *directory_id); - base::OnceClosure closure = - base::BindOnce(&CheckDirectoryEmptyOnUIThread, storage_name_, read_only_, - *directory_id, base::Passed(&success_callback_wrapper), - std::move(error_callback_wrapper)); + base::OnceClosure closure = base::BindOnce( + &CheckDirectoryEmptyOnUIThread, storage_name_, read_only_, *directory_id, + std::move(success_callback_wrapper), std::move(error_callback_wrapper)); EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), content::BrowserThread::UI, FROM_HERE, std::move(closure))); @@ -1231,19 +1232,22 @@ void MTPDeviceDelegateImplLinux::CreateSingleDirectory( const base::FilePath& directory_path, const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); auto repeating_error = MakeErrorCallbackRepeating(std::move(error_callback)); + auto repeating_success = base::BindRepeating( + [](base::OnceClosure closure) { std::move(closure).Run(); }, + base::Passed(&success_callback)); GetFileInfoSuccessCallback success_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::OnPathAlreadyExistsForCreateSingleDirectory, - weak_ptr_factory_.GetWeakPtr(), exclusive, success_callback, + weak_ptr_factory_.GetWeakPtr(), exclusive, repeating_success, repeating_error); ErrorCallback error_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::OnPathDoesNotExistForCreateSingleDirectory, - weak_ptr_factory_.GetWeakPtr(), directory_path, success_callback, + weak_ptr_factory_.GetWeakPtr(), directory_path, repeating_success, repeating_error); base::OnceClosure closure = base::BindOnce( &MTPDeviceDelegateImplLinux::GetFileInfoInternal, @@ -1258,7 +1262,7 @@ void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToCreateDirectory( const std::vector<base::FilePath>& components, const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback, storage::AsyncFileUtil::EntryList /* entries */, const bool has_more) { @@ -1270,7 +1274,7 @@ base::OnceClosure closure = base::BindOnce(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal, weak_ptr_factory_.GetWeakPtr(), components, exclusive, - success_callback, std::move(error_callback)); + std::move(success_callback), std::move(error_callback)); EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -1279,13 +1283,14 @@ void MTPDeviceDelegateImplLinux::OnDidCheckDirectoryEmptyToDeleteDirectory( const base::FilePath& directory_path, uint32_t directory_id, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback, bool is_empty) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); if (is_empty) { - RunDeleteObjectOnUIThread(directory_path, directory_id, success_callback, + RunDeleteObjectOnUIThread(directory_path, directory_id, + std::move(success_callback), std::move(error_callback)); } else { std::move(error_callback).Run(base::File::FILE_ERROR_NOT_EMPTY); @@ -1297,13 +1302,12 @@ void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread( const base::FilePath& object_path, const uint32_t object_id, - const DeleteObjectSuccessCallback& success_callback, + DeleteObjectSuccessCallback success_callback, ErrorCallback error_callback) { - const MTPDeviceTaskHelper::DeleteObjectSuccessCallback - success_callback_wrapper = - base::Bind(&MTPDeviceDelegateImplLinux::OnDidDeleteObject, - weak_ptr_factory_.GetWeakPtr(), object_path, object_id, - success_callback); + MTPDeviceTaskHelper::DeleteObjectSuccessCallback success_callback_wrapper = + base::BindRepeating(&MTPDeviceDelegateImplLinux::OnDidDeleteObject, + weak_ptr_factory_.GetWeakPtr(), object_path, + object_id, base::Passed(&success_callback)); MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError, @@ -1422,7 +1426,7 @@ void MTPDeviceDelegateImplLinux::OnPathAlreadyExistsForCreateSingleDirectory( const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1430,12 +1434,12 @@ if (!file_info.is_directory || exclusive) std::move(error_callback).Run(base::File::FILE_ERROR_EXISTS); else - success_callback.Run(); + std::move(success_callback).Run(); } void MTPDeviceDelegateImplLinux::OnPathDoesNotExistForCreateSingleDirectory( const base::FilePath& directory_path, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Error error) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1452,9 +1456,10 @@ } const MTPDeviceTaskHelper::CreateDirectorySuccessCallback - success_callback_wrapper = base::Bind( - &MTPDeviceDelegateImplLinux::OnDidCreateSingleDirectory, - weak_ptr_factory_.GetWeakPtr(), directory_path, success_callback); + success_callback_wrapper = + base::Bind(&MTPDeviceDelegateImplLinux::OnDidCreateSingleDirectory, + weak_ptr_factory_.GetWeakPtr(), directory_path, + base::Passed(&success_callback)); MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::HandleDeviceFileError, weak_ptr_factory_.GetWeakPtr(), std::move(error_callback), *parent_id); @@ -1469,7 +1474,7 @@ void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory( uint32_t dir_id, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1481,8 +1486,9 @@ base::OnceClosure task_closure = base::BindOnce( &ReadDirectoryOnUIThread, storage_name_, read_only_, dir_id, - base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadDirectory, - weak_ptr_factory_.GetWeakPtr(), dir_id, success_callback), + base::BindRepeating(&MTPDeviceDelegateImplLinux::OnDidReadDirectory, + weak_ptr_factory_.GetWeakPtr(), dir_id, + base::Passed(&success_callback)), base::BindOnce(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, weak_ptr_factory_.GetWeakPtr(), std::move(error_callback), dir_id)); @@ -1538,7 +1544,7 @@ void MTPDeviceDelegateImplLinux::OnGetDestFileInfoErrorToCopyFileFromLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Error error) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1553,16 +1559,16 @@ base::BindOnce(&OpenFileDescriptor, source_file_path, O_RDONLY), base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidOpenFDToCopyFileFromLocal, - weak_ptr_factory_.GetWeakPtr(), device_file_path, success_callback, - std::move(error_callback))); + weak_ptr_factory_.GetWeakPtr(), device_file_path, + std::move(success_callback), std::move(error_callback))); } void MTPDeviceDelegateImplLinux::OnDidCreateSingleDirectory( const base::FilePath& directory_path, - const CreateDirectorySuccessCallback& success_callback) { + CreateDirectorySuccessCallback success_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - success_callback.Run(); + std::move(success_callback).Run(); NotifyFileChange(directory_path.DirName(), storage::WatcherManager::ChangeType::CHANGED); PendingRequestDone(); @@ -1572,7 +1578,7 @@ const base::FilePath& created_directory, const std::vector<base::FilePath>& components, const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1580,14 +1586,14 @@ // Calls ReadDirectoryInternal to fill the cache for created directory. // Calls ReadDirectoryInternal in this method to call it via // EnsureInitAndRunTask. - const ReadDirectorySuccessCallback& success_callback_wrapper = base::Bind( + ReadDirectorySuccessCallback success_callback_wrapper = base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidReadDirectoryToCreateDirectory, - weak_ptr_factory_.GetWeakPtr(), components, exclusive, success_callback, - repeating_error); + weak_ptr_factory_.GetWeakPtr(), components, exclusive, + std::move(success_callback), repeating_error); base::OnceClosure closure = base::BindOnce( &MTPDeviceDelegateImplLinux::ReadDirectoryInternal, weak_ptr_factory_.GetWeakPtr(), created_directory.DirName(), - success_callback_wrapper, repeating_error); + std::move(success_callback_wrapper), repeating_error); EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), content::BrowserThread::IO, FROM_HERE, std::move(closure))); @@ -1603,7 +1609,7 @@ void MTPDeviceDelegateImplLinux::OnDidReadDirectory( uint32_t dir_id, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, const MTPDeviceTaskHelper::MTPEntries& mtp_entries, bool has_more) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1640,7 +1646,7 @@ file_info_cache_[dir_path.Append(entry.name)] = mtp_entry; } - success_callback.Run(file_list, has_more); + std::move(success_callback).Run(file_list, has_more); if (has_more) return; // Wait to be called again. @@ -1657,8 +1663,8 @@ const base::FilePath& snapshot_file_path) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(current_snapshot_request_info_.get()); - current_snapshot_request_info_->success_callback.Run( - file_info, snapshot_file_path); + std::move(current_snapshot_request_info_->success_callback) + .Run(file_info, snapshot_file_path); current_snapshot_request_info_.reset(); PendingRequestDone(); } @@ -1705,7 +1711,7 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::FilePath& temporary_file_path) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1718,10 +1724,10 @@ auto repeating_error = MakeErrorCallbackRepeating(std::move(error_callback)); CreateSnapshotFile( source_file_path, temporary_file_path, - base::BindRepeating( + base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidCreateSnapshotFileOfCopyFileLocal, weak_ptr_factory_.GetWeakPtr(), device_file_path, progress_callback, - success_callback, repeating_error), + base::Passed(&success_callback), repeating_error), base::BindOnce(&MTPDeviceDelegateImplLinux::HandleCopyFileLocalError, weak_ptr_factory_.GetWeakPtr(), repeating_error, temporary_file_path)); @@ -1730,7 +1736,7 @@ void MTPDeviceDelegateImplLinux::OnDidCreateSnapshotFileOfCopyFileLocal( const base::FilePath& device_file_path, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info, const base::FilePath& temporary_file_path) { @@ -1742,9 +1748,9 @@ // TODO(yawano): Avoid to call external method from internal code. CopyFileFromLocal( temporary_file_path, device_file_path, - base::Bind( + base::BindOnce( &MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocalOfCopyFileLocal, - weak_ptr_factory_.GetWeakPtr(), success_callback, + weak_ptr_factory_.GetWeakPtr(), base::Passed(&success_callback), temporary_file_path), base::BindOnce(&MTPDeviceDelegateImplLinux::HandleCopyFileLocalError, weak_ptr_factory_.GetWeakPtr(), std::move(error_callback), @@ -1752,22 +1758,22 @@ } void MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocalOfCopyFileLocal( - const CopyFileFromLocalSuccessCallback success_callback, + CopyFileFromLocalSuccessCallback success_callback, const base::FilePath& temporary_file_path) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DeleteTemporaryFile(temporary_file_path); - success_callback.Run(); + std::move(success_callback).Run(); } void MTPDeviceDelegateImplLinux::OnDidMoveFileLocalWithRename( - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, const base::FilePath& source_file_path, const uint32_t file_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); EvictCachedPathToId(file_id); - success_callback.Run(); + std::move(success_callback).Run(); NotifyFileChange(source_file_path, storage::WatcherManager::ChangeType::DELETED); NotifyFileChange(source_file_path.DirName(), @@ -1776,7 +1782,7 @@ } void MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal( - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, const base::FilePath& file_path, const int source_file_descriptor) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1787,7 +1793,7 @@ base::ThreadPool::PostTask( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, closure); - success_callback.Run(); + std::move(success_callback).Run(); NotifyFileChange(file_path.DirName(), storage::WatcherManager::ChangeType::CHANGED); PendingRequestDone(); @@ -1822,11 +1828,11 @@ void MTPDeviceDelegateImplLinux::OnDidDeleteObject( const base::FilePath& object_path, const uint32_t object_id, - const DeleteObjectSuccessCallback success_callback) { + DeleteObjectSuccessCallback success_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); EvictCachedPathToId(object_id); - success_callback.Run(); + std::move(success_callback).Run(); NotifyFileChange(object_path, storage::WatcherManager::ChangeType::DELETED); NotifyFileChange(object_path.DirName(), storage::WatcherManager::ChangeType::CHANGED); @@ -1892,13 +1898,12 @@ DCHECK(task_in_progress_); ReadDirectorySuccessCallback success_callback = - base::Bind(&MTPDeviceDelegateImplLinux::OnDidFillFileCache, - weak_ptr_factory_.GetWeakPtr(), - uncached_path); + base::BindOnce(&MTPDeviceDelegateImplLinux::OnDidFillFileCache, + weak_ptr_factory_.GetWeakPtr(), uncached_path); ErrorCallback error_callback = base::BindOnce(&MTPDeviceDelegateImplLinux::OnFillFileCacheFailed, weak_ptr_factory_.GetWeakPtr()); - ReadDirectoryInternal(uncached_path, success_callback, + ReadDirectoryInternal(uncached_path, std::move(success_callback), std::move(error_callback)); }
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h index f31bbac9..9deed73 100644 --- a/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h +++ b/chrome/browser/media_galleries/chromeos/mtp_device_delegate_impl_chromeos.h
@@ -71,7 +71,7 @@ // Maps file paths to file info. typedef std::map<base::FilePath, MTPDeviceTaskHelper::MTPEntry> FileInfoCache; - typedef base::Closure DeleteObjectSuccessCallback; + using DeleteObjectSuccessCallback = base::OnceClosure; // Should only be called by CreateMTPDeviceAsyncDelegate() factory call. // Defer the device initializations until the first file operation request. @@ -89,16 +89,15 @@ void CreateDirectory(const base::FilePath& directory_path, const bool exclusive, const bool recursive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; void ReadDirectory(const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; - void CreateSnapshotFile( - const base::FilePath& device_file_path, - const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, - ErrorCallback error_callback) override; + void CreateSnapshotFile(const base::FilePath& device_file_path, + const base::FilePath& local_path, + CreateSnapshotFileSuccessCallback success_callback, + ErrorCallback error_callback) override; bool IsStreaming() override; void ReadBytes(const base::FilePath& device_file_path, const scoped_refptr<net::IOBuffer>& buf, @@ -112,24 +111,23 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) override; void MoveFileLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) override; - void CopyFileFromLocal( - const base::FilePath& source_file_path, - const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, - ErrorCallback error_callback) override; + void CopyFileFromLocal(const base::FilePath& source_file_path, + const base::FilePath& device_file_path, + CopyFileFromLocalSuccessCallback success_callback, + ErrorCallback error_callback) override; void DeleteFile(const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) override; void DeleteDirectory(const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; void AddWatcher(const GURL& origin, const base::FilePath& file_path, @@ -148,19 +146,17 @@ void GetFileInfoInternal(const base::FilePath& file_path, GetFileInfoSuccessCallback success_callback, ErrorCallback error_callback); - void CreateDirectoryInternal( - const std::vector<base::FilePath>& components, - const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, - ErrorCallback error_callback); - void ReadDirectoryInternal( - const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, - ErrorCallback error_callback); + void CreateDirectoryInternal(const std::vector<base::FilePath>& components, + const bool exclusive, + CreateDirectorySuccessCallback success_callback, + ErrorCallback error_callback); + void ReadDirectoryInternal(const base::FilePath& root, + ReadDirectorySuccessCallback success_callback, + ErrorCallback error_callback); void CreateSnapshotFileInternal( const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback); void ReadBytesInternal(const base::FilePath& device_file_path, net::IOBuffer* buf, @@ -172,38 +168,36 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& source_file_info); void OnDidOpenFDToCopyFileFromLocal( const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback, const std::pair<int, base::File::Error>& open_fd_result); void DeleteFileInternal(const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info); - void DeleteDirectoryInternal( - const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, - ErrorCallback error_callback, - const base::File::Info& file_info); + void DeleteDirectoryInternal(const base::FilePath& file_path, + DeleteDirectorySuccessCallback success_callback, + ErrorCallback error_callback, + const base::File::Info& file_info); // Creates a single directory to |directory_path|. The caller must ensure that // parent directory |directory_path.DirName()| already exists. - void CreateSingleDirectory( - const base::FilePath& directory_path, - const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, - ErrorCallback error_callback); + void CreateSingleDirectory(const base::FilePath& directory_path, + const bool exclusive, + CreateDirectorySuccessCallback success_callback, + ErrorCallback error_callback); // Called when ReadDirectoryInternal() completes for filling cache as part of // creating directories. void OnDidReadDirectoryToCreateDirectory( const std::vector<base::FilePath>& components, const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback, storage::AsyncFileUtil::EntryList entries, const bool has_more); @@ -212,16 +206,15 @@ void OnDidCheckDirectoryEmptyToDeleteDirectory( const base::FilePath& directory_path, uint32_t directory_id, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback, bool is_empty); // Calls DeleteObjectOnUIThread on UI thread. - void RunDeleteObjectOnUIThread( - const base::FilePath& object_path, - const uint32_t object_id, - const DeleteObjectSuccessCallback& success_callback, - ErrorCallback error_callback); + void RunDeleteObjectOnUIThread(const base::FilePath& object_path, + const uint32_t object_id, + DeleteObjectSuccessCallback success_callback, + ErrorCallback error_callback); // Notifies |chage_type| of |file_path| to watchers. void NotifyFileChange(const base::FilePath& file_path, @@ -270,7 +263,7 @@ // path already exists. void OnPathAlreadyExistsForCreateSingleDirectory( const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info); @@ -278,7 +271,7 @@ // already exists. void OnPathDoesNotExistForCreateSingleDirectory( const base::FilePath& directory_path, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Error error); @@ -293,7 +286,7 @@ // caller about the file error and process the next pending request. void OnDidGetFileInfoToReadDirectory( uint32_t dir_id, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info); @@ -318,14 +311,14 @@ void OnGetDestFileInfoErrorToCopyFileFromLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Error error); // Called when CreateSignleDirectory() succeeds. void OnDidCreateSingleDirectory( const base::FilePath& directory_path, - const CreateDirectorySuccessCallback& success_callback); + CreateDirectorySuccessCallback success_callback); // Called when parent directory |created_directory| is created as part of // CreateDirectory. @@ -333,7 +326,7 @@ const base::FilePath& created_directory, const std::vector<base::FilePath>& components, const bool exclusive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback); // Called when it failed to create a parent directory. For creating parent @@ -351,7 +344,7 @@ // |file_list| contains the directory file entries with their file ids. // |has_more| is true if there are more file entries to read. void OnDidReadDirectory(uint32_t dir_id, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, const MTPDeviceTaskHelper::MTPEntries& mtp_entries, bool has_more); @@ -394,7 +387,7 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::FilePath& temporary_file_path); @@ -402,27 +395,26 @@ void OnDidCreateSnapshotFileOfCopyFileLocal( const base::FilePath& device_file_path, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback, const base::File::Info& file_info, const base::FilePath& temporary_file_path); // Called when CopyFileFromLocal() succeeds for CopyFileLocal. void OnDidCopyFileFromLocalOfCopyFileLocal( - const CopyFileFromLocalSuccessCallback success_callback, + CopyFileFromLocalSuccessCallback success_callback, const base::FilePath& temporary_file_path); // Called when MoveFileLocal() succeeds with rename operation. void OnDidMoveFileLocalWithRename( - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, const base::FilePath& source_file_path, const uint32_t file_id); // Called when CopyFileFromLocal() succeeds. - void OnDidCopyFileFromLocal( - const CopyFileFromLocalSuccessCallback& success_callback, - const base::FilePath& file_path, - const int source_file_descriptor); + void OnDidCopyFileFromLocal(CopyFileFromLocalSuccessCallback success_callback, + const base::FilePath& file_path, + const int source_file_descriptor); // Called when CopyFileLocal() fails. void HandleCopyFileLocalError(ErrorCallback error_callback, @@ -437,7 +429,7 @@ // Called when DeleteObject() succeeds. void OnDidDeleteObject(const base::FilePath& object_path, const uint32_t object_id, - const DeleteObjectSuccessCallback success_callback); + DeleteObjectSuccessCallback success_callback); // Called when DeleteFileOrDirectory() fails. void HandleDeleteFileOrDirectoryError(ErrorCallback error_callback,
diff --git a/chrome/browser/media_galleries/chromeos/snapshot_file_details.cc b/chrome/browser/media_galleries/chromeos/snapshot_file_details.cc index 1daf0399..9665b152 100644 --- a/chrome/browser/media_galleries/chromeos/snapshot_file_details.cc +++ b/chrome/browser/media_galleries/chromeos/snapshot_file_details.cc
@@ -15,12 +15,11 @@ SnapshotRequestInfo::SnapshotRequestInfo( uint32_t file_id, const base::FilePath& snapshot_file_path, - const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback& - success_callback, + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback success_callback, MTPDeviceAsyncDelegate::ErrorCallback error_callback) : file_id(file_id), snapshot_file_path(snapshot_file_path), - success_callback(success_callback), + success_callback(std::move(success_callback)), error_callback(std::move(error_callback)) {} SnapshotRequestInfo::SnapshotRequestInfo(SnapshotRequestInfo&& other) = default;
diff --git a/chrome/browser/media_galleries/chromeos/snapshot_file_details.h b/chrome/browser/media_galleries/chromeos/snapshot_file_details.h index 9094b470..f5b31d7 100644 --- a/chrome/browser/media_galleries/chromeos/snapshot_file_details.h +++ b/chrome/browser/media_galleries/chromeos/snapshot_file_details.h
@@ -17,12 +17,11 @@ // Used to represent snapshot file request params. struct SnapshotRequestInfo { - SnapshotRequestInfo( - uint32_t file_id, - const base::FilePath& snapshot_file_path, - const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback& - success_callback, - MTPDeviceAsyncDelegate::ErrorCallback error_callback); + SnapshotRequestInfo(uint32_t file_id, + const base::FilePath& snapshot_file_path, + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback + success_callback, + MTPDeviceAsyncDelegate::ErrorCallback error_callback); SnapshotRequestInfo(SnapshotRequestInfo&& other); SnapshotRequestInfo(const SnapshotRequestInfo& other) = delete; SnapshotRequestInfo& operator=(const SnapshotRequestInfo& other) = delete; @@ -35,8 +34,7 @@ const base::FilePath snapshot_file_path; // A callback to be called when CreateSnapshotFile() succeeds. - const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback - success_callback; + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback success_callback; // A callback to be called when CreateSnapshotFile() fails. MTPDeviceAsyncDelegate::ErrorCallback error_callback; @@ -64,9 +62,8 @@ return file_info_; } - const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback - success_callback() const { - return request_info_.success_callback; + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback success_callback() { + return std::move(request_info_.success_callback); } MTPDeviceAsyncDelegate::ErrorCallback error_callback() {
diff --git a/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h b/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h index b9ed99f..c47d9e5 100644 --- a/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h +++ b/chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h
@@ -30,16 +30,16 @@ class MTPDeviceAsyncDelegate { public: // A callback to be called when GetFileInfo method call succeeds. - typedef base::OnceCallback<void(const base::File::Info& file_info)> - GetFileInfoSuccessCallback; + using GetFileInfoSuccessCallback = + base::OnceCallback<void(const base::File::Info& file_info)>; // A callback to be called when CreateDirectory method call succeeds. - typedef base::RepeatingClosure CreateDirectorySuccessCallback; + using CreateDirectorySuccessCallback = base::OnceClosure; // A callback to be called when ReadDirectory method call succeeds. - typedef base::RepeatingCallback< - void(storage::AsyncFileUtil::EntryList file_list, bool has_more)> - ReadDirectorySuccessCallback; + using ReadDirectorySuccessCallback = + base::OnceCallback<void(storage::AsyncFileUtil::EntryList file_list, + bool has_more)>; // A callback to be called when GetFileInfo/ReadDirectory/CreateSnapshot // method call fails. @@ -49,14 +49,14 @@ // TODO: consider make this a OnceCallback. Right now it is repeating because // it is used in SnapshotRequestInfo, which is owned by SnapshotFileDetails, // and SnapshotFileDetails needs const access to SnapshotRequestInfo. - typedef base::RepeatingCallback<void(const base::File::Info& file_info, - const base::FilePath& local_path)> - CreateSnapshotFileSuccessCallback; + using CreateSnapshotFileSuccessCallback = + base::OnceCallback<void(const base::File::Info& file_info, + const base::FilePath& local_path)>; // A callback to be called when ReadBytes method call succeeds. - typedef base::OnceCallback<void(const base::File::Info& file_info, - int bytes_read)> - ReadBytesSuccessCallback; + using ReadBytesSuccessCallback = + base::OnceCallback<void(const base::File::Info& file_info, + int bytes_read)>; struct ReadBytesRequest { ReadBytesRequest(uint32_t file_id, @@ -82,19 +82,19 @@ typedef base::Callback<base::FilePath()> CreateTemporaryFileCallback; // A callback to be called when CopyFileLocal method call succeeds. - typedef base::Closure CopyFileLocalSuccessCallback; + using CopyFileLocalSuccessCallback = base::OnceClosure; // A callback to be called when MoveFileLocal method call succeeds. - typedef base::Closure MoveFileLocalSuccessCallback; + using MoveFileLocalSuccessCallback = base::OnceClosure; // A callback to be called when CopyFileFromLocal method call succeeds. - typedef base::Closure CopyFileFromLocalSuccessCallback; + using CopyFileFromLocalSuccessCallback = base::OnceClosure; // A callback to be called when DeleteFile method call succeeds. - typedef base::Closure DeleteFileSuccessCallback; + using DeleteFileSuccessCallback = base::OnceClosure; // A callback to be called when DeleteDirectory method call succeeds. - typedef base::Closure DeleteDirectorySuccessCallback; + using DeleteDirectorySuccessCallback = base::OnceClosure; typedef storage::AsyncFileUtil::CopyFileProgressCallback CopyFileProgressCallback; @@ -109,26 +109,24 @@ // returns base::File::FILE_ERROR_EXISTS if a directory already exists for // |directory_path|. When |recursive| is true, the directory is created // recursively to |directory_path|. - virtual void CreateDirectory( - const base::FilePath& directory_path, - const bool exclusive, - const bool recursive, - const CreateDirectorySuccessCallback& success_callback, - ErrorCallback error_callback) = 0; + virtual void CreateDirectory(const base::FilePath& directory_path, + const bool exclusive, + const bool recursive, + CreateDirectorySuccessCallback success_callback, + ErrorCallback error_callback) = 0; // Enumerates the |root| directory contents and invokes the appropriate // callback asynchronously when complete. - virtual void ReadDirectory( - const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, - ErrorCallback error_callback) = 0; + virtual void ReadDirectory(const base::FilePath& root, + ReadDirectorySuccessCallback success_callback, + ErrorCallback error_callback) = 0; // Copy the contents of |device_file_path| to |local_path|. Invokes the // appropriate callback asynchronously when complete. virtual void CreateSnapshotFile( const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback) = 0; // Platform-specific implementations that are streaming don't create a local @@ -155,7 +153,7 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) = 0; // Moves a file |source_file_path| to |device_file_path|. @@ -164,26 +162,25 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) = 0; // Copies a file from |source_file_path| to |device_file_path|. virtual void CopyFileFromLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback) = 0; // Deletes a file at |file_path|. virtual void DeleteFile(const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) = 0; // Deletes a directory at |file_path|. The directory must be empty. - virtual void DeleteDirectory( - const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, - ErrorCallback error_callback) = 0; + virtual void DeleteDirectory(const base::FilePath& file_path, + DeleteDirectorySuccessCallback success_callback, + ErrorCallback error_callback) = 0; // Adds watcher to |file_path| as |origin|. virtual void AddWatcher(
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h index d0b58c83..5e973f6 100644 --- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h +++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h
@@ -42,20 +42,19 @@ void CreateDirectory(const base::FilePath& directory_path, const bool exclusive, const bool recursive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; // Note: passed absolute paths, but expects relative paths in reply. void ReadDirectory(const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; // Note: passed absolute paths. - void CreateSnapshotFile( - const base::FilePath& device_file_path, - const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, - ErrorCallback error_callback) override; + void CreateSnapshotFile(const base::FilePath& device_file_path, + const base::FilePath& local_path, + CreateSnapshotFileSuccessCallback success_callback, + ErrorCallback error_callback) override; bool IsStreaming() override; void ReadBytes(const base::FilePath& device_file_path, const scoped_refptr<net::IOBuffer>& buf, @@ -69,24 +68,23 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) override; void MoveFileLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) override; - void CopyFileFromLocal( - const base::FilePath& source_file_path, - const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, - ErrorCallback error_callback) override; + void CopyFileFromLocal(const base::FilePath& source_file_path, + const base::FilePath& device_file_path, + CopyFileFromLocalSuccessCallback success_callback, + ErrorCallback error_callback) override; void DeleteFile(const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) override; void DeleteDirectory(const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; void AddWatcher(const GURL& origin, const base::FilePath& file_path, @@ -125,13 +123,13 @@ // Delegate for ReadDirectory, called on the UI thread. void ReadDirectoryImpl(const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback); // Delegate for CreateSnapshotFile, called on the UI thread. void DownloadFile(const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback); // Public for closures; should not be called except by
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm index 2d05e34..5307755 100644 --- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm +++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm
@@ -180,31 +180,32 @@ const base::FilePath& directory_path, const bool exclusive, const bool recursive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } void MTPDeviceDelegateImplMac::ReadDirectory( const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) { content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&MTPDeviceDelegateImplMac::ReadDirectoryImpl, - base::Unretained(this), root, success_callback, - std::move(error_callback))); + FROM_HERE, + base::BindOnce(&MTPDeviceDelegateImplMac::ReadDirectoryImpl, + base::Unretained(this), root, std::move(success_callback), + std::move(error_callback))); } void MTPDeviceDelegateImplMac::CreateSnapshotFile( const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback) { content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&MTPDeviceDelegateImplMac::DownloadFile, base::Unretained(this), device_file_path, local_path, - success_callback, std::move(error_callback))); + std::move(success_callback), std::move(error_callback))); } bool MTPDeviceDelegateImplMac::IsStreaming() { @@ -230,7 +231,7 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } @@ -239,7 +240,7 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } @@ -247,21 +248,21 @@ void MTPDeviceDelegateImplMac::CopyFileFromLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } void MTPDeviceDelegateImplMac::DeleteFile( const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } void MTPDeviceDelegateImplMac::DeleteDirectory( const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } @@ -307,11 +308,11 @@ void MTPDeviceDelegateImplMac::ReadDirectoryImpl( const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - read_dir_transactions_.emplace_back(root, success_callback, + read_dir_transactions_.emplace_back(root, std::move(success_callback), std::move(error_callback)); if (received_all_files_) { @@ -346,7 +347,7 @@ void MTPDeviceDelegateImplMac::DownloadFile( const base::FilePath& device_file_path, const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -363,7 +364,7 @@ root_path_.AppendRelativePath(device_file_path, &relative_path); read_file_transactions_.emplace_back(relative_path.value(), local_path, - success_callback, + std::move(success_callback), std::move(error_callback)); camera_interface_->DownloadFile(relative_path.value(), local_path); @@ -472,7 +473,8 @@ if (found_path) { content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(iter->success_callback, entry_list, false)); + FROM_HERE, + base::BindOnce(std::move(iter->success_callback), entry_list, false)); } else { content::GetIOThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(iter->error_callback), @@ -520,8 +522,8 @@ base::File::Info info = file_info_[item_filename.value()]; content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(iter->success_callback, info, iter->snapshot_file)); + FROM_HERE, base::BindOnce(std::move(iter->success_callback), info, + iter->snapshot_file)); read_file_transactions_.erase(iter); } @@ -532,7 +534,7 @@ ErrorCallback error_cb) : request_file(file), snapshot_file(snapshot_filename), - success_callback(success_cb), + success_callback(std::move(success_cb)), error_callback(std::move(error_cb)) {} MTPDeviceDelegateImplMac::ReadFileRequest::ReadFileRequest() = default; @@ -543,7 +545,7 @@ ReadDirectorySuccessCallback success_cb, ErrorCallback error_cb) : directory(dir), - success_callback(success_cb), + success_callback(std::move(success_cb)), error_callback(std::move(error_cb)) {} MTPDeviceDelegateImplMac::ReadDirectoryRequest::~ReadDirectoryRequest() {}
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc index 5bfae66..6bca4a03 100644 --- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc +++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc
@@ -395,14 +395,14 @@ const base::FilePath& directory_path, const bool exclusive, const bool recursive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } void MTPDeviceDelegateImplWin::ReadDirectory( const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!root.empty()); @@ -413,21 +413,23 @@ base::BindOnce(&ReadDirectoryOnBlockingPoolThread, storage_device_info_, root, base::Unretained(entries)), base::BindOnce(&MTPDeviceDelegateImplWin::OnDidReadDirectory, - weak_ptr_factory_.GetWeakPtr(), success_callback, - std::move(error_callback), base::Owned(entries)))); + weak_ptr_factory_.GetWeakPtr(), + std::move(success_callback), std::move(error_callback), + base::Owned(entries)))); } void MTPDeviceDelegateImplWin::CreateSnapshotFile( const base::FilePath& device_file_path, const base::FilePath& snapshot_file_path, - const CreateSnapshotFileSuccessCallback& success_callback, + CreateSnapshotFileSuccessCallback success_callback, ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(!device_file_path.empty()); DCHECK(!snapshot_file_path.empty()); - std::unique_ptr<SnapshotFileDetails> file_details(new SnapshotFileDetails( - SnapshotRequestInfo(device_file_path, snapshot_file_path, - success_callback, std::move(error_callback)))); + std::unique_ptr<SnapshotFileDetails> file_details( + new SnapshotFileDetails(SnapshotRequestInfo( + device_file_path, snapshot_file_path, std::move(success_callback), + std::move(error_callback)))); // Passing a raw SnapshotFileDetails* to the blocking pool is safe, because // it is owned by |file_details| in the reply callback. EnsureInitAndRunTask(PendingTaskInfo( @@ -461,7 +463,7 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } @@ -470,7 +472,7 @@ const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } @@ -478,21 +480,21 @@ void MTPDeviceDelegateImplWin::CopyFileFromLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, + CopyFileFromLocalSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } void MTPDeviceDelegateImplWin::DeleteFile( const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } void MTPDeviceDelegateImplWin::DeleteDirectory( const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback) { NOTREACHED(); } @@ -606,14 +608,14 @@ } void MTPDeviceDelegateImplWin::OnDidReadDirectory( - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback, storage::AsyncFileUtil::EntryList* file_list, base::File::Error error) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(file_list); if (error == base::File::FILE_OK) - success_callback.Run(*file_list, false /*no more entries*/); + std::move(success_callback).Run(*file_list, false /*no more entries*/); else std::move(error_callback).Run(error); task_in_progress_ = false; @@ -672,9 +674,9 @@ return; } if (succeeded) { - current_snapshot_details_->request_info().success_callback.Run( - current_snapshot_details_->file_info(), - current_snapshot_details_->request_info().snapshot_file_path); + std::move(current_snapshot_details_->success_callback()) + .Run(current_snapshot_details_->file_info(), + current_snapshot_details_->request_info().snapshot_file_path); } else { std::move(current_snapshot_details_->error_callback()) .Run(base::File::FILE_ERROR_FAILED);
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.h b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.h index d45641d..68b8c05 100644 --- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.h +++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.h
@@ -100,16 +100,15 @@ void CreateDirectory(const base::FilePath& directory_path, const bool exclusive, const bool recursive, - const CreateDirectorySuccessCallback& success_callback, + CreateDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; void ReadDirectory(const base::FilePath& root, - const ReadDirectorySuccessCallback& success_callback, + ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; - void CreateSnapshotFile( - const base::FilePath& device_file_path, - const base::FilePath& local_path, - const CreateSnapshotFileSuccessCallback& success_callback, - ErrorCallback error_callback) override; + void CreateSnapshotFile(const base::FilePath& device_file_path, + const base::FilePath& local_path, + CreateSnapshotFileSuccessCallback success_callback, + ErrorCallback error_callback) override; bool IsStreaming() override; void ReadBytes(const base::FilePath& device_file_path, const scoped_refptr<net::IOBuffer>& buf, @@ -123,24 +122,23 @@ const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, const CopyFileProgressCallback& progress_callback, - const CopyFileLocalSuccessCallback& success_callback, + CopyFileLocalSuccessCallback success_callback, ErrorCallback error_callback) override; void MoveFileLocal( const base::FilePath& source_file_path, const base::FilePath& device_file_path, const CreateTemporaryFileCallback& create_temporary_file_callback, - const MoveFileLocalSuccessCallback& success_callback, + MoveFileLocalSuccessCallback success_callback, ErrorCallback error_callback) override; - void CopyFileFromLocal( - const base::FilePath& source_file_path, - const base::FilePath& device_file_path, - const CopyFileFromLocalSuccessCallback& success_callback, - ErrorCallback error_callback) override; + void CopyFileFromLocal(const base::FilePath& source_file_path, + const base::FilePath& device_file_path, + CopyFileFromLocalSuccessCallback success_callback, + ErrorCallback error_callback) override; void DeleteFile(const base::FilePath& file_path, - const DeleteFileSuccessCallback& success_callback, + DeleteFileSuccessCallback success_callback, ErrorCallback error_callback) override; void DeleteDirectory(const base::FilePath& file_path, - const DeleteDirectorySuccessCallback& success_callback, + DeleteDirectorySuccessCallback success_callback, ErrorCallback error_callback) override; void AddWatcher(const GURL& origin, const base::FilePath& file_path, @@ -200,7 +198,7 @@ // // If the ReadDirectory() fails, |file_list| is not set and |error_callback| // is invoked to notify the caller about the platform file |error|. - void OnDidReadDirectory(const ReadDirectorySuccessCallback& success_callback, + void OnDidReadDirectory(ReadDirectorySuccessCallback success_callback, ErrorCallback error_callback, storage::AsyncFileUtil::EntryList* file_list, base::File::Error error);
diff --git a/chrome/browser/media_galleries/win/snapshot_file_details.cc b/chrome/browser/media_galleries/win/snapshot_file_details.cc index 36fb8ed..cd39768 100644 --- a/chrome/browser/media_galleries/win/snapshot_file_details.cc +++ b/chrome/browser/media_galleries/win/snapshot_file_details.cc
@@ -15,12 +15,11 @@ SnapshotRequestInfo::SnapshotRequestInfo( const base::FilePath& device_file_path, const base::FilePath& snapshot_file_path, - const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback& - success_callback, + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback success_callback, MTPDeviceAsyncDelegate::ErrorCallback error_callback) : device_file_path(device_file_path), snapshot_file_path(snapshot_file_path), - success_callback(success_callback), + success_callback(std::move(success_callback)), error_callback(std::move(error_callback)) {} SnapshotRequestInfo::SnapshotRequestInfo(SnapshotRequestInfo&& other) = default;
diff --git a/chrome/browser/media_galleries/win/snapshot_file_details.h b/chrome/browser/media_galleries/win/snapshot_file_details.h index 58144f48..eb26ddfc 100644 --- a/chrome/browser/media_galleries/win/snapshot_file_details.h +++ b/chrome/browser/media_galleries/win/snapshot_file_details.h
@@ -13,12 +13,11 @@ // Structure used to represent snapshot file request params. struct SnapshotRequestInfo { - SnapshotRequestInfo( - const base::FilePath& device_file_path, - const base::FilePath& snapshot_file_path, - const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback& - success_callback, - MTPDeviceAsyncDelegate::ErrorCallback error_callback); + SnapshotRequestInfo(const base::FilePath& device_file_path, + const base::FilePath& snapshot_file_path, + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback + success_callback, + MTPDeviceAsyncDelegate::ErrorCallback error_callback); SnapshotRequestInfo(SnapshotRequestInfo&& other); SnapshotRequestInfo(const SnapshotRequestInfo& other) = delete; SnapshotRequestInfo& operator=(const SnapshotRequestInfo& other) = delete; @@ -50,6 +49,10 @@ const SnapshotRequestInfo& request_info() const { return request_info_; } + MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback success_callback() { + return std::move(request_info_.success_callback); + } + MTPDeviceAsyncDelegate::ErrorCallback error_callback() { return std::move(request_info_.error_callback); }
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_features.cc b/chrome/browser/nearby_sharing/common/nearby_share_features.cc index e208a74..dcddb46 100644 --- a/chrome/browser/nearby_sharing/common/nearby_share_features.cc +++ b/chrome/browser/nearby_sharing/common/nearby_share_features.cc
@@ -8,7 +8,7 @@ // Enables Nearby Sharing functionality. const base::Feature kNearbySharing{"NearbySharing", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables use of device contacts in Nearby Share. The Nearby server returns // both Google contacts and device contacts in ListContactPeople RPC responses.
diff --git a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc index 2ecde512..52c10264 100644 --- a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc +++ b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc
@@ -28,7 +28,7 @@ constexpr base::TimeDelta kContactUploadPeriod = base::TimeDelta::FromHours(24); constexpr base::TimeDelta kContactDownloadPeriod = - base::TimeDelta::FromHours(12); + base::TimeDelta::FromHours(1); constexpr base::TimeDelta kContactDownloadRpcTimeout = base::TimeDelta::FromSeconds(60);
diff --git a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc index d04165c..20b9f6b 100644 --- a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc
@@ -40,7 +40,7 @@ // From nearby_share_contact_manager_impl.cc. constexpr base::TimeDelta kContactUploadPeriod = base::TimeDelta::FromHours(24); constexpr base::TimeDelta kContactDownloadPeriod = - base::TimeDelta::FromHours(12); + base::TimeDelta::FromHours(1); constexpr base::TimeDelta kContactDownloadRpcTimeout = base::TimeDelta::FromSeconds(60);
diff --git a/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc b/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc index eb346ea..7614a53 100644 --- a/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_connections_manager_impl.cc
@@ -126,12 +126,21 @@ connection_lifecycle_listeners_.Add( this, lifecycle_listener.InitWithNewPipeAndPassReceiver()); + // Only auto-upgrade bandwidth if advertising at high-visibility. + // This acts as a privacy safeguard when advertising in the background. + // Bandwidth upgrades may expose stable identifiers, and so they're + // only safe to expose after we've verified the sender's identity. + // Once we have verified their identity, we will manually trigger + // a bandwidth upgrade. This isn't a concern in the foreground + // because high-visibility already leaks the device name. + bool auto_upgrade_bandwidth = is_high_power; + incoming_connection_listener_ = listener; nearby_connections_->StartAdvertising( kServiceId, endpoint_info, AdvertisingOptions::New( kStrategy, std::move(allowed_mediums), - /*auto_upgrade_bandwidth=*/is_high_power, + auto_upgrade_bandwidth, /*enforce_topology_constraints=*/true, /*enable_bluetooth_listening=*/use_ble, /*fast_advertisement_service_uuid=*/
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc index 8e60c5b..24ee497 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -2032,6 +2032,10 @@ base::Optional<std::string> endpoint_id = info->endpoint_id(); if (endpoint_id) { + // Upgrade bandwidth regardless of advertising visibility because either + // the system or the user has verified the sender's identity; the + // stable identifiers potentially exposed by performing a bandwidth + // upgrade are no longer a concern. nearby_connections_manager_->UpgradeBandwidth(*endpoint_id); } else { NS_LOG(WARNING) << __func__ @@ -2637,6 +2641,10 @@ NS_LOG(VERBOSE) << __func__ << ": Paired key handshake succeeded for target - " << share_target.id; + // Upgrade bandwidth regardless of advertising visibility because the + // sender's identity has been confirmed; the stable identifiers + // potentially exposed by performing a bandwidth upgrade are no longer a + // concern. nearby_connections_manager_->UpgradeBandwidth(*info->endpoint_id()); ReceiveIntroduction(share_target, /*four_digit_token=*/base::nullopt); break; @@ -2647,6 +2655,9 @@ "receiving connection from target - " << share_target.id; if (advertising_power_level_ == PowerLevel::kHighPower) + // Upgrade bandwidth if advertising at high-visibility. Bandwidth + // upgrades may expose stable identifiers, but this isn't a concern + // here because high-visibility already leaks the device name. nearby_connections_manager_->UpgradeBandwidth(*info->endpoint_id()); if (four_digit_token)
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 369259b..6ab9165f 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -185,12 +185,6 @@ void AddToWidgetInputEventObservers( content::RenderWidgetHost* widget_host, content::RenderWidgetHost::InputEventObserver* observer) { -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": widget_host: " << widget_host - << "; observer: " << observer; -#endif - // Since Widget API doesn't allow to check whether the observer is already // added, the observer is removed and added again, to ensure that it is added // only once. @@ -202,26 +196,6 @@ widget_host->AddInputEventObserver(observer); } -// Removes |observer| from the input observers of |widget_host|. -// This method is a NOOP for branded builds. -void MaybeRemoveFromWidgetInputEventObservers( - content::RenderWidgetHost* widget_host, - content::RenderWidgetHost::InputEventObserver* observer) { -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": widget_host: " << widget_host - << "; observer: " << observer; - - if (!widget_host) - return; - -#if defined(OS_ANDROID) - widget_host->RemoveImeInputEventObserver(observer); -#endif - widget_host->RemoveInputEventObserver(observer); -#endif // !BUILDFLAG(GOOGLE_CHROME_BRANDING) -} - #if defined(OS_ANDROID) void HideSavePasswordInfobar(content::WebContents* web_contents) { InfoBarService* infobar_service = @@ -281,17 +255,7 @@ contents, autofill_client))); } -ChromePasswordManagerClient::~ChromePasswordManagerClient() { -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "wc: " << web_contents(); - if (web_contents()) { - VLOG(1) << "wc->GetRenderViewHost(): " - << web_contents()->GetMainFrame()->GetRenderViewHost(); - } -#endif -} +ChromePasswordManagerClient::~ChromePasswordManagerClient() = default; bool ChromePasswordManagerClient::IsSavingAndFillingEnabled( const GURL& url) const { @@ -1228,14 +1192,6 @@ autofill_assistant::RuntimeManager::GetOrCreateForWebContents( web_contents); autofill_assistant_manager->AddObserver(this); - -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "wc: " << web_contents; - VLOG(1) << "wc->GetRenderViewHost(): " - << web_contents->GetMainFrame()->GetRenderViewHost(); -#endif } void ChromePasswordManagerClient::DidStartNavigation( @@ -1265,13 +1221,6 @@ password_reuse_detection_manager_.DidNavigateMainFrame(GetLastCommittedURL()); -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "wc: " << web_contents(); - VLOG(1) << "wc->GetRenderViewHost(): " - << web_contents()->GetMainFrame()->GetRenderViewHost(); -#endif AddToWidgetInputEventObservers( web_contents()->GetMainFrame()->GetRenderViewHost()->GetWidget(), this); #if defined(OS_ANDROID) @@ -1294,18 +1243,6 @@ // don't like to be destroyed earlier than the pipe itself. content_credential_manager_.DisconnectBinding(); - DCHECK(web_contents()->GetMainFrame()->GetRenderViewHost()); - -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "wc: " << web_contents(); - VLOG(1) << "wc->GetRenderViewHost(): " - << web_contents()->GetMainFrame()->GetRenderViewHost(); -#endif - MaybeRemoveFromWidgetInputEventObservers( - web_contents()->GetMainFrame()->GetRenderViewHost()->GetWidget(), this); - auto* autofill_assistant_manager = autofill_assistant::RuntimeManager::GetForWebContents(web_contents()); if (autofill_assistant_manager) { @@ -1315,22 +1252,8 @@ #if !defined(OS_ANDROID) void ChromePasswordManagerClient::OnPaste() { -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "wc: " << web_contents(); - VLOG(1) << "wc->GetRenderViewHost(): " - << web_contents()->GetMainFrame()->GetRenderViewHost(); -#endif - base::string16 text; bool used_crosapi_workaround = false; - - // Note: The call to `clipboard->ReadText()` below runs a nested message loop, - // potentially returning control back to this method after the client has been - // destroyed. Check `self` prior to dereferencing members. - base::WeakPtr<ChromePasswordManagerClient> self = - weak_ptr_factory_.GetWeakPtr(); #if BUILDFLAG(IS_CHROMEOS_LACROS) // On Lacros, the ozone/wayland clipboard implementation is asynchronous by // default and runs a nested message loop to fake synchroncity. This in turn @@ -1362,22 +1285,13 @@ clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, &data_dst, &text); } - if (self) { - was_on_paste_called_ = true; - password_reuse_detection_manager_.OnPaste(std::move(text)); - } + was_on_paste_called_ = true; + password_reuse_detection_manager_.OnPaste(std::move(text)); } #endif void ChromePasswordManagerClient::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "rfh: " << render_frame_host; - VLOG(1) << "rfh->GetView(): " << render_frame_host->GetView(); -#endif - // TODO(drubery): We should handle input events on subframes separately, so // that we can accurately report that the password was reused on a subframe. // Currently any password reuse for this WebContents will report password @@ -1386,21 +1300,6 @@ render_frame_host->GetView()->GetRenderWidgetHost(), this); } -void ChromePasswordManagerClient::RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) { -#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) - // TODO(https://crbug.com/1104919): Remove this logging. - VLOG(1) << __FUNCTION__ << ": this: " << this; - VLOG(1) << "rfh: " << render_frame_host; - VLOG(1) << "rfh->GetView(): " << render_frame_host->GetView(); -#endif - - if (!render_frame_host->GetView()) - return; - MaybeRemoveFromWidgetInputEventObservers( - render_frame_host->GetView()->GetRenderWidgetHost(), this); -} - void ChromePasswordManagerClient::OnInputEvent( const blink::WebInputEvent& event) { #if defined(OS_ANDROID)
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index 4cc426a..4f48ffc9 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -12,7 +12,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/optional.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -300,7 +299,6 @@ void OnPaste() override; #endif void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; - void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; // content::RenderWidgetHost::InputEventObserver overrides. void OnInputEvent(const blink::WebInputEvent&) override; @@ -420,11 +418,6 @@ // ChromePasswordManagerClient and IOSChromePasswordManagerClient. password_manager::PasswordManagerClientHelper helper_; - // This is added as a workaround for an issue inside OnPaste(). Please don't - // just use the WeakPtrs returned from this factory blindly, but make a - // informed decision after carefully considering the involved lifetimes. - base::WeakPtrFactory<ChromePasswordManagerClient> weak_ptr_factory_{this}; - WEB_CONTENTS_USER_DATA_KEY_DECL(); DISALLOW_COPY_AND_ASSIGN(ChromePasswordManagerClient);
diff --git a/chrome/browser/policy/extension_policy_browsertest.cc b/chrome/browser/policy/extension_policy_browsertest.cc index 20db587..5d27b0e 100644 --- a/chrome/browser/policy/extension_policy_browsertest.cc +++ b/chrome/browser/policy/extension_policy_browsertest.cc
@@ -175,12 +175,7 @@ class ExtensionPolicyTest : public PolicyTest { public: - ExtensionPolicyTest() { -#if BUILDFLAG(IS_CHROMEOS_ASH) - scoped_feature_list_.InitAndDisableFeature( - chromeos::features::kCameraSystemWebApp); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - } + ExtensionPolicyTest() = default; protected: void SetUp() override { @@ -385,24 +380,15 @@ skip_scheduled_extension_checks_; private: - base::test::ScopedFeatureList scoped_feature_list_; - web_app::ScopedOsHooksSuppress os_hooks_suppress_; }; } // namespace #if BUILDFLAG(IS_CHROMEOS_ASH) -// Check that component extension can't be blocklisted, besides the camera app -// that can be disabled by extension policy. This is a temporary solution until -// there's a dedicated policy to disable the camera, at which point the special -// check should be removed. -// TODO(http://crbug.com/1002935) +// Check that component extension can't be blocklisted. IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest, ExtensionInstallBlocklistComponentApps) { - extensions::ExtensionPrefs* extension_prefs = - extensions::ExtensionPrefs::Get(browser()->profile()); - // Load all component extensions. extensions::ComponentLoader::EnableBackgroundExtensionsForTesting(); extension_service()->component_loader()->AddDefaultComponentExtensions(false); @@ -410,31 +396,17 @@ extensions::ExtensionRegistry* registry = extension_registry(); ASSERT_TRUE( - registry->enabled_extensions().GetByID(extension_misc::kCameraAppId)); - ASSERT_TRUE( registry->enabled_extensions().GetByID(extensions::kWebStoreAppId)); - const size_t enabled_count = registry->enabled_extensions().size(); - // Verify that only Camera app can be blocklisted. base::ListValue blocklist; - blocklist.AppendString(extension_misc::kCameraAppId); blocklist.AppendString(extensions::kWebStoreAppId); PolicyMap policies; policies.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, blocklist.Clone(), nullptr); UpdateProviderPolicy(policies); - - ASSERT_FALSE( - registry->enabled_extensions().GetByID(extension_misc::kCameraAppId)); - ASSERT_TRUE( - registry->disabled_extensions().GetByID(extension_misc::kCameraAppId)); - EXPECT_EQ(1u, registry->disabled_extensions().size()); - EXPECT_EQ(extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY, - extension_prefs->GetDisableReasons(extension_misc::kCameraAppId)); ASSERT_TRUE( registry->enabled_extensions().GetByID(extensions::kWebStoreAppId)); - EXPECT_EQ(enabled_count - 1, registry->enabled_extensions().size()); } // Ensures that OS Settings can't be disabled by ExtensionInstallBlocklist
diff --git a/chrome/browser/policy/system_features_policy_browsertest.cc b/chrome/browser/policy/system_features_policy_browsertest.cc index 11dabf8..becdb22c 100644 --- a/chrome/browser/policy/system_features_policy_browsertest.cc +++ b/chrome/browser/policy/system_features_policy_browsertest.cc
@@ -30,10 +30,7 @@ class SystemFeaturesPolicyTest : public PolicyTest { public: - SystemFeaturesPolicyTest() { - scoped_feature_list_.InitAndDisableFeature( - chromeos::features::kCameraSystemWebApp); - } + SystemFeaturesPolicyTest() = default; protected: base::string16 GetWebUITitle(const GURL& url) { @@ -100,40 +97,8 @@ EXPECT_EQ(expected_visibility, update.ShowInShelf()); }); } - - private: - base::test::ScopedFeatureList scoped_feature_list_; }; -IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableCameraBeforeInstall) { - base::Value system_features(base::Value::Type::LIST); - system_features.Append(kCameraFeature); - UpdateSystemFeaturesDisableList(std::move(system_features), nullptr); - EnableExtensions(false); - VerifyAppState(extension_misc::kCameraAppId, - apps::mojom::Readiness::kDisabledByPolicy, true, - apps::mojom::OptionalBool::kTrue); - - UpdateSystemFeaturesDisableList(base::Value(), nullptr); - VerifyAppState(extension_misc::kCameraAppId, apps::mojom::Readiness::kReady, - false, apps::mojom::OptionalBool::kTrue); -} - -IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableCameraAfterInstall) { - EnableExtensions(false); - base::Value system_features(base::Value::Type::LIST); - system_features.Append(kCameraFeature); - UpdateSystemFeaturesDisableList(std::move(system_features), nullptr); - - VerifyAppState(extension_misc::kCameraAppId, - apps::mojom::Readiness::kDisabledByPolicy, true, - apps::mojom::OptionalBool::kTrue); - - UpdateSystemFeaturesDisableList(base::Value(), nullptr); - VerifyAppState(extension_misc::kCameraAppId, apps::mojom::Readiness::kReady, - false, apps::mojom::OptionalBool::kTrue); -} - IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableWebStoreBeforeInstall) { base::Value system_features(base::Value::Type::LIST); system_features.Append(kWebStoreFeature); @@ -189,26 +154,6 @@ false, apps::mojom::OptionalBool::kTrue); } -IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, - DisableCameraAndWebStoreAfterInstall) { - EnableExtensions(false); - base::Value system_features(base::Value::Type::LIST); - system_features.Append(kWebStoreFeature); - system_features.Append(kCameraFeature); - UpdateSystemFeaturesDisableList(std::move(system_features), nullptr); - - VerifyAppState(extensions::kWebStoreAppId, - apps::mojom::Readiness::kDisabledByPolicy, true, - apps::mojom::OptionalBool::kTrue); - VerifyAppState(extension_misc::kCameraAppId, - apps::mojom::Readiness::kDisabledByPolicy, true, - apps::mojom::OptionalBool::kTrue); - - UpdateSystemFeaturesDisableList(base::Value(), nullptr); - VerifyAppState(extensions::kWebStoreAppId, apps::mojom::Readiness::kReady, - false, apps::mojom::OptionalBool::kTrue); -} - IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, RedirectChromeSettingsURL) { PolicyMap policies; base::Value system_features(base::Value::Type::LIST);
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 5bdf364..b4d2826 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -2506,6 +2506,12 @@ break; case IDC_CONTENT_CONTEXT_EMOJI: { + // The emoji dialog is UI that can interfere with the fullscreen bubble, + // so drop fullscreen when it is shown. https://crbug.com/1170584 + // TODO(avi): Do we need to attach the fullscreen block to the emoji + // panel? + source_web_contents_->ForSecurityDropFullscreen().RunAndReset(); + Browser* browser = GetBrowser(); if (browser) { browser->window()->ShowEmojiPanel();
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index a4a7aa10..0abb7ac 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -30,8 +30,6 @@ "../common/instance_checker.js", "../common/string_util.js", "../common/tree_walker.js", - "background/annotation/node_identifier.js", - "background/annotation/user_annotation_handler.js", "background/automation_object_constructor_installer.js", "background/base_automation_handler.js", "background/braille_background.js", @@ -109,7 +107,6 @@ "injected/script_installer.js", "learn_mode/kbexplorer.js", "options/options.js", - "panel/annotations_ui.js", "panel/i_search.js", "panel/panel.js", "panel/panel_menu.js", @@ -186,8 +183,6 @@ "background/earcons/static.wav", "background/logging/log.css", "background/logging/log.html", - "i_tutorial/practice_areas/jump_commands.html", - "i_tutorial/practice_areas/selects.html", "images/chromevox-128.png", "images/chromevox-16.png", "images/chromevox-19.png", @@ -206,6 +201,8 @@ "options/unchecked.png", "panel/panel.css", "panel/panel.html", + "tutorial/practice_areas/jump_commands.html", + "tutorial/practice_areas/selects.html", ] sources += chromevox_es6_modules rewrite_rules = [ @@ -411,8 +408,6 @@ js2gtest("chromevox_extension_js_tests") { test_type = "extension" sources = [ - "background/annotation/node_identifier_test.js", - "background/annotation/user_annotation_handler_test.js", "background/background_test.js", "background/braille_command_data_test.js", "background/color_test.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/node_identifier.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/node_identifier.js deleted file mode 100644 index 4a87038..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/node_identifier.js +++ /dev/null
@@ -1,179 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Defines a class used to identify AutomationNodes. - */ - -goog.provide('NodeIdentifier'); - -/** - * Stores all identifying attributes for an AutomationNode. - * A helper object for NodeIdentifier. - * @typedef {{ - * id: string, - * name: string, - * role: string, - * description: string, - * restriction: string, - * childCount: number, - * indexInParent: number, - * className: string, - * htmlTag: string }} - */ -let Attributes; - -NodeIdentifier = class { - /** - * @param {!{ - * attributes: !Attributes, - * pageUrl: string, ancestry: - * !Array<!Attributes>}} params - * @private - */ - constructor(params) { - /** - * @type {!Attributes} - */ - this.attributes = params.attributes; - /** - * @type {string} - */ - this.pageUrl = params.pageUrl; - /** - * @type {!Array<!Attributes>} - */ - this.ancestry = params.ancestry; - } - - /** - * @param {!AutomationNode} node - * @return {!NodeIdentifier} - */ - static constructFromNode(node) { - const params = { - attributes: NodeIdentifier.createAttributes_(node), - pageUrl: node.root.docUrl || '', - ancestry: NodeIdentifier.createAttributesAncestry_(node) - }; - return new NodeIdentifier(params); - } - - /** - * @param {string} str - * @return {?NodeIdentifier} - */ - static constructFromString(str) { - try { - const params = - /** - @type {!{attributes: !Attributes, pageUrl: string, ancestry: - !Array<!Attributes>}} - */ - (JSON.parse(str)); - return new NodeIdentifier(params); - } catch (error) { - console.error('Invalid string argument to NodeIdentifier constructor'); - console.error(error); - return null; - } - } - - /** - * Returns true if |this| is equal to |other|. - * @param {!NodeIdentifier} other - * @return {boolean} - */ - equals(other) { - // If pageUrl and HTML Id match, we know they refer to the same node. - if (this.pageUrl && this.attributes.id && this.pageUrl === other.pageUrl && - this.attributes.id === other.attributes.id) { - return true; - } - - // Ensure both NodeIdentifiers are composed of matching Attributes. - if (!this.matchingAttributes_(this.attributes, other.attributes)) { - return false; - } - - if (this.ancestry.length !== other.ancestry.length) { - return false; - } - - for (let i = 0; i < this.ancestry.length; ++i) { - if (!this.matchingAttributes_(this.ancestry[i], other.ancestry[i])) { - return false; - } - } - return true; - } - - /** - * @param {!AutomationNode} node - * @return {!Attributes} - * @private - */ - static createAttributes_(node) { - return { - id: (node.htmlAttributes) ? node.htmlAttributes['id'] || '' : '', - name: node.name || '', - role: node.role || '', - description: node.description || '', - restriction: node.restriction || '', - childCount: node.childCount || 0, - indexInParent: node.indexInParent || 0, - className: node.className || '', - htmlTag: node.htmlTag || '' - }; - } - - /** - * @param {!AutomationNode} node - * @return {!Array<!Attributes>} - * @private - */ - static createAttributesAncestry_(node) { - const ancestry = []; - let scanNode = node.parent; - const treeRoot = node.root; - while (scanNode && scanNode !== treeRoot) { - ancestry.push(NodeIdentifier.createAttributes_(scanNode)); - scanNode = scanNode.parent; - } - return ancestry; - } - - /** - * @param {!Attributes} target - * @param {!Attributes} candidate - * @return {boolean} - * @private - */ - matchingAttributes_(target, candidate) { - for (const [key, targetValue] of Object.entries(target)) { - if (candidate[key] !== targetValue) { - return false; - } - } - return true; - } - - /** - * @override - */ - toJSON() { - return { - attributes: this.attributes, - pageUrl: this.pageUrl, - ancestry: this.ancestry - }; - } - - /** - * @override - */ - toString() { - return JSON.stringify(this); - } -};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/node_identifier_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/node_identifier_test.js deleted file mode 100644 index 7da998f..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/node_identifier_test.js +++ /dev/null
@@ -1,152 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Include test fixture. -GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js']); - -/** - * Test fixture for NodeIdentifier. - */ -ChromeVoxNodeIdentifierTest = class extends ChromeVoxNextE2ETest { - /** - * Returns the start node of the current ChromeVox range. - */ - getRangeStart() { - return ChromeVoxState.instance.getCurrentRange().start.node; - } - - get basicButtonDoc() { - return ` - <p>Start here</p> - <button id="apple-button">Apple</button> - <button>Orange</button> - `; - } - - get duplicateButtonDoc() { - return ` - <p>Start here</p> - <button>Click me</button> - <button>Click me</button> - `; - } - - get identicalListsDoc() { - return ` - <p>Start here</p> - <ul> - <li>Apple</li> - <li>Orange</li> - </ul> - <ul> - <li>Apple</li> - <li>Orange</li> - </ul> - `; - } -}; - - -// Tests that we can distinguish between two similar buttons. -TEST_F('ChromeVoxNodeIdentifierTest', 'BasicButtonTest', function() { - this.runWithLoadedTree(this.basicButtonDoc, function(rootNode) { - const appleNode = - rootNode.find({role: RoleType.BUTTON, attributes: {name: 'Apple'}}); - const orangeNode = - rootNode.find({role: RoleType.BUTTON, attributes: {name: 'Orange'}}); - assertFalse(!appleNode); - assertFalse(!orangeNode); - const appleId = NodeIdentifier.constructFromNode(appleNode); - const duplicateAppleId = NodeIdentifier.constructFromNode(appleNode); - const orangeId = NodeIdentifier.constructFromNode(orangeNode); - - assertTrue(appleId.equals(duplicateAppleId)); - assertFalse(appleId.equals(orangeId)); - }); -}); - -// Tests that we can distinguish two buttons with the same name. -TEST_F('ChromeVoxNodeIdentifierTest', 'DuplicateButtonTest', function() { - this.runWithLoadedTree(this.duplicateButtonDoc, function() { - CommandHandler.onCommand('nextButton'); - const firstButton = this.getRangeStart(); - const firstButtonId = NodeIdentifier.constructFromNode(firstButton); - CommandHandler.onCommand('nextButton'); - const secondButton = this.getRangeStart(); - const secondButtonId = NodeIdentifier.constructFromNode(secondButton); - - assertFalse(firstButtonId.equals(secondButtonId)); - }); -}); - -// Tests that we can differentiate between the list items of two identical -// lists. -TEST_F('ChromeVoxNodeIdentifierTest', 'IdenticalListsTest', function() { - this.runWithLoadedTree(this.identicalListsDoc, function() { - // Create NodeIdentifiers for each item. - CommandHandler.onCommand('nextObject'); - CommandHandler.onCommand('nextObject'); - const firstApple = NodeIdentifier.constructFromNode(this.getRangeStart()); - CommandHandler.onCommand('nextObject'); - CommandHandler.onCommand('nextObject'); - const firstOrange = NodeIdentifier.constructFromNode(this.getRangeStart()); - CommandHandler.onCommand('nextObject'); - CommandHandler.onCommand('nextObject'); - const secondApple = NodeIdentifier.constructFromNode(this.getRangeStart()); - CommandHandler.onCommand('nextObject'); - CommandHandler.onCommand('nextObject'); - const secondOrange = NodeIdentifier.constructFromNode(this.getRangeStart()); - - assertFalse(firstApple.equals(secondApple)); - assertFalse(firstOrange.equals(secondOrange)); - }); -}); - -// Tests that we can successfully stringify NodeIdentifiers. -TEST_F('ChromeVoxNodeIdentifierTest', 'ToStringTest', function() { - this.runWithLoadedTree(this.basicButtonDoc, function(rootNode) { - const appleNode = - rootNode.find({role: RoleType.BUTTON, attributes: {name: 'Apple'}}); - const orangeNode = - rootNode.find({role: RoleType.BUTTON, attributes: {name: 'Orange'}}); - assertFalse(!appleNode); - assertFalse(!orangeNode); - const appleId = NodeIdentifier.constructFromNode(appleNode); - const orangeId = NodeIdentifier.constructFromNode(orangeNode); - - const expectedAppleString = [ - '{"attributes":{"id":"apple-button","name":"Apple","role":"button",', - '"description":"","restriction":"","childCount":0,"indexInParent":1,', - '"className":"","htmlTag":"button"},', - '"pageUrl":"data:text/html,<!doctype html>%3Cp%3EStart%20here%3C%2Fp%3E', - '%20%3Cbutton%20id%3D%22apple-button%22%3EApple%3C%2Fbutton%3E%20%3Cbut', - 'ton%3EOrange%3C%2Fbutton%3E","ancestry":[]}' - ].join(''); - const expectedOrangeString = [ - '{"attributes":{"id":"","name":"Orange","role":"button",', - '"description":"","restriction":"","childCount":0,"indexInParent":2,', - '"className":"","htmlTag":"button"},"pageUrl":"data:text/html,<!doctype', - ' html>%3Cp%3EStart%20here%3C%2Fp%3E%20%3Cbutton%20id%3D%22apple-button', - '%22%3EApple%3C%2Fbutton%3E%20%3Cbutton%3EOrange%3C%2Fbutton%3E",', - '"ancestry":[]}' - ].join(''); - - assertEquals(appleId.toString(), expectedAppleString); - assertEquals(orangeId.toString(), expectedOrangeString); - }); -}); - -// Tests that we can successfully create a NodeIdentifier from a string -// representation. -TEST_F('ChromeVoxNodeIdentifierTest', 'FromStringTest', function() { - this.runWithLoadedTree(this.basicButtonDoc, function(rootNode) { - const appleNode = - rootNode.find({role: RoleType.BUTTON, attributes: {name: 'Apple'}}); - assertFalse(!appleNode); - const appleId = NodeIdentifier.constructFromNode(appleNode); - const appleIdStr = JSON.stringify(appleId); - const duplicateAppleId = NodeIdentifier.constructFromString(appleIdStr); - assertTrue(appleId.equals(duplicateAppleId)); - }); -});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/user_annotation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/user_annotation_handler.js deleted file mode 100644 index b67218c..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/user_annotation_handler.js +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Manages ChromeVox users' custom annotations. - */ - -goog.provide('UserAnnotationHandler'); - -goog.require('NodeIdentifier'); - -/** - * Stores annotation-related data. - * @typedef {{ - * annotation: string, - * identifier: !NodeIdentifier - * }} - */ -let AnnotationData; - -UserAnnotationHandler = class { - static init() { - UserAnnotationHandler.instance = new UserAnnotationHandler(); - } - - /** - * @private - */ - constructor() { - /** - * Stores user annotations. - * Maps URLs to arrays of AnnotationData objects for that page. - * @private {Object<string, !Array<!AnnotationData>>} - */ - this.annotations_ = {}; - /** - * Whether this feature is enabled or not. - * @type {boolean} - */ - this.enabled = false; - chrome.commandLinePrivate.hasSwitch( - 'enable-experimental-accessibility-chromevox-annotations', - (enabled) => { - this.enabled = enabled; - }); - } - - /** - * Creates or updates an annotation for an AutomationNode. - * @param {!AutomationNode} node - * @param {string} annotation - */ - static setAnnotationForNode(node, annotation) { - const identifier = NodeIdentifier.constructFromNode(node); - UserAnnotationHandler.setAnnotationForIdentifier(identifier, annotation); - } - - /** - * Creates or updates an annotation for a NodeIdentifier. - * @param {!NodeIdentifier} identifier - * @param {string} annotation - */ - static setAnnotationForIdentifier(identifier, annotation) { - const url = identifier.pageUrl; - if (!UserAnnotationHandler.instance || - !UserAnnotationHandler.instance.enabled || !url) { - return; - } - - const annotationData = {annotation, identifier}; - if (!UserAnnotationHandler.instance.annotations_[url]) { - UserAnnotationHandler.instance.annotations_[url] = []; - } - // Either update an existing annotation or add a new one. - const annotations = UserAnnotationHandler.instance.annotations_[url]; - const target = annotationData.identifier; - let updated = false; - for (let i = 0; i < annotations.length; ++i) { - if (target.equals(annotations[i].identifier)) { - UserAnnotationHandler.instance.annotations_[url][i] = annotationData; - updated = true; - break; - } - } - if (!updated) { - UserAnnotationHandler.instance.annotations_[url].push(annotationData); - } - } - - /** - * Returns the annotation for node, if one exists. Otherwise, returns null. - * @param {!AutomationNode} node - * @return {?string} - */ - static getAnnotationForNode(node) { - if (!node.root) { - return null; - } - const url = node.root.docUrl || ''; - if (!UserAnnotationHandler.instance || - !UserAnnotationHandler.instance.enabled || !url) { - return null; - } - - const candidates = UserAnnotationHandler.instance.annotations_[url]; - if (!candidates) { - return null; - } - - const target = NodeIdentifier.constructFromNode(node); - for (let i = 0; i < candidates.length; ++i) { - const candidate = candidates[i]; - if (target.equals(candidate.identifier)) { - return candidate.annotation; - } - } - - return null; - } -};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/user_annotation_handler_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/user_annotation_handler_test.js deleted file mode 100644 index 1d7997a..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/annotation/user_annotation_handler_test.js +++ /dev/null
@@ -1,164 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Include test fixture. -GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js']); - -GEN_INCLUDE(['../../testing/fake_objects.js']); - -/** - * Test fixture for UserAnnotationHandler. - * @constructor - * @extends {ChromeVoxE2ETest} - */ -ChromeVoxAnnotationTest = class extends ChromeVoxNextE2ETest { - /** @override */ - testGenCppIncludes() { - super.testGenCppIncludes(); - GEN(` - #include "base/command_line.h" - #include "ui/accessibility/accessibility_switches.h" - #include "ui/base/ui_base_switches.h" - `); - } - - /** @override */ - testGenPreamble() { - GEN(` - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableExperimentalAccessibilityChromeVoxAnnotations); - `); - super.testGenPreamble(); - } - - assertNumberOfAnnotationsForUrl(url, numAnnotations) { - const annotations = UserAnnotationHandler.instance.annotations_[url]; - if (!annotations) { - console.error('No annotations for provided url'); - assertFalse(true); - } - assertEquals(numAnnotations, annotations.length); - } - - /** - * Returns the start node of the current ChromeVox range. - * @return {AutomationNode} - */ - getRangeStart() { - return ChromeVoxState.instance.getCurrentRange().start.node; - } - - // Test documents // - get basicButtonDoc() { - return ` - <p>Start here</p> - <button>Apple</button> - <button>Orange</button> - `; - } - - get duplicateButtonDoc() { - return ` - <p>Start here</p> - <button>Click me</button> - <button>Click me</button> - `; - } -}; - -TEST_F('ChromeVoxAnnotationTest', 'BasicButtonTest', function() { - const mockFeedback = this.createMockFeedback(); - this.runWithLoadedTree(this.basicButtonDoc, function(root) { - const pageUrl = root.docUrl; - // Create annotations for both buttons. - CommandHandler.onCommand('nextButton'); - const appleNode = this.getRangeStart(); - UserAnnotationHandler.setAnnotationForNode(appleNode, 'Batman'); - CommandHandler.onCommand('nextButton'); - const orangeNode = this.getRangeStart(); - UserAnnotationHandler.setAnnotationForNode(orangeNode, 'Robin'); - - this.assertNumberOfAnnotationsForUrl(pageUrl, 2); - assertEquals( - UserAnnotationHandler.getAnnotationForNode(appleNode), 'Batman'); - assertEquals( - UserAnnotationHandler.getAnnotationForNode(orangeNode), 'Robin'); - CommandHandler.onCommand('jumpToTop'); - mockFeedback.call(doCmd('nextButton')) - .expectSpeech('Batman', 'Button') - .call(doCmd('nextButton')) - .expectSpeech('Robin', 'Button') - .replay(); - }); -}); - -TEST_F('ChromeVoxAnnotationTest', 'DuplicateButtonTest', function() { - const mockFeedback = this.createMockFeedback(); - this.runWithLoadedTree(this.duplicateButtonDoc, function(root) { - const pageUrl = root.docUrl; - CommandHandler.onCommand('nextButton'); - const firstButton = this.getRangeStart(); - UserAnnotationHandler.setAnnotationForNode(firstButton, 'First button'); - CommandHandler.onCommand('nextButton'); - const secondButton = this.getRangeStart(); - UserAnnotationHandler.setAnnotationForNode(secondButton, 'Second button'); - - this.assertNumberOfAnnotationsForUrl(pageUrl, 2); - assertEquals( - UserAnnotationHandler.getAnnotationForNode(firstButton), - 'First button'); - assertEquals( - UserAnnotationHandler.getAnnotationForNode(secondButton), - 'Second button'); - CommandHandler.onCommand('jumpToTop'); - mockFeedback.call(doCmd('nextButton')) - .expectSpeech('First button', 'Button') - .call(doCmd('nextButton')) - .expectSpeech('Second button', 'Button') - .replay(); - }); -}); - -TEST_F('ChromeVoxAnnotationTest', 'UpdateAnnotationTest', function() { - this.runWithLoadedTree(this.basicButtonDoc, function(root) { - const pageUrl = root.docUrl; - let appleButton = - root.find({role: RoleType.BUTTON, attributes: {name: 'Apple'}}); - assertFalse(!appleButton); - UserAnnotationHandler.setAnnotationForNode(appleButton, 'Good morning'); - this.assertNumberOfAnnotationsForUrl(pageUrl, 1); - assertEquals( - 'Good morning', - UserAnnotationHandler.getAnnotationForNode(appleButton)); - // Update annotation. - appleButton = - root.find({role: RoleType.BUTTON, attributes: {name: 'Apple'}}); - assertFalse(!appleButton); - UserAnnotationHandler.setAnnotationForNode(appleButton, 'Good night'); - this.assertNumberOfAnnotationsForUrl(root.docUrl, 1); - assertEquals( - 'Good night', UserAnnotationHandler.getAnnotationForNode(appleButton)); - }); -}); - -// Tests that we can create an annotation for a node using its NodeIdentifier. -TEST_F('ChromeVoxAnnotationTest', 'CreateFromNodeIdentifier', function() { - const mockFeedback = this.createMockFeedback(); - this.runWithLoadedTree(this.basicButtonDoc, function(root) { - const pageUrl = root.docUrl; - const appleButton = - root.find({role: RoleType.BUTTON, attributes: {name: 'Apple'}}); - assertFalse(!appleButton); - const appleId = NodeIdentifier.constructFromNode(appleButton); - UserAnnotationHandler.setAnnotationForIdentifier(appleId, 'Testing'); - - this.assertNumberOfAnnotationsForUrl(pageUrl, 1); - CommandHandler.onCommand('jumpToTop'); - mockFeedback.call(doCmd('nextButton')) - .expectSpeech('Testing', 'Button') - .call(doCmd('nextButton')) - .expectSpeech('Orange', 'Button') - .replay(); - }); -});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js index 7123b19..e68d605 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
@@ -112,7 +112,6 @@ FindHandler.init(); DownloadHandler.init(); PhoneticData.init(); - UserAnnotationHandler.init(); chrome.accessibilityPrivate.onAnnounceForAccessibility.addListener( (announceText) => {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js index bea7946e..f6cb8de 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -22,8 +22,6 @@ goog.require('ChromeVoxKbHandler'); goog.require('ChromeVoxPrefs'); goog.require('CommandStore'); -goog.require('UserAnnotationHandler'); -goog.require('NodeIdentifier'); goog.scope(function() { const AutomationEvent = chrome.automation.AutomationEvent; @@ -245,10 +243,6 @@ case 'help': (new PanelCommand(PanelCommandType.TUTORIAL)).send(); return false; - case 'showNextUpdatePage': - (new PanelCommand(PanelCommandType.UPDATE_NOTES)).send(); - localStorage['notifications_update_notification_shown'] = true; - return false; case 'toggleDarkScreen': const oldState = sessionStorage.getItem('darkScreen'); const newState = (oldState === 'true') ? false : true; @@ -1070,17 +1064,6 @@ .go(); } return false; - case 'toggleAnnotationsWidget': { - if (!UserAnnotationHandler.instance.enabled) { - return false; - } - const node = ChromeVoxState.instance.currentRange.start.node; - const identifier = NodeIdentifier.constructFromNode(node); - (new PanelCommand( - PanelCommandType.OPEN_ANNOTATIONS_UI, JSON.stringify(identifier))) - .send(); - } - return false; case 'logLanguageInformationForCurrentNode': { if (!CommandHandler.languageLoggingEnabled_) { return false;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js index 6290df4..7b9828b 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js
@@ -513,10 +513,6 @@ 'sequence': {'cvoxModifier': true, 'keys': {'keyCode': [79, 84]}} }, { - 'command': 'showNextUpdatePage', - 'sequence': {'cvoxModifier': true, 'keys': {'keyCode': [79, 78]}} - }, - { 'command': 'toggleEarcons', 'sequence': {'cvoxModifier': true, 'keys': {'keyCode': [65, 69]}} }, @@ -759,10 +755,6 @@ } }, { - 'command': 'toggleAnnotationsWidget', - 'sequence': {'cvoxModifier': true, 'keys': {'keyCode': [65, 79]}} - }, - { 'command': 'logLanguageInformationForCurrentNode', 'sequence': {'cvoxModifier': true, 'keys': {'keyCode': [80, 76]}} }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js index baaeb32..9160f1a 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js
@@ -26,11 +26,9 @@ goog.require('LocaleOutputHelper'); goog.require('MathHandler'); goog.require('NavBraille'); -goog.require('NodeIdentifier'); goog.require('Output'); goog.require('Output.EventType'); goog.require('PanelCommand'); goog.require('PhoneticData'); -goog.require('UserAnnotationHandler'); goog.require('constants'); goog.require('cursors.Cursor');
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output.js index e3240c1d..c5c691a 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output.js
@@ -22,7 +22,6 @@ goog.require('Spannable'); goog.require('TextLog'); goog.require('TtsCategory'); -goog.require('UserAnnotationHandler'); goog.require('ValueSelectionSpan'); goog.require('ValueSpan'); goog.require('constants'); @@ -760,12 +759,10 @@ options.annotation.push(new Output.SelectionSpan(0, 0)); } - const nameOrAnnotation = - UserAnnotationHandler.getAnnotationForNode(node) || node.name; if (localStorage['languageSwitching'] === 'true') { - this.assignLocaleAndAppend_(nameOrAnnotation, node, buff, options); + this.assignLocaleAndAppend_(node.name, node, buff, options); } else { - this.append_(buff, nameOrAnnotation || '', options); + this.append_(buff, node.name || '', options); } ruleStr.writeTokenWithValue(token, node.name);
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel_command.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel_command.js index 01ecc6c..c66061e9 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel_command.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel_command.js
@@ -75,10 +75,8 @@ ADD_ANNOTATION_SPEECH: 'add_annotation_speech', CLOSE_CHROMEVOX: 'close_chromevox', UPDATE_BRAILLE: 'update_braille', - OPEN_ANNOTATIONS_UI: 'open_annotations_ui', OPEN_MENUS: 'open_menus', OPEN_MENUS_MOST_RECENT: 'open_menus_most_recent', SEARCH: 'search', TUTORIAL: 'tutorial', - UPDATE_NOTES: 'update_notes', };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/annotations_ui.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/annotations_ui.js deleted file mode 100644 index 272437c..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/annotations_ui.js +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview ChromeVox Annotations UI. - */ - -goog.provide('AnnotationsUI'); - -AnnotationsUI = class { - /** - * @param {Element} input The annotations input in the panel. - * @param {!string} identifier A stringified NodeIdentifier. - */ - static init(input, identifier) { - AnnotationsUI.instance = new AnnotationsUI(identifier); - input.focus(); - input.addEventListener('keydown', AnnotationsUI.onKeyDown, false); - } - - /** - * @param {!string} identifier A stringified NodeIdentifier. - * @private - */ - constructor(identifier) { - this.identifier_ = identifier; - } - - /** - * @param {Event} event - */ - static onKeyDown(event) { - switch (event.key) { - case 'Enter': - AnnotationsUI.saveAnnotation(event.target.value); - break; - default: - return; - } - event.preventDefault(); - event.stopPropagation(); - } - - /** - * Revives |AnnotationsUI.instance.identifier_| and sets its annotation to - * |annotation|, if it's not empty. - * @param {string} annotation - */ - static saveAnnotation(annotation) { - // Revive identifier. - const identifier = - NodeIdentifier.constructFromString(AnnotationsUI.instance.identifier_); - chrome.extension.getBackgroundPage()['UserAnnotationHandler'] - .setAnnotationForIdentifier(identifier, annotation); - Panel.closeMenusAndRestoreFocus(); - } -};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.html b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.html index a1f2b8c2..e28b65c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.html +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.html
@@ -48,18 +48,6 @@ <div class="i18n" id="searchDescription" msgid="search_widget_description"></div> </div> - <div id="annotations-container" hidden> - <input class="i18n" msgid="annotations_widget_intro" id="annotations" - type="text"> - <div hidden id="save-annotation-label" class="i18n" - msgid="save_annotation"></div> - <div hidden id="discard-annotation-label" class="i18n" - msgid="discard_annotation"></div> - <button id="save-annotation" - aria-labelledby="save-annotation-label">Save</button> - <button id="discard-annotation" - aria-labelledby="discard-annotation-label">Discard</button> - </div> </div> <div id="options_close"> <div hidden id="options_title" class="i18n" msgid="options"></div>
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js index 1474cd9..9c3db99 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js
@@ -8,7 +8,6 @@ goog.provide('Panel'); -goog.require('AnnotationsUI'); goog.require('BrailleCommandData'); goog.require('CommandStore'); goog.require('EventGenerator'); @@ -24,7 +23,6 @@ goog.require('PanelMenu'); goog.require('PanelMenuItem'); goog.require('QueueMode'); -goog.require('UserAnnotationHandler'); /** * Class to manage the panel. @@ -56,7 +54,6 @@ }; chrome.loginState.getSessionState(updateSessionState); chrome.loginState.onSessionStateChanged.addListener(updateSessionState); - UserAnnotationHandler.init(); LocaleOutputHelper.init(); /** @type {Element} @private */ @@ -75,12 +72,6 @@ Panel.searchInput_ = $('search'); /** @type {Element} @private */ - Panel.annotationsContainer_ = $('annotations-container'); - - /** @type {Element} @private */ - Panel.annotationsInput_ = $('annotations'); - - /** @type {Element} @private */ Panel.brailleTableElement_ = $('braille-table'); Panel.brailleTableElement2_ = $('braille-table2'); @@ -113,19 +104,8 @@ */ Panel.activeMenu_ = null; - /** - * @type {Object} - * @private - */ - Panel.iTutorial = { - // Closure needs this to know about the showNextLesson function. - // Otherwise, Closure fires an error whenever calling showNextLesson(). - showNextLesson: () => { - throw new Error( - 'iTutorial should be assigned to the <i-tutorial> ' + - 'element before calling showNextLesson()'); - } - }; + /** @private {Object} */ + Panel.tutorial = null; Panel.setPendingCallback(null); Panel.updateFromPrefs(); @@ -146,9 +126,6 @@ $('menus_button').addEventListener('mousedown', Panel.onOpenMenus, false); $('options').addEventListener('click', Panel.onOptions, false); $('close').addEventListener('click', Panel.onClose, false); - $('discard-annotation') - .addEventListener('click', Panel.closeMenusAndRestoreFocus, false); - $('save-annotation').addEventListener('click', Panel.saveAnnotation, false); document.addEventListener('keydown', Panel.onKeyDown, false); document.addEventListener('mouseup', Panel.onMouseUp, false); @@ -164,7 +141,7 @@ Panel.ownerWindow = window; /** @private {boolean} */ - Panel.iTutorialReadyForTesting_ = false; + Panel.tutorialReadyForTesting_ = false; } /** @@ -174,19 +151,10 @@ if (Panel.mode_ === Panel.Mode.SEARCH) { Panel.speechContainer_.hidden = true; Panel.brailleContainer_.hidden = true; - Panel.annotationsContainer_.hidden = true; Panel.searchContainer_.hidden = false; return; } - if (Panel.mode_ === Panel.Mode.ANNOTATION) { - Panel.speechContainer_.hidden = true; - Panel.brailleContainer_.hidden = true; - Panel.searchContainer_.hidden = true; - Panel.annotationsContainer_.hidden = false; - return; - } - Panel.speechContainer_.hidden = false; Panel.brailleContainer_.hidden = false; Panel.searchContainer_.hidden = true; @@ -253,13 +221,6 @@ case PanelCommandType.TUTORIAL: Panel.onTutorial(); break; - case PanelCommandType.UPDATE_NOTES: - break; - case PanelCommandType.OPEN_ANNOTATIONS_UI: - if (typeof command.data === 'string') { - Panel.openAnnotationsUI(command.data); - } - break; case PanelCommandType.CLOSE_CHROMEVOX: Panel.onClose(); break; @@ -1084,9 +1045,6 @@ // Make sure all menus are cleared to avoid bogus output when we re-open. Panel.clearMenus(); - // Ensure annotations input is cleared. - Panel.annotationsInput_.value = ''; - // Make sure we're not in full-screen mode. Panel.setMode(Panel.Mode.COLLAPSED); @@ -1108,8 +1066,8 @@ } Panel.setMode(Panel.Mode.FULLSCREEN_TUTORIAL); - if (Panel.iTutorial.show) { - Panel.iTutorial.show(); + if (Panel.tutorial && Panel.tutorial.show) { + Panel.tutorial.show(); } } @@ -1135,7 +1093,7 @@ } tutorialContainer.appendChild(tutorialElement); document.body.appendChild(tutorialContainer); - Panel.iTutorial = tutorialElement; + Panel.tutorial = tutorialElement; // Add listeners. These are custom events fired from custom components. const backgroundPage = chrome.extension.getBackgroundPage(); @@ -1170,7 +1128,9 @@ const actions = evt.detail.actions; chromeVoxStateInstance.createUserActionMonitor(actions, () => { chromeVoxStateInstance.destroyUserActionMonitor(); - Panel.iTutorial.showNextLesson(); + if (Panel.tutorial && Panel.tutorial.showNextLesson) { + Panel.tutorial.showNextLesson(); + } }); }); $('chromevox-tutorial').addEventListener('stopinteractivemode', (evt) => { @@ -1185,7 +1145,7 @@ backgroundPage['ChromeVox']['earcons']['playEarcon'](earconId); }); $('chromevox-tutorial').addEventListener('readyfortesting', () => { - Panel.iTutorialReadyForTesting_ = true; + Panel.tutorialReadyForTesting_ = true; }); $('chromevox-tutorial').addEventListener('openUrl', (evt) => { const url = evt.detail.url; @@ -1252,23 +1212,6 @@ } Panel.searchMenu.activateItem(0); } - - /** - * Initializes the annotations UI. - * @param {!string} identifier - */ - static openAnnotationsUI(identifier) { - Panel.setMode(Panel.Mode.ANNOTATION); - Panel.annotationsInput_.value = ''; - AnnotationsUI.init(Panel.annotationsInput_, identifier); - } - - /** - * Creates a new annotation using the contents of |annotationsInput|. - */ - static saveAnnotation() { - AnnotationsUI.saveAnnotation(Panel.annotationsInput_.value); - } }; /** @@ -1280,8 +1223,8 @@ onCurrentRangeChanged(range) { if (Panel.mode_ === Panel.Mode.FULLSCREEN_TUTORIAL) { - if (Panel.iTutorial && Panel.iTutorial.restartNudges) { - Panel.iTutorial.restartNudges(); + if (Panel.tutorial && Panel.tutorial.restartNudges) { + Panel.tutorial.restartNudges(); } } } @@ -1291,7 +1234,6 @@ * @enum {string} */ Panel.Mode = { - ANNOTATION: 'annotation', COLLAPSED: 'collapsed', FOCUSED: 'focused', FULLSCREEN_MENUS: 'menus', @@ -1303,7 +1245,6 @@ * @type {!Object<string, {title: string, location: (string|undefined)}>} */ Panel.ModeInfo = { - annotation: {title: 'panel_title', location: '#focus'}, collapsed: {title: 'panel_title', location: '#'}, focused: {title: 'panel_title', location: '#focus'}, menus: {title: 'panel_menus_title', location: '#fullscreen'},
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js index ac9ca3d..924a3b34 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
@@ -11,11 +11,11 @@ */ ChromeVoxTutorialTest = class extends ChromeVoxPanelTestBase { assertActiveLessonIndex(expectedIndex) { - assertEquals(expectedIndex, this.getPanel().iTutorial.activeLessonIndex); + assertEquals(expectedIndex, this.getTutorial().activeLessonIndex); } assertActiveScreen(expectedScreen) { - assertEquals(expectedScreen, this.getPanel().iTutorial.activeScreen); + assertEquals(expectedScreen, this.getTutorial().activeScreen); } async launchAndWaitForTutorial() { @@ -26,9 +26,7 @@ }); } - /** - * Waits for the interactive tutorial to load. - */ + /** Waits for the tutorial to load. */ async waitForTutorial() { return new Promise(resolve => { const doc = this.getPanelWindow().document; @@ -47,10 +45,10 @@ // Once the tutorial has been added to the document, we need // to wait for the lesson templates to load. const panel = this.getPanel(); - if (panel.iTutorialReadyForTesting_) { + if (panel.tutorialReadyForTesting_) { resolve(); } else { - panel.iTutorial.addEventListener('readyfortesting', () => { + panel.tutorial.addEventListener('readyfortesting', () => { resolve(); }); } @@ -68,6 +66,10 @@ }); } + getTutorial() { + return this.getPanel().tutorial; + } + get simpleDoc() { return ` <p>Some web content</p> @@ -108,7 +110,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('nextObject')) .expectSpeech('Quick orientation') @@ -142,7 +144,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('nextObject')) .expectSpeech('Quick orientation') @@ -168,7 +170,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('nextObject')) .expectSpeech('Quick orientation') @@ -196,7 +198,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); const giveNudge = () => { tutorial.giveNudge(); }; @@ -224,7 +226,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); const giveNudge = () => { tutorial.giveNudge(); }; @@ -260,7 +262,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('previousButton')) .expectSpeech('Exit tutorial') @@ -275,7 +277,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(() => { // Press Escape. @@ -295,7 +297,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(this.assertActiveScreen.bind(this, 'main_menu')) .call(doCmd('nextObject')) @@ -322,7 +324,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(this.assertActiveScreen.bind(this, 'main_menu')) .call(doCmd('nextObject')) @@ -353,7 +355,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(() => { tutorial.curriculum = 'essential_keys'; @@ -381,7 +383,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('nextObject')) .expectSpeech('Quick orientation') @@ -406,7 +408,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('nextObject')) .expectSpeech('Quick orientation') @@ -430,7 +432,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); const nextObjectAndExpectSpeechAndEarcon = (speech, earcon) => { mockFeedback.call(doCmd('nextObject')) .expectSpeech(speech) @@ -461,7 +463,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); const keyboardHandler = ChromeVoxState.instance.keyboardHandler_; // Helper functions. For this test, activate commands by hooking into the @@ -525,7 +527,7 @@ TEST_F('ChromeVoxTutorialTest', 'RestartNudges', function() { this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); let restart = false; // Swap in below function to track when nudges get restarted. tutorial.restartNudges = () => { @@ -569,7 +571,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(() => { tutorial.curriculum = 'resources'; @@ -593,7 +595,7 @@ const mockFeedback = this.createMockFeedback(); this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); mockFeedback.expectSpeech('ChromeVox tutorial') .call(doCmd('nextObject')) .expectSpeech('Quick orientation') @@ -627,7 +629,7 @@ TEST_F('ChromeVoxTutorialTest', 'StartStopInteractiveMode', function() { this.runWithLoadedTree(this.simpleDoc, async function(root) { await this.launchAndWaitForTutorial(); - const tutorial = this.getPanel().iTutorial; + const tutorial = this.getTutorial(); let userActionMonitorCreatedCount = 0; let userActionMonitorDestroyedCount = 0; let isUserActionMonitorActive = false;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/practice_areas/jump_commands.html b/chrome/browser/resources/chromeos/accessibility/chromevox/tutorial/practice_areas/jump_commands.html similarity index 100% rename from chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/practice_areas/jump_commands.html rename to chrome/browser/resources/chromeos/accessibility/chromevox/tutorial/practice_areas/jump_commands.html
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/practice_areas/selects.html b/chrome/browser/resources/chromeos/accessibility/chromevox/tutorial/practice_areas/selects.html similarity index 100% rename from chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/practice_areas/selects.html rename to chrome/browser/resources/chromeos/accessibility/chromevox/tutorial/practice_areas/selects.html
diff --git a/chrome/browser/resources/chromeos/accessibility/common/tutorial/tutorial_lesson.js b/chrome/browser/resources/chromeos/accessibility/common/tutorial/tutorial_lesson.js index 900dce6..db27a1e9 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/tutorial/tutorial_lesson.js +++ b/chrome/browser/resources/chromeos/accessibility/common/tutorial/tutorial_lesson.js
@@ -134,7 +134,7 @@ * @private */ populatePracticeContent() { - const path = '../i_tutorial/practice_areas/' + this.practiceFile + '.html'; + const path = '../tutorial/practice_areas/' + this.practiceFile + '.html'; const xhr = new XMLHttpRequest(); xhr.open('GET', path, true); xhr.onload = (evt) => {
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.html b/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.html index 3e49b8ca..0386511 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.html +++ b/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.html
@@ -18,8 +18,8 @@ <dom-module id="oobe-content-dialog"> <template> <style include="oobe-dialog-host"></style> - <oobe-dialog id="dialog" has-buttons hide-shadow$="[[hideShadow]]" - no-lazy$="[[noLazy]]" no-header + <oobe-dialog id="dialog" has-buttons="[[!noButtons]]" + hide-shadow$="[[hideShadow]]" no-lazy$="[[noLazy]]" no-header no-footer-padding$="[[noFooterPadding]]" footer-shrinkable$="[[footerShrinkable]]"> <slot slot="footer" name="content"></slot>
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.js b/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.js index 7b347002ad..16aa599 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.js +++ b/chrome/browser/resources/chromeos/login/components/oobe_content_dialog/oobe_content_dialog_old.js
@@ -39,6 +39,14 @@ type: Boolean, value: false, }, + + /** + * Supports loading dialog which is shown without buttons. + */ + noButtons: { + type: Boolean, + value: false, + }, }, focus() {
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_loading_dialog/oobe_loading_dialog.html b/chrome/browser/resources/chromeos/login/components/oobe_loading_dialog/oobe_loading_dialog.html index a21b4ac..67aa429 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_loading_dialog/oobe_loading_dialog.html +++ b/chrome/browser/resources/chromeos/login/components/oobe_loading_dialog/oobe_loading_dialog.html
@@ -25,7 +25,7 @@ color: #747474; } </style> - <oobe-content-dialog role="dialog" no-footer-padding> + <oobe-content-dialog role="dialog" no-footer-padding no-buttons> <div slot="content" class="flex layout vertical center center-justified"> <paper-spinner-lite dir="ltr" active></paper-spinner-lite> <div id="comment" aria-live="polite" class="focus-on-show"
diff --git a/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js b/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js index 4e0df55d..8737212 100644 --- a/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js +++ b/chrome/browser/resources/chromeos/password_change/lock_screen_reauth.js
@@ -17,6 +17,11 @@ import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +const clearDataType = { + appcache: true, + cache: true, + cookies: true, +}; Polymer({ is: 'lock-reauth', @@ -62,6 +67,8 @@ ready() { this.signinFrame_ = this.getSigninFrame_(); this.authenticator_ = new cr.login.Authenticator(this.signinFrame_); + this.authenticator_.addEventListener( + 'authCompleted', this.onAuthCompletedMessage_.bind(this)); chrome.send('initialize'); }, @@ -69,7 +76,7 @@ * Loads the authentication parameter into the iframe. * @param {!Object} data authenticator parameters bag. */ - LoadAuthenticatorParam(data) { + loadAuthenticator(data) { this.authenticator_.setWebviewPartition(data.webviewPartitionName); let params = {}; for (let i in cr.login.Authenticator.SUPPORTED_PARAMS) { @@ -84,6 +91,19 @@ chrome.send('authenticatorLoaded'); }, + + /** + * This function is used when the wrong user is verified correctly + * It reset authenticator state and display error message. + */ + resetAuthenticator() { + this.signinFrame_.clearData({since: 0}, clearDataType, () => { + this.authenticator_.resetStates(); + this.isButtonsEnabled_ = true; + this.isErrorDisplayed_ = true; + }); + }, + /** * @return {!Element} * @private @@ -97,10 +117,19 @@ return signinFrame; }, + onAuthCompletedMessage_(e) { + let credentials = e.detail; + chrome.send('completeAuthentication', [ + credentials.gaiaId, credentials.email, credentials.password, + credentials.usingSAML, credentials.services, + credentials.passwordAttributes + ]); + }, + /** @private */ onVerify_() { this.authenticator_.load( - cr.login.Authenticator.AuthMode.DEFAULT, this.authenticatorParams_); + cr.login.Authenticator.AuthMode.DEFAULT, this.authenticatorParams_); this.isButtonsEnabled_ = false; this.isVerifyUser_ = false; this.isErrorDisplayed_ = false;
diff --git a/chrome/browser/resources/inline_login/inline_login_app.html b/chrome/browser/resources/inline_login/inline_login_app.html index 3490bcf..5693827 100644 --- a/chrome/browser/resources/inline_login/inline_login_app.html +++ b/chrome/browser/resources/inline_login/inline_login_app.html
@@ -22,10 +22,13 @@ } <if expr="chromeos"> - /* Content of the webview already has 64px border, add negative margin to make - * distance to the top 64px. */ #addAccount { + /* Content of the webview already has 64px border, add negative margin to + * make distance to the top 64px. */ margin-top: calc(-1 * var(--dialog-top-border-size)); + /* margin-bottom = padding below button + button height + * + padding above button. */ + margin-bottom: calc(3 * 32px); } /* Make distance to the top 64px. */ #welcome {
diff --git a/chrome/browser/resources/pdf/pdf_viewer_base.js b/chrome/browser/resources/pdf/pdf_viewer_base.js index 99267222..76291a0 100644 --- a/chrome/browser/resources/pdf/pdf_viewer_base.js +++ b/chrome/browser/resources/pdf/pdf_viewer_base.js
@@ -186,7 +186,6 @@ plugin.setAttribute('headers', headers); plugin.setAttribute('background-color', this.getBackgroundColor()); - plugin.setAttribute('top-toolbar-height', 0); const javascript = this.browserApi.getStreamInfo().javascript || 'block'; plugin.setAttribute('javascript', javascript);
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index fe8e6228..6450053 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -467,6 +467,7 @@ "chromeos/personalization_page/wallpaper_subpage.m.js", "chromeos/pref_to_setting_metric_converter.m.js", "chromeos/route_origin_behavior.m.js", + "chromeos/search_handler.m.js", "controls/controlled_button.m.js", "controls/controlled_radio_button.m.js", "controls/extension_controlled_indicator.m.js", @@ -1204,18 +1205,16 @@ is_polymer3 = true deps = [ ":metrics_recorder.m", - - # ":os_icons.m", + ":os_icons.m", ":os_page_visibility.m", ":os_route.m", # ":os_settings.m", - # ":os_settings_icons_css.m", + ":os_settings_icons_css.m", ":os_settings_routes.m", ":pref_to_setting_metric_converter.m", ":route_origin_behavior.m", - - #":search_handler.m", + ":search_handler.m", ] } @@ -1242,7 +1241,7 @@ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_icons.m.js", ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":os_icons_module" ] } @@ -1269,9 +1268,6 @@ js_library("os_settings_icons_css.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_settings_icons_css.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":os_settings_icons_css_module" ] } @@ -1298,9 +1294,6 @@ js_library("search_handler.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/search_handler.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":modulize" ] } @@ -1369,12 +1362,16 @@ js_file = "os_icons.m.js" html_file = "os_icons.html" html_type = "iron-iconset" + auto_imports = os_settings_auto_imports + namespace_rewrites = os_settings_namespace_rewrites } polymer_modulizer("os_settings_icons_css") { js_file = "os_settings_icons_css.m.js" html_file = "os_settings_icons_css.html" html_type = "style-module" + auto_imports = os_settings_auto_imports + namespace_rewrites = os_settings_namespace_rewrites } js_modulizer("modulize") {
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index d9fa838..c2a4716 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -35,6 +35,7 @@ "settings.FingerprintResultType|FingerprintResultType", "settings.FingerprintScan|FingerprintScan", "settings.FingerprintSetupStep|FingerprintSetupStep", + "settings.getSearchHandler|getSearchHandler", "settings.GlobalScrollTargetBehavior|GlobalScrollTargetBehavior", "settings.GoogleAssistantBrowserProxy|GoogleAssistantBrowserProxy", "settings.GoogleAssistantBrowserProxyImpl|GoogleAssistantBrowserProxyImpl", @@ -92,6 +93,7 @@ "settings.recordSettingChange|recordSettingChange", "settings.Router|Router", "settings.routes|routes", + "settings.setSearchHandlerForTesting|setSearchHandlerForTesting", "settings.SmartLockSignInEnabledState|SmartLockSignInEnabledState", "settings.TimeZoneAutoDetectMethod|TimeZoneAutoDetectMethod", "settings.TimeZoneBrowserProxy|TimeZoneBrowserProxy", @@ -159,6 +161,7 @@ "chrome/browser/resources/settings/about_page/about_page_browser_proxy.html|AboutPageBrowserProxyImpl,AboutPageUpdateInfo,AboutPageBrowserProxy,browserChannelToI18nId,VersionInfo,ChannelInfo,BrowserChannel,isTargetChannelMoreStable,UpdateStatus,UpdateStatusChangedEvent,RegulatoryInfo,TPMFirmwareUpdateStatusChangedEvent", "chrome/browser/resources/settings/chromeos/os_about_page/device_name_browser_proxy.html|DeviceNameBrowserProxy,DeviceNameBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.html|MainPageBehavior", + "chrome/browser/resources/settings/chromeos/searh_handler.html|getSearchHandler, setSearchHandlerForTesting", "ui/webui/resources/cr_components/chromeos/network/network_listener_behavior.html|NetworkListenerBehavior", "ui/webui/resources/cr_elements/cr_slider/cr_slider.html|SliderTick", "ui/webui/resources/html/assert.html|assert,assertNotReached",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index 6b63d2b..4f6d91f 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -49,6 +49,8 @@ import './os_about_page/detailed_build_info.m.js'; import './os_about_page/update_warning_dialog.m.js'; import './os_search_page/os_search_page.m.js'; +import './os_icons.m.js'; +import './os_settings_icons_css.m.js'; export {AboutPageBrowserProxyImpl, BrowserChannel, UpdateStatus} from '../about_page/about_page_browser_proxy.m.js'; export {LifetimeBrowserProxy, LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.m.js'; @@ -89,3 +91,4 @@ export {ParentalControlsBrowserProxy, ParentalControlsBrowserProxyImpl} from './parental_controls_page/parental_controls_browser_proxy.m.js'; export {ChangePictureBrowserProxy, ChangePictureBrowserProxyImpl} from './personalization_page/change_picture_browser_proxy.m.js'; export {WallpaperBrowserProxyImpl} from './personalization_page/wallpaper_browser_proxy.m.js'; +export {setSearchHandlerForTesting, getSearchHandler} from './search_handler.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/search_handler.js b/chrome/browser/resources/settings/chromeos/search_handler.js index 40774f0..ae23ff9 100644 --- a/chrome/browser/resources/settings/chromeos/search_handler.js +++ b/chrome/browser/resources/settings/chromeos/search_handler.js
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +// #import '../constants/routes.mojom-lite.js'; + /** * @fileoverview * Provides functions used for OS settings search. @@ -16,7 +19,7 @@ * @param {!chromeos.settings.mojom.SearchHandlerInterface} * testSearchHandler A test search handler. */ - function setSearchHandlerForTesting(testSearchHandler) { + /* #export */ function setSearchHandlerForTesting(testSearchHandler) { settingsSearchHandler = testSearchHandler; }
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index b4a2211..bfaffe55 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -89,19 +89,6 @@ DISALLOW_COPY_AND_ASSIGN(SingleClientBookmarksSyncTest); }; -class SingleClientBookmarksSyncTestWithDisabledCommitWithoutFavicon - : public SyncTest { - public: - SingleClientBookmarksSyncTestWithDisabledCommitWithoutFavicon() - : SyncTest(SINGLE_CLIENT) { - features_override_.InitAndEnableFeature( - switches::kSyncDoNotCommitBookmarksWithoutFavicon); - } - - private: - base::test::ScopedFeatureList features_override_; -}; - class SingleClientBookmarksSyncTestWithEnabledReuploadRemoteBookmarks : public SingleClientBookmarksSyncTest { public: @@ -1361,9 +1348,8 @@ .Wait()); } -IN_PROC_BROWSER_TEST_F( - SingleClientBookmarksSyncTestWithDisabledCommitWithoutFavicon, - PRE_ShouldUploadUnsyncedEntityAfterRestart) { +IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, + PRE_ShouldUploadUnsyncedEntityAfterRestart) { ASSERT_TRUE(SetupSync()); const std::string title = "Title"; @@ -1389,9 +1375,8 @@ SetTitle(kSingleProfileIndex, bookmark, new_title); } -IN_PROC_BROWSER_TEST_F( - SingleClientBookmarksSyncTestWithDisabledCommitWithoutFavicon, - ShouldUploadUnsyncedEntityAfterRestart) { +IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, + ShouldUploadUnsyncedEntityAfterRestart) { ASSERT_TRUE(SetupClients()); const std::string title = "Title";
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 42dd7f8..da4995a 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2738,6 +2738,7 @@ "//components/services/app_service/public/cpp:instance_update", "//components/session_manager/core", "//components/user_manager", + "//extensions/browser/api/messaging", "//extensions/browser/api/vpn_provider", "//google_apis/drive", "//media/capture:capture_lib", @@ -3419,8 +3420,6 @@ if (toolkit_views) { sources += [ - "autofill/address_profiles/save_address_profile_bubble_controller.cc", - "autofill/address_profiles/save_address_profile_bubble_controller.h", "autofill/autofill_bubble_base.h", "autofill/autofill_bubble_controller_base.cc", "autofill/autofill_bubble_controller_base.h", @@ -3444,6 +3443,8 @@ "autofill/payments/save_upi_bubble_controller.h", "autofill/payments/save_upi_bubble_controller_impl.cc", "autofill/payments/save_upi_bubble_controller_impl.h", + "autofill/save_address_profile_bubble_controller.cc", + "autofill/save_address_profile_bubble_controller.h", "bubble_anchor_util.h", "manifest_web_app_browser_controller.cc", "manifest_web_app_browser_controller.h", @@ -3489,8 +3490,6 @@ "views/apps/app_info_dialog/app_info_summary_panel.h", "views/apps/chrome_native_app_window_views.cc", "views/apps/chrome_native_app_window_views.h", - "views/autofill/address_profiles/save_address_profile_view.cc", - "views/autofill/address_profiles/save_address_profile_view.h", "views/autofill/autofill_bubble_handler_impl.cc", "views/autofill/autofill_bubble_handler_impl.h", "views/autofill/autofill_popup_base_view.cc", @@ -3526,6 +3525,8 @@ "views/autofill/payments/save_payment_icon_view.h", "views/autofill/payments/save_upi_offer_bubble_views.cc", "views/autofill/payments/save_upi_offer_bubble_views.h", + "views/autofill/save_address_profile_view.cc", + "views/autofill/save_address_profile_view.h", "views/bookmarks/bookmark_bar_view.cc", "views/bookmarks/bookmark_bar_view.h", "views/bookmarks/bookmark_bar_view_observer.h",
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index e5c28455..e8597f1 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2213,6 +2213,9 @@ <message name="IDS_PWA_INSTALL_BOTTOM_SHEET_ACCESSIBILITY" desc="The content description for the bottom sheet install UI."> Install this app </message> + <message name="IDS_IMAGE_ZOOM_CONTENT_DESCRIPTION" desc="The content description string for the screenshot in the image zoom view."> + Screenshot. Tap to close. + </message> <!-- Page info popup --> <message name="IDS_PAGE_INFO_CONNECTION_OFFLINE" desc="Message to display in the page info bubble when viewing and offline page.">
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_IMAGE_ZOOM_CONTENT_DESCRIPTION.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_IMAGE_ZOOM_CONTENT_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..9ad7a83 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_IMAGE_ZOOM_CONTENT_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +2c6da52d45c43b8fac75fd0d43d87a8d855e95e5 \ No newline at end of file
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc index b30d1948..8bcb8e4 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc
@@ -15,9 +15,9 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_id.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index f9815b6..dc8b13b 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -28,10 +28,10 @@ #include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/translate/chrome_translate_client.h" -#include "chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h" #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" #include "chrome/browser/ui/autofill/payments/create_card_unmask_prompt_view.h" #include "chrome/browser/ui/autofill/payments/credit_card_scanner_controller.h" +#include "chrome/browser/ui/autofill/save_address_profile_bubble_controller.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/page_info/page_info_dialog.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
diff --git a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.cc b/chrome/browser/ui/autofill/save_address_profile_bubble_controller.cc similarity index 95% rename from chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.cc rename to chrome/browser/ui/autofill/save_address_profile_bubble_controller.cc index 6b8d3c11..18c7ffd 100644 --- a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.cc +++ b/chrome/browser/ui/autofill/save_address_profile_bubble_controller.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h" +#include "chrome/browser/ui/autofill/save_address_profile_bubble_controller.h" #include "chrome/browser/ui/autofill/autofill_bubble_handler.h" #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h b/chrome/browser/ui/autofill/save_address_profile_bubble_controller.h similarity index 88% rename from chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h rename to chrome/browser/ui/autofill/save_address_profile_bubble_controller.h index d50ae44..4251312 100644 --- a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h +++ b/chrome/browser/ui/autofill/save_address_profile_bubble_controller.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_AUTOFILL_ADDRESS_PROFILES_SAVE_ADDRESS_PROFILE_BUBBLE_CONTROLLER_H_ -#define CHROME_BROWSER_UI_AUTOFILL_ADDRESS_PROFILES_SAVE_ADDRESS_PROFILE_BUBBLE_CONTROLLER_H_ +#ifndef CHROME_BROWSER_UI_AUTOFILL_SAVE_ADDRESS_PROFILE_BUBBLE_CONTROLLER_H_ +#define CHROME_BROWSER_UI_AUTOFILL_SAVE_ADDRESS_PROFILE_BUBBLE_CONTROLLER_H_ #include "base/strings/string16.h" #include "chrome/browser/ui/autofill/autofill_bubble_controller_base.h" @@ -61,4 +61,4 @@ } // namespace autofill -#endif // CHROME_BROWSER_UI_AUTOFILL_ADDRESS_PROFILES_SAVE_ADDRESS_PROFILE_BUBBLE_CONTROLLER_H_ +#endif // CHROME_BROWSER_UI_AUTOFILL_SAVE_ADDRESS_PROFILE_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_browsertest.cc b/chrome/browser/ui/autofill/save_address_profile_bubble_controller_browsertest.cc similarity index 95% rename from chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_browsertest.cc rename to chrome/browser/ui/autofill/save_address_profile_bubble_controller_browsertest.cc index 357da6ac..b436d43 100644 --- a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_browsertest.cc +++ b/chrome/browser/ui/autofill/save_address_profile_bubble_controller_browsertest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h" +#include "chrome/browser/ui/autofill/save_address_profile_bubble_controller.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_unittest.cc b/chrome/browser/ui/autofill/save_address_profile_bubble_controller_unittest.cc similarity index 91% rename from chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_unittest.cc rename to chrome/browser/ui/autofill/save_address_profile_bubble_controller_unittest.cc index a872624..c692076 100644 --- a/chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_unittest.cc +++ b/chrome/browser/ui/autofill/save_address_profile_bubble_controller_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h" +#include "chrome/browser/ui/autofill/save_address_profile_bubble_controller.h" #include "base/test/scoped_feature_list.h" #include "chrome/test/base/browser_with_test_window_test.h"
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index f1250d0..4b84e7a 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -608,11 +608,7 @@ DCHECK(ContainsIndex(index)); - // Ensure pinned and non-pinned tabs do not mix. - const int first_non_pinned_tab = IndexOfFirstNonPinnedTab(); - to_position = IsTabPinned(index) - ? std::min(first_non_pinned_tab - 1, to_position) - : std::max(first_non_pinned_tab, to_position); + to_position = ConstrainMoveIndex(to_position, IsTabPinned(index)); if (index == to_position) return to_position; @@ -1619,12 +1615,19 @@ delegate_->ShouldRunUnloadListenerBeforeClosing(contents); } -int TabStripModel::ConstrainInsertionIndex(int index, bool pinned_tab) { +int TabStripModel::ConstrainInsertionIndex(int index, bool pinned_tab) const { return pinned_tab ? base::ClampToRange(index, 0, IndexOfFirstNonPinnedTab()) : base::ClampToRange(index, IndexOfFirstNonPinnedTab(), count()); } +int TabStripModel::ConstrainMoveIndex(int index, bool pinned_tab) const { + return pinned_tab + ? base::ClampToRange(index, 0, IndexOfFirstNonPinnedTab() - 1) + : base::ClampToRange(index, IndexOfFirstNonPinnedTab(), + count() - 1); +} + std::vector<int> TabStripModel::GetIndicesForCommand(int index) const { if (!IsTabSelected(index)) return {index};
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index 604afd63..c61701b6 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -611,7 +611,9 @@ bool RunUnloadListenerBeforeClosing(content::WebContents* contents); bool ShouldRunUnloadListenerBeforeClosing(content::WebContents* contents); - int ConstrainInsertionIndex(int index, bool pinned_tab); + int ConstrainInsertionIndex(int index, bool pinned_tab) const; + + int ConstrainMoveIndex(int index, bool pinned_tab) const; // If |index| is selected all the selected indices are returned, otherwise a // vector with |index| is returned. This is used when executing commands to
diff --git a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc index b8c70e74..bafabd6 100644 --- a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc +++ b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/ui/autofill/payments/save_card_ui.h" #include "chrome/browser/ui/autofill/payments/save_upi_bubble.h" #include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.h" #include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h" #include "chrome/browser/ui/views/autofill/payments/save_card_bubble_views.h" @@ -19,6 +18,7 @@ #include "chrome/browser/ui/views/autofill/payments/save_card_manage_cards_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/save_upi_offer_bubble_views.h" +#include "chrome/browser/ui/views/autofill/save_address_profile_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
diff --git a/chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.cc b/chrome/browser/ui/views/autofill/save_address_profile_view.cc similarity index 88% rename from chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.cc rename to chrome/browser/ui/views/autofill/save_address_profile_view.cc index ebac7a0..1cd6cac5 100644 --- a/chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.cc +++ b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.h" +#include "chrome/browser/ui/views/autofill/save_address_profile_view.h" -#include "chrome/browser/ui/autofill/address_profiles/save_address_profile_bubble_controller.h" +#include "chrome/browser/ui/autofill/save_address_profile_bubble_controller.h" #include "components/autofill/core/common/autofill_features.h" namespace autofill {
diff --git a/chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.h b/chrome/browser/ui/views/autofill/save_address_profile_view.h similarity index 82% rename from chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.h rename to chrome/browser/ui/views/autofill/save_address_profile_view.h index b24cc6c..9aae948 100644 --- a/chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.h +++ b/chrome/browser/ui/views/autofill/save_address_profile_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_ADDRESS_PROFILES_SAVE_ADDRESS_PROFILE_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_ADDRESS_PROFILES_SAVE_ADDRESS_PROFILE_VIEW_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_ADDRESS_PROFILE_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_ADDRESS_PROFILE_VIEW_H_ #include "chrome/browser/ui/autofill/autofill_bubble_base.h" #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" @@ -44,4 +44,4 @@ } // namespace autofill -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_ADDRESS_PROFILES_SAVE_ADDRESS_PROFILE_VIEW_H_ +#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_ADDRESS_PROFILE_VIEW_H_
diff --git a/chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view_unittest.cc b/chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc similarity index 96% rename from chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view_unittest.cc rename to chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc index e1a20de..fd6c888b 100644 --- a/chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view_unittest.cc +++ b/chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/autofill/address_profiles/save_address_profile_view.h" +#include "chrome/browser/ui/views/autofill/save_address_profile_view.h" #include "base/test/scoped_feature_list.h" #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc index 61633578..48044f18 100644 --- a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc
@@ -33,6 +33,7 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/grid_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/widget/widget.h" namespace chrome { @@ -122,3 +123,7 @@ 0, provider->GetDistanceMetric( views::DISTANCE_DIALOG_SCROLLABLE_AREA_MAX_HEIGHT)); } + +BEGIN_METADATA(ExtensionInstallBlockedDialogView, + views::BubbleDialogDelegateView) +END_METADATA
diff --git a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.h b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.h index f63a4b5..89a014e2 100644 --- a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.h +++ b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.h
@@ -13,6 +13,7 @@ #include "ui/gfx/image/image_skia.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/button/button.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" namespace gfx { @@ -24,6 +25,7 @@ class ExtensionInstallBlockedDialogView : public views::BubbleDialogDelegateView { public: + METADATA_HEADER(ExtensionInstallBlockedDialogView); ExtensionInstallBlockedDialogView(const std::string& extension_name, const base::string16& custom_error_message, const gfx::ImageSkia& icon,
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc index e89bcb4..77b06af7 100644 --- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc +++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
@@ -38,6 +38,8 @@ #include "ui/views/controls/label.h" #include "ui/views/controls/link.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/metadata/metadata_header_macros.h" +#include "ui/views/metadata/metadata_impl_macros.h" #if !BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.h" @@ -118,9 +120,13 @@ class ExtensionInstalledBubbleView : public BubbleSyncPromoDelegate, public views::BubbleDialogDelegateView { public: + METADATA_HEADER(ExtensionInstalledBubbleView); ExtensionInstalledBubbleView( Browser* browser, std::unique_ptr<ExtensionInstalledBubbleModel> model); + ExtensionInstalledBubbleView(const ExtensionInstalledBubbleView&) = delete; + ExtensionInstalledBubbleView& operator=(const ExtensionInstalledBubbleView&) = + delete; ~ExtensionInstalledBubbleView() override; static void Show(Browser* browser, @@ -142,8 +148,6 @@ Browser* const browser_; const std::unique_ptr<ExtensionInstalledBubbleModel> model_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionInstalledBubbleView); }; // static @@ -269,6 +273,9 @@ GetWidget()->Close(); } +BEGIN_METADATA(ExtensionInstalledBubbleView, views::BubbleDialogDelegateView) +END_METADATA + void ShowUiOnToolbarMenu(scoped_refptr<const extensions::Extension> extension, Browser* browser, const SkBitmap& icon) {
diff --git a/chrome/browser/ui/views/hats/hats_next_web_dialog.cc b/chrome/browser/ui/views/hats/hats_next_web_dialog.cc index 1219bb03..c874b01 100644 --- a/chrome/browser/ui/views/hats/hats_next_web_dialog.cc +++ b/chrome/browser/ui/views/hats/hats_next_web_dialog.cc
@@ -34,6 +34,7 @@ #include "ui/views/controls/webview/web_dialog_view.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/web_dialogs/web_dialog_delegate.h" constexpr gfx::Size HatsNextWebDialog::kMinSize; @@ -270,3 +271,7 @@ bool HatsNextWebDialog::IsWaitingForSurveyForTesting() { return loading_timer_.IsRunning(); } + +BEGIN_METADATA(HatsNextWebDialog, views::BubbleDialogDelegateView) +ADD_READONLY_PROPERTY_METADATA(GURL, ParameterizedHatsURL) +END_METADATA
diff --git a/chrome/browser/ui/views/hats/hats_next_web_dialog.h b/chrome/browser/ui/views/hats/hats_next_web_dialog.h index 30d02f2..b4d97958b 100644 --- a/chrome/browser/ui/views/hats/hats_next_web_dialog.h +++ b/chrome/browser/ui/views/hats/hats_next_web_dialog.h
@@ -9,6 +9,7 @@ #include "content/public/browser/web_contents_observer.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/webview/web_dialog_view.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/window/dialog_delegate.h" #include "ui/web_dialogs/web_dialog_delegate.h" @@ -29,6 +30,7 @@ public content::WebContentsDelegate, public ProfileObserver { public: + METADATA_HEADER(HatsNextWebDialog); HatsNextWebDialog(Browser* browser, const std::string& trigger_id, base::OnceClosure success_callback,
diff --git a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc index bce65401..04ac2b5 100644 --- a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc
@@ -16,6 +16,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/style/typography.h" namespace media_router { @@ -141,4 +142,7 @@ // static MediaRemotingDialogView* MediaRemotingDialogView::instance_ = nullptr; +BEGIN_METADATA(MediaRemotingDialogView, views::BubbleDialogDelegateView) +END_METADATA + } // namespace media_router
diff --git a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.h b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.h index 85c93073..a6a0f25 100644 --- a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.h +++ b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_MEDIA_REMOTING_DIALOG_VIEW_H_ #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/metadata/metadata_header_macros.h" class MediaRouterActionController; class PrefService; @@ -26,6 +27,10 @@ // then mirroring it remotely. class MediaRemotingDialogView : public views::BubbleDialogDelegateView { public: + METADATA_HEADER(MediaRemotingDialogView); + MediaRemotingDialogView(const MediaRemotingDialogView&) = delete; + MediaRemotingDialogView& operator=(const MediaRemotingDialogView&) = delete; + using PermissionCallback = base::OnceCallback<void(bool)>; // Checks the existing preference value, and if unset, instantiates and shows // the singleton dialog to get user's permission. |callback| runs on the same @@ -66,8 +71,6 @@ // sticky. If this is checked, we record the preference and don't show the // dialog again. views::Checkbox* remember_choice_checkbox_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(MediaRemotingDialogView); }; } // namespace media_router
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc index 222a485..a8da2bb3 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
@@ -41,6 +41,7 @@ #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/layout_provider.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/style/platform_style.h" #include "ui/views/widget/widget.h" @@ -51,7 +52,6 @@ PermissionPromptStyle prompt_style) : browser_(browser), delegate_(delegate), - name_or_origin_(GetDisplayNameOrOrigin()), permission_requested_time_(permission_requested_time) { // Note that browser_ may be null in unit tests. DCHECK(delegate_); @@ -61,7 +61,7 @@ // as the default action. SetDefaultButton(ui::DIALOG_BUTTON_NONE); - if (ShouldShowAllowThisTimeButton()) { + if (GetShowAllowThisTimeButton()) { // Host every button in the extra_view to have full control over the width // of the dialog. SetButtons(ui::DIALOG_BUTTON_NONE); @@ -247,7 +247,7 @@ } void PermissionPromptBubbleView::AddedToWidget() { - if (name_or_origin_.is_origin) { + if (GetDisplayNameIsOrigin()) { // There is a risk of URL spoofing from origins that are too wide to fit in // the bubble; elide origins from the front to prevent this. GetBubbleFrameView()->SetTitleView( @@ -261,12 +261,12 @@ base::string16 PermissionPromptBubbleView::GetWindowTitle() const { int message_id; - if (ShouldShowAllowThisTimeButton()) { + if (GetShowAllowThisTimeButton()) { message_id = IDS_PERMISSIONS_BUBBLE_PROMPT_ONE_TIME; } else { message_id = IDS_PERMISSIONS_BUBBLE_PROMPT; } - return l10n_util::GetStringFUTF16(message_id, name_or_origin_.name_or_origin); + return l10n_util::GetStringFUTF16(message_id, GetDisplayName()); } base::string16 PermissionPromptBubbleView::GetAccessibleWindowTitle() const { @@ -288,8 +288,7 @@ if (visible_requests.size() == 1) { return l10n_util::GetStringFUTF16( IDS_PERMISSIONS_BUBBLE_PROMPT_ACCESSIBLE_TITLE_ONE_PERM, - name_or_origin_.name_or_origin, - visible_requests[0]->GetMessageTextFragment()); + GetDisplayName(), visible_requests[0]->GetMessageTextFragment()); } int template_id = @@ -297,13 +296,12 @@ ? IDS_PERMISSIONS_BUBBLE_PROMPT_ACCESSIBLE_TITLE_TWO_PERMS : IDS_PERMISSIONS_BUBBLE_PROMPT_ACCESSIBLE_TITLE_TWO_PERMS_MORE; return l10n_util::GetStringFUTF16( - template_id, name_or_origin_.name_or_origin, + template_id, GetDisplayName(), visible_requests[0]->GetMessageTextFragment(), visible_requests[1]->GetMessageTextFragment()); } -PermissionPromptBubbleView::DisplayNameOrOrigin -PermissionPromptBubbleView::GetDisplayNameOrOrigin() const { +base::string16 PermissionPromptBubbleView::GetDisplayName() const { DCHECK(!delegate_->Requests().empty()); GURL origin_url = delegate_->GetRequestingOrigin(); @@ -312,19 +310,26 @@ extensions::ui_util::GetEnabledExtensionNameForUrl(origin_url, browser_->profile()); if (!extension_name.empty()) - return {extension_name, false /* is_origin */}; + return extension_name; } // File URLs should be displayed as "This file". - if (origin_url.SchemeIsFile()) { - return {l10n_util::GetStringUTF16(IDS_PERMISSIONS_BUBBLE_PROMPT_THIS_FILE), - false /* is_origin */}; - } + if (origin_url.SchemeIsFile()) + return l10n_util::GetStringUTF16(IDS_PERMISSIONS_BUBBLE_PROMPT_THIS_FILE); // Web URLs should be displayed as the origin in the URL. - return {url_formatter::FormatUrlForSecurityDisplay( - origin_url, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC), - true /* is_origin */}; + return url_formatter::FormatUrlForSecurityDisplay( + origin_url, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); +} + +bool PermissionPromptBubbleView::GetDisplayNameIsOrigin() const { + DCHECK(!delegate_->Requests().empty()); + GURL origin_url = delegate_->GetRequestingOrigin(); + return (!origin_url.SchemeIs(extensions::kExtensionScheme) || + extensions::ui_util::GetEnabledExtensionNameForUrl( + origin_url, browser_->profile()) + .empty()) && + !origin_url.SchemeIsFile(); } base::Optional<base::string16> PermissionPromptBubbleView::GetExtraText() @@ -370,7 +375,7 @@ base::TimeTicks::Now() - permission_requested_time_); } -bool PermissionPromptBubbleView::ShouldShowAllowThisTimeButton() const { +bool PermissionPromptBubbleView::GetShowAllowThisTimeButton() const { if (!base::FeatureList::IsEnabled( permissions::features::kOneTimeGeolocationPermission)) { return false; @@ -381,3 +386,8 @@ return delegate_->Requests()[0]->GetRequestType() == permissions::RequestType::kGeolocation; } + +BEGIN_METADATA(PermissionPromptBubbleView, views::BubbleDialogDelegateView) +ADD_READONLY_PROPERTY_METADATA(base::string16, DisplayName) +ADD_READONLY_PROPERTY_METADATA(bool, DisplayNameIsOrigin) +END_METADATA
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h index f686b87..79698b7 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
@@ -10,6 +10,7 @@ #include "chrome/browser/ui/views/permission_bubble/permission_prompt_style.h" #include "components/permissions/permission_prompt.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/metadata/metadata_header_macros.h" namespace permissions { enum class RequestType; @@ -21,10 +22,14 @@ // website. class PermissionPromptBubbleView : public views::BubbleDialogDelegateView { public: + METADATA_HEADER(PermissionPromptBubbleView); PermissionPromptBubbleView(Browser* browser, permissions::PermissionPrompt::Delegate* delegate, base::TimeTicks permission_requested_time, PermissionPromptStyle prompt_style); + PermissionPromptBubbleView(const PermissionPromptBubbleView&) = delete; + PermissionPromptBubbleView& operator=(const PermissionPromptBubbleView&) = + delete; ~PermissionPromptBubbleView() override; void Show(); @@ -47,20 +52,16 @@ void ClosingPermission(); private: - // Holds the string to be displayed as the origin of the permission prompt, - // and whether or not that string is an origin. - struct DisplayNameOrOrigin { - base::string16 name_or_origin; - bool is_origin; - }; - bool ShouldShowRequest(permissions::RequestType type) const; std::vector<permissions::PermissionRequest*> GetVisibleRequests() const; void AddRequestLine(permissions::PermissionRequest* request); // Returns the origin to be displayed in the permission prompt. May return // a non-origin, e.g. extension URLs use the name of the extension. - DisplayNameOrOrigin GetDisplayNameOrOrigin() const; + base::string16 GetDisplayName() const; + + // Returns whether the display name is an origin. + bool GetDisplayNameIsOrigin() const; // Get extra information to display for the permission, if any. base::Optional<base::string16> GetExtraText() const; @@ -71,17 +72,12 @@ // Determines whether the current request should also display an // "Allow only this time" option in addition to the "Allow on every visit" // option. - bool ShouldShowAllowThisTimeButton() const; + bool GetShowAllowThisTimeButton() const; Browser* const browser_; permissions::PermissionPrompt::Delegate* const delegate_; - // The requesting domain's name or origin. - const DisplayNameOrOrigin name_or_origin_; - base::TimeTicks permission_requested_time_; - - DISALLOW_COPY_AND_ASSIGN(PermissionPromptBubbleView); }; #endif // CHROME_BROWSER_UI_VIEWS_PERMISSION_BUBBLE_PERMISSION_PROMPT_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc index c3b7277..6201ca9 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
@@ -29,6 +29,7 @@ #include "ui/views/bubble/bubble_border.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/widget/widget.h" namespace { @@ -80,7 +81,7 @@ if (!widget) return; widget->CloseWithReason( - bubble_->HasAccepted() ? views::Widget::ClosedReason::kAcceptButtonClicked + bubble_->GetAccepted() ? views::Widget::ClosedReason::kAcceptButtonClicked : views::Widget::ClosedReason::kUnspecified); } @@ -133,8 +134,8 @@ } } -bool DiceWebSigninInterceptionBubbleView::HasAccepted() const { - return has_accepted_; +bool DiceWebSigninInterceptionBubbleView::GetAccepted() const { + return accepted_; } DiceWebSigninInterceptionBubbleView::DiceWebSigninInterceptionBubbleView( @@ -195,20 +196,20 @@ switch (user_choice) { case SigninInterceptionUserChoice::kAccept: result = SigninInterceptionResult::kAccepted; - has_accepted_ = true; + accepted_ = true; break; case SigninInterceptionUserChoice::kDecline: result = SigninInterceptionResult::kDeclined; - has_accepted_ = false; + accepted_ = false; break; case SigninInterceptionUserChoice::kGuest: result = SigninInterceptionResult::kAcceptedWithGuest; - has_accepted_ = true; + accepted_ = true; } RecordInterceptionResult(bubble_parameters_, profile_, result); std::move(callback_).Run(result); - if (!has_accepted_) { + if (!accepted_) { // Only close the dialog when the user declined. If the user accepted the // dialog displays a spinner until the handle is released. GetWidget()->CloseWithReason( @@ -233,3 +234,8 @@ return DiceWebSigninInterceptionBubbleView::CreateBubble( browser->profile(), anchor_view, bubble_parameters, std::move(callback)); } + +BEGIN_METADATA(DiceWebSigninInterceptionBubbleView, + views::BubbleDialogDelegateView) +ADD_READONLY_PROPERTY_METADATA(bool, Accepted) +END_METADATA
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h index 828976fb..6990a39 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h
@@ -12,6 +12,7 @@ #include "base/gtest_prod_util.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/signin/dice_web_signin_interceptor.h" +#include "ui/views/metadata/metadata_header_macros.h" namespace views { class View; @@ -24,12 +25,12 @@ class DiceWebSigninInterceptionBubbleView : public views::BubbleDialogDelegateView { public: - ~DiceWebSigninInterceptionBubbleView() override; - + METADATA_HEADER(DiceWebSigninInterceptionBubbleView); DiceWebSigninInterceptionBubbleView( const DiceWebSigninInterceptionBubbleView& other) = delete; DiceWebSigninInterceptionBubbleView& operator=( const DiceWebSigninInterceptionBubbleView& other) = delete; + ~DiceWebSigninInterceptionBubbleView() override; // Warning: the bubble is closed when the handle is destroyed ; it is the // responsibility of the caller to keep the handle alive until the bubble @@ -50,7 +51,7 @@ SigninInterceptionResult result); // Returns true if the user has accepted the interception. - bool HasAccepted() const; + bool GetAccepted() const; private: FRIEND_TEST_ALL_PREFIXES(DiceWebSigninInterceptionBubbleBrowserTest, @@ -95,7 +96,7 @@ void OnWebUIUserChoice(SigninInterceptionUserChoice user_choice); Profile* profile_; - bool has_accepted_ = false; + bool accepted_ = false; DiceWebSigninInterceptor::Delegate::BubbleParameters bubble_parameters_; base::OnceCallback<void(SigninInterceptionResult)> callback_;
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc index ad5778ff..d9493cef 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc
@@ -152,12 +152,12 @@ bubble_handle_ = bubble->GetHandle(); views::test::WidgetClosingObserver closing_observer(widget); - EXPECT_FALSE(bubble->HasAccepted()); + EXPECT_FALSE(bubble->GetAccepted()); // Simulate clicking Accept in the WebUI. bubble->OnWebUIUserChoice(SigninInterceptionUserChoice::kAccept); ASSERT_TRUE(callback_result_.has_value()); EXPECT_EQ(callback_result_, SigninInterceptionResult::kAccepted); - EXPECT_TRUE(bubble->HasAccepted()); + EXPECT_TRUE(bubble->GetAccepted()); // Widget was not closed yet. ASSERT_FALSE(closing_observer.widget_closed()); @@ -198,12 +198,12 @@ bubble_handle_ = bubble->GetHandle(); views::test::WidgetClosingObserver closing_observer(widget); - EXPECT_FALSE(bubble->HasAccepted()); + EXPECT_FALSE(bubble->GetAccepted()); // Simulate clicking Guest in the WebUI. bubble->OnWebUIUserChoice(SigninInterceptionUserChoice::kGuest); ASSERT_TRUE(callback_result_.has_value()); EXPECT_EQ(callback_result_, SigninInterceptionResult::kAcceptedWithGuest); - EXPECT_TRUE(bubble->HasAccepted()); + EXPECT_TRUE(bubble->GetAccepted()); // Widget was not closed yet. ASSERT_FALSE(closing_observer.widget_closed());
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc b/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc index 497a681..68dcf51 100644 --- a/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc +++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_view.cc
@@ -18,6 +18,7 @@ #include "ui/views/bubble/bubble_border.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/widget/widget.h" #include "url/gurl.h" @@ -72,6 +73,9 @@ views::Widget::ClosedReason::kCloseButtonClicked); } +BEGIN_METADATA(ProfileCustomizationBubbleView, views::BubbleDialogDelegateView) +END_METADATA + void DiceWebSigninInterceptorDelegate::ShowProfileCustomizationBubbleInternal( Browser* browser) { DCHECK(browser);
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_view.h b/chrome/browser/ui/views/profiles/profile_customization_bubble_view.h index 9850b72..0acd277 100644 --- a/chrome/browser/ui/views/profiles/profile_customization_bubble_view.h +++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_view.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_CUSTOMIZATION_BUBBLE_VIEW_H_ #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/metadata/metadata_header_macros.h" namespace views { class View; @@ -16,12 +17,12 @@ // This bubble is implemented as a WebUI page rendered inside a native bubble. class ProfileCustomizationBubbleView : public views::BubbleDialogDelegateView { public: - ~ProfileCustomizationBubbleView() override; - + METADATA_HEADER(ProfileCustomizationBubbleView); ProfileCustomizationBubbleView(const ProfileCustomizationBubbleView& other) = delete; ProfileCustomizationBubbleView& operator=( const ProfileCustomizationBubbleView& other) = delete; + ~ProfileCustomizationBubbleView() override; static void CreateBubble(Profile* profile, views::View* anchor_view);
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 51ba7bb..117bb76 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -44,6 +44,7 @@ #include "ui/views/controls/label.h" #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/layout_provider.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/view_class_properties.h" #include "ui/views/widget/widget.h" @@ -602,7 +603,7 @@ // If widget is already visible and anchored to the correct tab we should not // try to reset the anchor view or reshow. - if (GetWidget()->IsVisible() && GetAnchorView() == tab && + if (GetWidgetVisible() && GetAnchorView() == tab && !slide_animation_delegate_->is_animating()) { GetWidget()->SetBounds( slide_animation_delegate_->CalculateTargetBounds(tab)); @@ -611,11 +612,11 @@ return; } - if (GetWidget()->IsVisible()) + if (GetWidgetVisible()) ++hover_cards_seen_count_; const bool animations_enabled = gfx::Animation::ShouldRenderRichAnimation(); - if (GetWidget()->IsVisible() && !disable_animations_for_testing_ && + if (GetWidgetVisible() && !disable_animations_for_testing_ && animations_enabled) { slide_animation_delegate_->AnimateToAnchorView(tab); } else { @@ -627,7 +628,7 @@ OnHoverCardLanded(); } - if (!GetWidget()->IsVisible()) { + if (!GetWidgetVisible()) { if (disable_animations_for_testing_ || show_immediately || !animations_enabled) { GetWidget()->SetOpacity(1.0f); @@ -642,13 +643,13 @@ } } -bool TabHoverCardBubbleView::IsVisible() { +bool TabHoverCardBubbleView::GetWidgetVisible() const { return GetWidget()->IsVisible(); } void TabHoverCardBubbleView::FadeOutToHide() { delayed_show_timer_.Stop(); - if (!GetWidget()->IsVisible()) + if (!GetWidgetVisible()) return; thumbnail_observation_->Observe(nullptr); slide_animation_delegate_->StopAnimation(); @@ -661,7 +662,7 @@ } } -bool TabHoverCardBubbleView::IsFadingOut() const { +bool TabHoverCardBubbleView::GetFadingOut() const { return fade_animation_delegate_->IsFadingOut(); } @@ -913,7 +914,7 @@ base::TimeDelta elapsed_time) { constexpr base::TimeDelta kMaxHoverCardReshowTimeDelta = base::TimeDelta::FromSeconds(5); - if ((!GetWidget()->IsVisible() || IsFadingOut()) && + if ((!GetWidgetVisible() || GetFadingOut()) && elapsed_time <= kMaxHoverCardReshowTimeDelta) { constexpr base::TimeDelta kMinHoverCardReshowTimeDelta = base::TimeDelta::FromMilliseconds(1); @@ -924,3 +925,8 @@ kHoverCardHistogramBucketCount); } } + +BEGIN_METADATA(TabHoverCardBubbleView, views::BubbleDialogDelegateView) +ADD_READONLY_PROPERTY_METADATA(bool, WidgetVisible) +ADD_READONLY_PROPERTY_METADATA(bool, FadingOut) +END_METADATA
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index cf92c20..37782b2 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -12,6 +12,7 @@ #include "base/timer/timer.h" #include "chrome/browser/ui/tabs/tab_utils.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/metadata/metadata_header_macros.h" namespace gfx { class ImageSkia; @@ -28,6 +29,7 @@ // Dialog that displays an informational hover card containing page information. class TabHoverCardBubbleView : public views::BubbleDialogDelegateView { public: + METADATA_HEADER(TabHoverCardBubbleView); explicit TabHoverCardBubbleView(Tab* tab); TabHoverCardBubbleView(const TabHoverCardBubbleView&) = delete; TabHoverCardBubbleView& operator=(const TabHoverCardBubbleView&) = delete; @@ -36,11 +38,11 @@ // Updates card content and anchoring and shows the tab hover card. void UpdateAndShow(Tab* tab); - bool IsVisible(); + bool GetWidgetVisible() const; void FadeOutToHide(); - bool IsFadingOut() const; + bool GetFadingOut() const; // Returns the target tab (if any). views::View* GetDesiredAnchorView();
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 3fc650a..7f92847 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -2122,7 +2122,7 @@ return false; return hover_card_ && hover_card_->GetWidget()->IsVisible() && - !hover_card_->IsFadingOut() && + !hover_card_->GetFadingOut() && hover_card_->GetDesiredAnchorView() == tab; } @@ -3700,7 +3700,7 @@ void TabStrip::OnMouseExited(const ui::MouseEvent& event) { if (base::FeatureList::IsEnabled(features::kTabHoverCards) && hover_card_ && - hover_card_->IsVisible()) { + hover_card_->GetVisible()) { hover_card_->set_last_mouse_exit_timestamp(base::TimeTicks::Now()); } UpdateHoverCard(nullptr);
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc index 3c0eea8..112cff3 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.cc
@@ -285,3 +285,6 @@ bool ChromeLabsBubbleView::IsRestartPromptVisibleForTesting() { return restart_prompt_->GetVisible(); } + +BEGIN_METADATA(ChromeLabsBubbleView, views::BubbleDialogDelegateView) +END_METADATA
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h index eca81ab..982b97a0 100644 --- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h +++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h
@@ -12,10 +12,13 @@ #include "components/flags_ui/flags_storage.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/layout/flex_layout_view.h" +#include "ui/views/metadata/metadata_header_macros.h" // TODO(elainechien): Use composition instead of inheritance. class ChromeLabsBubbleView : public views::BubbleDialogDelegateView { public: + METADATA_HEADER(ChromeLabsBubbleView); + static void Show(views::View* anchor_view, std::unique_ptr<ChromeLabsBubbleViewModel> model);
diff --git a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc index 51b49e3..72d089b 100644 --- a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc +++ b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.cc
@@ -33,6 +33,7 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/layout_provider.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/style/platform_style.h" #include "ui/views/style/typography.h" #include "ui/views/view_class_properties.h" @@ -350,3 +351,6 @@ views::Button* FeaturePromoBubbleView::GetSnoozeButtonForTesting() const { return snooze_button_; } + +BEGIN_METADATA(FeaturePromoBubbleView, views::BubbleDialogDelegateView) +END_METADATA
diff --git a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h index 2004555..dc75d79 100644 --- a/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h +++ b/chrome/browser/ui/views/user_education/feature_promo_bubble_view.h
@@ -14,7 +14,7 @@ #include "chrome/browser/ui/views/user_education/feature_promo_bubble_timeout.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" - +#include "ui/views/metadata/metadata_header_macros.h" namespace ui { class MouseEvent; @@ -32,7 +32,7 @@ // a deferred context. class FeaturePromoBubbleView : public views::BubbleDialogDelegateView { public: - // Disallow copy and assign. + METADATA_HEADER(FeaturePromoBubbleView); FeaturePromoBubbleView(const FeaturePromoBubbleView&) = delete; FeaturePromoBubbleView& operator=(const FeaturePromoBubbleView&) = delete; ~FeaturePromoBubbleView() override;
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc index ce647e6..54d6f4a 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc
@@ -26,10 +26,10 @@ #include "chrome/browser/web_applications/components/app_registry_controller.h" #include "chrome/browser/web_applications/components/install_finalizer.h" #include "chrome/browser/web_applications/components/policy/web_app_policy_constants.h" -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/test/web_app_install_observer.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc index a72869f..74ddc5a 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc
@@ -7,20 +7,47 @@ #include "base/notreached.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/saml/public_saml_url_fetcher.h" +#include "chrome/browser/chromeos/login/saml/in_session_password_sync_manager.h" +#include "chrome/browser/chromeos/login/saml/in_session_password_sync_manager_factory.h" #include "chrome/browser/chromeos/login/signin_partition_manager.h" #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/common/chrome_features.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/installer/util/google_update_settings.h" #include "chromeos/constants/chromeos_switches.h" +#include "chromeos/dbus/util/version_loader.h" +#include "chromeos/login/auth/challenge_response/cert_utils.h" +#include "chromeos/login/auth/cryptohome_key_constants.h" #include "components/user_manager/known_user.h" #include "content/public/browser/storage_partition.h" #include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_urls.h" +#include "ui/base/l10n/l10n_util.h" namespace chromeos { +namespace { + +std::vector<std::string> ConvertToVector(const base::ListValue* list) { + std::vector<std::string> string_list; + if (!list) { + return string_list; + } + + for (const base::Value& value : *list) { + if (value.is_string()) { + string_list.push_back(value.GetString()); + } + } + + return string_list; +} + +} // namespace LockScreenReauthHandler::LockScreenReauthHandler(const std::string& email) : email_(email) {} + LockScreenReauthHandler::~LockScreenReauthHandler() = default; void LockScreenReauthHandler::HandleInitialize(const base::ListValue* value) { @@ -105,6 +132,8 @@ base::DictionaryValue params; params.SetString("webviewPartitionName", partition_name); + signin_partition_name_ = partition_name; + params.SetString("gaiaUrl", GaiaUrls::GetInstance()->gaia_url().spec()); params.SetString("clientId", GaiaUrls::GetInstance()->oauth2_chrome_client_id()); @@ -131,7 +160,85 @@ login::ExtractSamlPasswordAttributesEnabled()); AllowJavascript(); - CallJavascriptFunction("$(\'main-element\').LoadAuthenticatorParam", params); + CallJavascriptFunction("$(\'main-element\').loadAuthenticator", params); +} + +void LockScreenReauthHandler::HandleCompleteAuthentication( + const base::ListValue* params) { + CHECK_EQ(params->GetList().size(), 6); + std::string gaia_id, email, password; + bool using_saml; + const base::ListValue* servicesList; + ::login::StringList services = ::login::StringList(); + const base::DictionaryValue* password_attributes; + gaia_id = params->GetList()[0].GetString(); + email = params->GetList()[1].GetString(); + password = params->GetList()[2].GetString(); + using_saml = params->GetList()[3].GetBool(); + params->GetList(4, &servicesList); + services = ConvertToVector(servicesList); + params->GetDictionary(5, &password_attributes); + + if (gaia::CanonicalizeEmail(email) != gaia::CanonicalizeEmail(email_)) { + // The authenticated user email doesn't match the current user's email. + CallJavascriptFunction("$(\'main-element\').resetAuthenticator"); + return; + } + + DCHECK(!email.empty()); + DCHECK(!gaia_id.empty()); + + login::SigninPartitionManager* signin_partition_manager = + login::SigninPartitionManager::Factory::GetForBrowserContext( + Profile::FromWebUI(web_ui())); + + online_login_helper_ = std::make_unique<OnlineLoginHelper>( + signin_partition_name_, signin_partition_manager, + base::BindOnce(&LockScreenReauthHandler::OnCookieWaitTimeout, + weak_factory_.GetWeakPtr()), + base::BindOnce(&LockScreenReauthHandler::CheckCredentials, + weak_factory_.GetWeakPtr())); + + std::string error_message; + pending_user_context_ = std::make_unique<UserContext>(); + if (!login::BuildUserContextForGaiaSignIn( + login::GetUsertypeFromServicesString(services), + user_manager::known_user::GetAccountId(email, gaia_id, + AccountType::GOOGLE), + using_saml, false /* using_saml_api */, password, + SamlPasswordAttributes::FromJs(*password_attributes), + /*sync_trusted_vault_keys=*/base::nullopt, + *extension_provided_client_cert_usage_observer_, + pending_user_context_.get(), &error_message)) { + pending_user_context_.reset(); + NOTREACHED(); + return; + } + + online_login_helper_->SetUserContext(std::move(pending_user_context_)); + online_login_helper_->RequestCookiesAndCompleteAuthentication(); +} + +void LockScreenReauthHandler::OnCookieWaitTimeout() { + NOTREACHED() << "Cookie has timed out while attempting to login in."; + const user_manager::User* user = + user_manager::UserManager::Get()->GetActiveUser(); + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + chromeos::InSessionPasswordSyncManager* password_sync_manager = + chromeos::InSessionPasswordSyncManagerFactory::GetForProfile(profile); + password_sync_manager->lock_screen_start_reauth_dialog->Dismiss(); +} + +void LockScreenReauthHandler::CheckCredentials(const UserContext& user_context) { + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByAccountId( + user_context.GetAccountId()); + if (!profile) { + LOG(ERROR) << "Invalid account id"; + return; + } + chromeos::InSessionPasswordSyncManager* password_sync_manager = + chromeos::InSessionPasswordSyncManagerFactory::GetForProfile(profile); + password_sync_manager->CheckCredentials(user_context); } void LockScreenReauthHandler::RegisterMessages() { @@ -144,6 +251,11 @@ "authenticatorLoaded", base::BindRepeating(&LockScreenReauthHandler::HandleAuthenticatorLoaded, weak_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "completeAuthentication", + base::BindRepeating( + &LockScreenReauthHandler::HandleCompleteAuthentication, + weak_factory_.GetWeakPtr())); } } // namespace chromeos \ No newline at end of file
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h index fd069356..ca07123 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.h
@@ -20,7 +20,9 @@ void RegisterMessages() override; + // WebUI message handlers. void HandleInitialize(const base::ListValue*); + void HandleCompleteAuthentication(const base::ListValue*); void HandleAuthenticatorLoaded(const base::ListValue*); @@ -39,15 +41,25 @@ const std::string& partition_name, net::CookieAccessResult result); + void OnCookieWaitTimeout(); + + void CheckCredentials(const UserContext& user_context); + // True if the authenticator is still loading. bool authenticator_being_loaded_ = false; // User non-canonicalized email for display std::string email_; + std::string signin_partition_name_; + + std::unique_ptr<UserContext> pending_user_context_; + std::unique_ptr<LoginClientCertUsageObserver> extension_provided_client_cert_usage_observer_; + std::unique_ptr<OnlineLoginHelper> online_login_helper_; + base::WeakPtrFactory<LockScreenReauthHandler> weak_factory_{this}; };
diff --git a/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc index e8e527e..640108b 100644 --- a/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.cc
@@ -16,7 +16,7 @@ #include "base/json/json_writer.h" #include "base/macros.h" #include "base/metrics/histogram_functions.h" -#include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/supervised_user/supervised_user_features.h" #include "chrome/browser/supervised_user/supervised_user_service.h" @@ -82,10 +82,7 @@ if (!ProfileManager::GetActiveUserProfile()->IsChild()) { return GetUrlWithEmailParam(chrome::kChromeUIChromeSigninURL, email); } - // User type is Child. - if (!arc::IsSecondaryAccountForChildEnabled() && is_arc_source) { - return GURL(chrome::kChromeUIAccountManagerErrorURL); - } + return GetUrlWithEmailParam( SupervisedUserService::GetEduCoexistenceLoginUrl(), email); }
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc index dda9e15df..ad76b5d 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -17,7 +17,6 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/child_accounts/secondary_account_consent_logger.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/chrome_device_id_helper.h" @@ -140,12 +139,10 @@ UMA_HISTOGRAM_ENUMERATION("Signin.SecondaryAccountConsentLog", result); secondary_account_consent_logger_.reset(); if (result == SecondaryAccountConsentLogger::Result::kSuccess) { - // The EDU account has been added/reauthenticated. Mark migration to ARC++ - // as completed. - if (arc::IsSecondaryAccountForChildEnabled()) { - pref_service_->SetBoolean(::prefs::kEduCoexistenceArcMigrationCompleted, - true); - } + // The EDU account has been added/re-authenticated. Mark migration to + // ARC++ as completed. + pref_service_->SetBoolean(::prefs::kEduCoexistenceArcMigrationCompleted, + true); UpsertAccount(refresh_token); } else { @@ -218,12 +215,10 @@ void OnConsentLogged(const std::string& refresh_token, bool success) { if (success) { - // The EDU account has been added/reauthenticated. Mark migration to ARC++ - // as completed. - if (arc::IsSecondaryAccountForChildEnabled()) { - pref_service_->SetBoolean(::prefs::kEduCoexistenceArcMigrationCompleted, - true); - } + // The EDU account has been added/re-authenticated. Mark migration to + // ARC++ as completed. + pref_service_->SetBoolean(::prefs::kEduCoexistenceArcMigrationCompleted, + true); UpsertAccount(refresh_token); } else {
diff --git a/chrome/browser/usb/usb_chooser_context.cc b/chrome/browser/usb/usb_chooser_context.cc index 81a7e7f..ffb3f5f 100644 --- a/chrome/browser/usb/usb_chooser_context.cc +++ b/chrome/browser/usb/usb_chooser_context.cc
@@ -34,6 +34,7 @@ constexpr char kSerialNumberKey[] = "serial-number"; constexpr char kVendorIdKey[] = "vendor-id"; constexpr int kDeviceIdWildcard = -1; +constexpr int kUsbClassMassStorage = 0x08; // Reasons a permission may be closed. These are used in histograms so do not // remove/reorder entries. Only add at the end just before @@ -115,6 +116,28 @@ return device_value; } +bool IsMassStorageInterface(const device::mojom::UsbInterfaceInfo& interface) { + for (auto& alternate : interface.alternates) { + if (alternate->class_code == kUsbClassMassStorage) + return true; + } + return false; +} + +bool ShouldExposeDevice(const device::mojom::UsbDeviceInfo& device_info) { + // blink::USBDevice::claimInterface() disallows claiming mass storage + // interfaces, but explicitly prevent access in the browser process as + // ChromeOS would allow these interfaces to be claimed. + + for (auto& configuration : device_info.configurations) { + for (auto& interface : configuration->interfaces) { + if (!IsMassStorageInterface(*interface)) + return true; + } + } + return false; +} + } // namespace void UsbChooserContext::DeviceObserver::OnDeviceAdded( @@ -158,7 +181,10 @@ std::vector<device::mojom::UsbDeviceInfoPtr> devices) { for (auto& device_info : devices) { DCHECK(device_info); - devices_.insert(std::make_pair(device_info->guid, std::move(device_info))); + if (ShouldExposeDevice(*device_info)) { + devices_.insert( + std::make_pair(device_info->guid, std::move(device_info))); + } } is_initialized_ = true; @@ -542,6 +568,8 @@ DCHECK(device_info); // Update the device list. DCHECK(!base::Contains(devices_, device_info->guid)); + if (!ShouldExposeDevice(*device_info)) + return; devices_.insert(std::make_pair(device_info->guid, device_info->Clone())); // Notify all observers. @@ -552,6 +580,12 @@ void UsbChooserContext::OnDeviceRemoved( device::mojom::UsbDeviceInfoPtr device_info) { DCHECK(device_info); + + if (!ShouldExposeDevice(*device_info)) { + DCHECK(!base::Contains(devices_, device_info->guid)); + return; + } + // Update the device list. DCHECK(base::Contains(devices_, device_info->guid)); devices_.erase(device_info->guid);
diff --git a/chrome/browser/usb/usb_chooser_context_unittest.cc b/chrome/browser/usb/usb_chooser_context_unittest.cc index 01fc46ca..a70f5678 100644 --- a/chrome/browser/usb/usb_chooser_context_unittest.cc +++ b/chrome/browser/usb/usb_chooser_context_unittest.cc
@@ -9,6 +9,7 @@ #include "base/no_destructor.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" #include "base/values.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -1272,3 +1273,36 @@ /*product_id=*/1357, /*name=*/"Unknown product 0x054D from vendor 0x18D2"); } + +TEST_F(UsbChooserContextTest, MassStorageHidden) { + GURL url("https://www.google.com"); + const auto origin = url::Origin::Create(url); + + // Mass storage devices should be hidden. + std::vector<device::mojom::UsbConfigurationInfoPtr> storage_configs; + storage_configs.push_back( + device::FakeUsbDeviceInfo::CreateConfiguration(0x08, 0x06, 0x50)); + UsbDeviceInfoPtr storage_device_info = device_manager_.CreateAndAddDevice( + 0, 0, "vendor1", "storage", "123ABC", std::move(storage_configs)); + + // Composite devices with both mass storage and allowed interfaces should be + // shown. + std::vector<device::mojom::UsbConfigurationInfoPtr> complex_configs; + complex_configs.push_back( + device::FakeUsbDeviceInfo::CreateConfiguration(0x08, 0x06, 0x50, 1)); + complex_configs.push_back( + device::FakeUsbDeviceInfo::CreateConfiguration(0xff, 0x42, 0x1, 2)); + UsbDeviceInfoPtr complex_device_info = device_manager_.CreateAndAddDevice( + 0, 0, "vendor2", "complex", "456DEF", std::move(complex_configs)); + + UsbChooserContext* chooser_context = GetChooserContext(profile()); + + base::RunLoop loop; + chooser_context->GetDevices( + base::BindLambdaForTesting([&](std::vector<UsbDeviceInfoPtr> devices) { + EXPECT_EQ(1u, devices.size()); + EXPECT_EQ(complex_device_info->product_name, devices[0]->product_name); + loop.Quit(); + })); + loop.Run(); +}
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 9d5a3ca6..2d2301d 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -32,6 +32,8 @@ "pending_app_manager_impl.h", "pending_app_registration_task.cc", "pending_app_registration_task.h", + "policy/web_app_policy_manager.cc", + "policy/web_app_policy_manager.h", "system_web_app_manager.cc", "system_web_app_manager.h", "web_app.cc",
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index 68afc82..3d839cf 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -35,8 +35,6 @@ "pending_app_manager.h", "policy/web_app_policy_constants.cc", "policy/web_app_policy_constants.h", - "policy/web_app_policy_manager.cc", - "policy/web_app_policy_manager.h", "protocol_handler_manager.cc", "protocol_handler_manager.h", "system_web_app_types.h",
diff --git a/chrome/browser/web_applications/extensions/BUILD.gn b/chrome/browser/web_applications/extensions/BUILD.gn index 8441f7e..ea6ea89 100644 --- a/chrome/browser/web_applications/extensions/BUILD.gn +++ b/chrome/browser/web_applications/extensions/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//extensions/buildflags/buildflags.gni") assert(enable_extensions) @@ -85,4 +86,8 @@ "//skia", "//testing/gtest", ] + + if (is_chromeos_ash) { + deps += [ "//chrome/browser/chromeos:chromeos" ] + } }
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc index 95bde98..c20d965 100644 --- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include <memory> #include <utility> @@ -22,6 +22,8 @@ #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "components/crx_file/id_util.h" #include "components/sync_preferences/testing_pref_service_syncable.h" @@ -29,6 +31,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h" +#include "components/policy/core/common/policy_pref_names.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + using sync_preferences::TestingPrefServiceSyncable; namespace web_app { @@ -165,7 +172,8 @@ class WebAppPolicyManagerTest : public ChromeRenderViewHostTestHarness { public: - WebAppPolicyManagerTest() = default; + WebAppPolicyManagerTest() + : testing_local_state_(TestingBrowserProcess::GetGlobal()) {} WebAppPolicyManagerTest(const WebAppPolicyManagerTest&) = delete; WebAppPolicyManagerTest& operator=(const WebAppPolicyManagerTest&) = delete; ~WebAppPolicyManagerTest() override = default; @@ -203,6 +211,7 @@ } WebAppPolicyManager* policy_manager() { return web_app_policy_manager_; } + ScopedTestingLocalState testing_local_state_; private: TestAppRegistrar* test_app_registrar_ = nullptr; @@ -522,4 +531,29 @@ } } +#if BUILDFLAG(IS_CHROMEOS_ASH) +TEST_F(WebAppPolicyManagerTest, DisableWebApps) { + policy_manager()->Start(); + base::RunLoop().RunUntilIdle(); + + auto disabled_apps = policy_manager()->GetDisabledSystemWebApps(); + EXPECT_TRUE(disabled_apps.empty()); + + // Add camera to system features disable list policy. + auto disabled_apps_list = + std::make_unique<base::Value>(base::Value::Type::LIST); + disabled_apps_list->Append(policy::SystemFeature::kCamera); + testing_local_state_.Get()->SetUserPref( + policy::policy_prefs::kSystemFeaturesDisableList, + std::move(disabled_apps_list)); + base::RunLoop().RunUntilIdle(); + + std::set<SystemAppType> expected_disabled_apps; + expected_disabled_apps.insert(SystemAppType::CAMERA); + + disabled_apps = policy_manager()->GetDisabledSystemWebApps(); + EXPECT_EQ(disabled_apps, expected_disabled_apps); +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + } // namespace web_app
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc similarity index 65% rename from chrome/browser/web_applications/components/policy/web_app_policy_manager.cc rename to chrome/browser/web_applications/policy/web_app_policy_manager.cc index 83e3505..f12605c 100644 --- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include <algorithm> #include <utility> @@ -13,16 +13,24 @@ #include "base/metrics/histogram_functions.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/components/app_registry_controller.h" #include "chrome/browser/web_applications/components/external_install_options.h" #include "chrome/browser/web_applications/components/policy/web_app_policy_constants.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_install_utils.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h" +#include "components/policy/core/common/policy_pref_names.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + namespace web_app { namespace { @@ -75,8 +83,14 @@ WebAppPolicyManager::~WebAppPolicyManager() = default; void WebAppPolicyManager::SetSubsystems( - PendingAppManager* pending_app_manager) { + PendingAppManager* pending_app_manager, + AppRegistrar* app_registrar, + AppRegistryController* app_registry_controller, + SystemWebAppManager* web_app_manager) { pending_app_manager_ = pending_app_manager; + app_registrar_ = app_registrar; + app_registry_controller_ = app_registry_controller; + web_app_manager_ = web_app_manager; } void WebAppPolicyManager::Start() { @@ -128,6 +142,49 @@ weak_ptr_factory_.GetWeakPtr())); RefreshPolicyInstalledApps(); + ObserveSystemDisableListPolicy(); +} + +void WebAppPolicyManager::OnAppsPolicyChanged() { +#if BUILDFLAG(IS_CHROMEOS_ASH) + auto disabled_web_apps = GetDisabledWebAppsIds(); + std::vector<web_app::AppId> app_ids = app_registrar_->GetAppIds(); + for (const auto& id : app_ids) { + const bool is_disabled = base::Contains(disabled_web_apps, id); + app_registry_controller_->SetAppIsDisabled(id, is_disabled); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +} + +std::set<SystemAppType> WebAppPolicyManager::GetDisabledSystemWebApps() const { + std::set<SystemAppType> disabled_system_apps; + +#if BUILDFLAG(IS_CHROMEOS_ASH) + PrefService* const local_state = g_browser_process->local_state(); + if (!local_state) // Sometimes it's not available in tests. + return disabled_system_apps; + + const base::ListValue* disabled_system_features_pref = + local_state->GetList(policy::policy_prefs::kSystemFeaturesDisableList); + if (!disabled_system_features_pref) + return disabled_system_apps; + + for (const auto& entry : *disabled_system_features_pref) { + switch (entry.GetInt()) { + case policy::SystemFeature::kCamera: + disabled_system_apps.insert(SystemAppType::CAMERA); + break; + case policy::SystemFeature::kOsSettings: + disabled_system_apps.insert(SystemAppType::SETTINGS); + break; + case policy::SystemFeature::kScanning: + disabled_system_apps.insert(SystemAppType::SCANNING); + break; + } + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + return disabled_system_apps; } void WebAppPolicyManager::RefreshPolicyInstalledApps() { @@ -179,4 +236,35 @@ } } +void WebAppPolicyManager::ObserveSystemDisableListPolicy() { +#if BUILDFLAG(IS_CHROMEOS_ASH) + PrefService* const local_state = g_browser_process->local_state(); + if (!local_state) { // Sometimes it's not available in tests. + return; + } + local_state_pref_change_registrar_.Init(local_state); + + local_state_pref_change_registrar_.Add( + policy::policy_prefs::kSystemFeaturesDisableList, + base::BindRepeating(&WebAppPolicyManager::OnAppsPolicyChanged, + base::Unretained(this))); + +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +} + +std::set<AppId> WebAppPolicyManager::GetDisabledWebAppsIds() const { + std::set<AppId> disabled_web_apps; +#if BUILDFLAG(IS_CHROMEOS_ASH) + auto disabled_system_apps = GetDisabledSystemWebApps(); + for (const auto& app_type : disabled_system_apps) { + base::Optional<AppId> app_id = + web_app_manager_->GetAppIdForSystemApp(app_type); + if (app_id.has_value()) { + disabled_web_apps.insert(app_id.value()); + } + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + return disabled_web_apps; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.h b/chrome/browser/web_applications/policy/web_app_policy_manager.h similarity index 62% rename from chrome/browser/web_applications/components/policy/web_app_policy_manager.h rename to chrome/browser/web_applications/policy/web_app_policy_manager.h index 2e4de42..f56b50a 100644 --- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.h +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_POLICY_WEB_APP_POLICY_MANAGER_H_ -#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_POLICY_WEB_APP_POLICY_MANAGER_H_ +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_POLICY_WEB_APP_POLICY_MANAGER_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_POLICY_WEB_APP_POLICY_MANAGER_H_ #include <vector> @@ -21,6 +21,9 @@ namespace web_app { +class AppRegistryController; +class SystemWebAppManager; + // Policy installation allows enterprise admins to control and manage // Web Apps on behalf of their managed users. This class tracks the policy that // affects Web Apps and also tracks which Web Apps are currently installed based @@ -39,7 +42,10 @@ WebAppPolicyManager& operator=(const WebAppPolicyManager&) = delete; ~WebAppPolicyManager(); - void SetSubsystems(PendingAppManager* pending_app_manager); + void SetSubsystems(PendingAppManager* pending_app_manager, + AppRegistrar* app_registrar, + AppRegistryController* app_registry_controller, + SystemWebAppManager* web_app_manager); void Start(); @@ -47,6 +53,13 @@ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + // Used for handling SystemFeaturesDisableList policy. Checks if the app is + // disabled and notifies app_registry_controller_ about the current app state. + void OnAppsPolicyChanged(); + + // Gets system web apps disabled by SystemFeaturesDisableList policy. + std::set<SystemAppType> GetDisabledSystemWebApps() const; + private: void InitChangeRegistrarAndRefreshPolicyInstalledApps(); @@ -55,21 +68,30 @@ std::map<GURL, PendingAppManager::InstallResult> install_results, std::map<GURL, bool> uninstall_results); + void ObserveSystemDisableListPolicy(); + + // Gets ids of web apps disabled by SystemFeaturesDisableList policy. + std::set<AppId> GetDisabledWebAppsIds() const; + Profile* profile_; PrefService* pref_service_; - // Used to install, uninstall, and update apps. Should outlive this class. + // Used to install, uninstall, and update apps. Should outlive this class + // (owned by WebAppProvider). PendingAppManager* pending_app_manager_ = nullptr; + AppRegistrar* app_registrar_ = nullptr; + AppRegistryController* app_registry_controller_ = nullptr; + SystemWebAppManager* web_app_manager_ = nullptr; PrefChangeRegistrar pref_change_registrar_; + PrefChangeRegistrar local_state_pref_change_registrar_; bool is_refreshing_ = false; bool needs_refresh_ = false; base::WeakPtrFactory<WebAppPolicyManager> weak_ptr_factory_{this}; - }; } // namespace web_app -#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_POLICY_WEB_APP_POLICY_MANAGER_H_ +#endif // CHROME_BROWSER_WEB_APPLICATIONS_POLICY_WEB_APP_POLICY_MANAGER_H_
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index 45bfe7c..e6e732a 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/web_applications/components/web_app_ui_manager.h" #include "chrome/browser/web_applications/components/web_app_utils.h" #include "chrome/browser/web_applications/components/web_application_info.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/chrome_features.h" @@ -53,8 +54,6 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/constants/ash_features.h" #include "ash/public/cpp/app_list/internal_app_id_constants.h" -#include "base/values.h" -#include "chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h" #include "chrome/browser/chromeos/web_applications/camera_system_web_app_info.h" #include "chrome/browser/chromeos/web_applications/connectivity_diagnostics_system_web_app_info.h" #include "chrome/browser/chromeos/web_applications/diagnostics_system_web_app_info.h" @@ -72,7 +71,6 @@ #include "chromeos/components/media_app_ui/url_constants.h" #include "chromeos/constants/chromeos_pref_names.h" #include "chromeos/strings/grit/chromeos_strings.h" -#include "components/policy/core/common/policy_pref_names.h" #include "extensions/common/constants.h" #if !defined(OFFICIAL_BUILD) @@ -310,37 +308,6 @@ return install_options; } -std::set<SystemAppType> GetDisabledSystemWebApps() { - std::set<SystemAppType> disabled_system_apps; - -#if BUILDFLAG(IS_CHROMEOS_ASH) - PrefService* const local_state = g_browser_process->local_state(); - if (!local_state) // Sometimes it's not available in tests. - return disabled_system_apps; - - const base::ListValue* disabled_system_features_pref = - local_state->GetList(policy::policy_prefs::kSystemFeaturesDisableList); - if (!disabled_system_features_pref) - return disabled_system_apps; - - for (const auto& entry : *disabled_system_features_pref) { - switch (entry.GetInt()) { - case policy::SystemFeature::kCamera: - disabled_system_apps.insert(SystemAppType::CAMERA); - break; - case policy::SystemFeature::kOsSettings: - disabled_system_apps.insert(SystemAppType::SETTINGS); - break; - case policy::SystemFeature::kScanning: - disabled_system_apps.insert(SystemAppType::SCANNING); - break; - } - } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - - return disabled_system_apps; -} - } // namespace SystemAppInfo::SystemAppInfo(const std::string& internal_name, @@ -375,8 +342,7 @@ case SystemAppType::SETTINGS: return true; case SystemAppType::CAMERA: - return base::FeatureList::IsEnabled( - chromeos::features::kCameraSystemWebApp); + return true; case SystemAppType::TERMINAL: return true; case SystemAppType::MEDIA: @@ -451,12 +417,14 @@ AppRegistrar* registrar, AppRegistryController* registry_controller, WebAppUiManager* ui_manager, - OsIntegrationManager* os_integration_manager) { + OsIntegrationManager* os_integration_manager, + WebAppPolicyManager* web_app_policy_manager) { pending_app_manager_ = pending_app_manager; registrar_ = registrar; registry_controller_ = registry_controller; ui_manager_ = ui_manager; os_integration_manager_ = os_integration_manager; + web_app_policy_manager_ = web_app_policy_manager; } void SystemWebAppManager::Start() { @@ -485,7 +453,8 @@ UpdateLastAttemptedInfo(); } - const auto disabled_system_apps = GetDisabledSystemWebApps(); + const auto disabled_system_apps = + web_app_policy_manager_->GetDisabledSystemWebApps(); for (const auto& app : system_app_infos_) { install_options_list.push_back(CreateInstallOptionsForSystemApp( @@ -502,21 +471,6 @@ weak_ptr_factory_.GetWeakPtr(), should_force_install_apps, install_start_time)); } -#if BUILDFLAG(IS_CHROMEOS_ASH) - PrefService* const local_state = g_browser_process->local_state(); - if (local_state) { // Sometimes it's not available in tests. - local_state_pref_change_registrar_.Init(local_state); - - // Sometimes this function gets called twice in tests. - if (!local_state_pref_change_registrar_.IsObserved( - policy::policy_prefs::kSystemFeaturesDisableList)) { - local_state_pref_change_registrar_.Add( - policy::policy_prefs::kSystemFeaturesDisableList, - base::BindRepeating(&SystemWebAppManager::OnAppsPolicyChanged, - base::Unretained(this))); - } - } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) } void SystemWebAppManager::InstallSystemAppsForTesting() { @@ -855,7 +809,7 @@ // May be called more than once in tests. if (!on_apps_synchronized_->is_signaled()) { on_apps_synchronized_->Signal(); - OnAppsPolicyChanged(); + web_app_policy_manager_->OnAppsPolicyChanged(); } #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -926,23 +880,4 @@ return true; } -void SystemWebAppManager::OnAppsPolicyChanged() { -#if BUILDFLAG(IS_CHROMEOS_ASH) - if (!on_apps_synchronized_->is_signaled()) - return; - - auto disabled_system_apps = GetDisabledSystemWebApps(); - - for (const auto& app_type_to_app_info : system_app_infos_) { - const bool is_disabled = - base::Contains(disabled_system_apps, app_type_to_app_info.first); - base::Optional<AppId> app_id = - GetAppIdForSystemApp(app_type_to_app_info.first); - if (app_id.has_value()) { - registry_controller_->SetAppIsDisabled(app_id.value(), is_disabled); - } - } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) -} - } // namespace web_app
diff --git a/chrome/browser/web_applications/system_web_app_manager.h b/chrome/browser/web_applications/system_web_app_manager.h index 8e20f62..46e367b 100644 --- a/chrome/browser/web_applications/system_web_app_manager.h +++ b/chrome/browser/web_applications/system_web_app_manager.h
@@ -18,7 +18,6 @@ #include "chrome/browser/web_applications/components/pending_app_manager.h" #include "chrome/browser/web_applications/components/system_web_app_types.h" #include "chrome/browser/web_applications/components/web_application_info.h" -#include "components/prefs/pref_change_registrar.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" #include "url/origin.h" @@ -43,6 +42,7 @@ class WebAppUiManager; class OsIntegrationManager; class AppRegistryController; +class WebAppPolicyManager; using OriginTrialsMap = std::map<url::Origin, std::vector<std::string>>; using WebApplicationInfoFactory = @@ -139,7 +139,8 @@ AppRegistrar* registrar, AppRegistryController* registry_controller, WebAppUiManager* ui_manager, - OsIntegrationManager* os_integration_manager); + OsIntegrationManager* os_integration_manager, + WebAppPolicyManager* web_app_policy_manager); void Start(); @@ -220,9 +221,6 @@ void ResetOnAppsSynchronizedForTesting(); - // Updates each system app either disabled/not disabled. - void OnAppsPolicyChanged(); - void Shutdown(); protected: @@ -281,7 +279,7 @@ OsIntegrationManager* os_integration_manager_ = nullptr; - PrefChangeRegistrar local_state_pref_change_registrar_; + WebAppPolicyManager* web_app_policy_manager_ = nullptr; base::WeakPtrFactory<SystemWebAppManager> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/web_applications/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/system_web_app_manager_unittest.cc index 8776e45..33969fc 100644 --- a/chrome/browser/web_applications/system_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/system_web_app_manager_unittest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/web_applications/components/web_app_icon_generator.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/pending_app_manager_impl.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/test/test_data_retriever.h" #include "chrome/browser/web_applications/test/test_file_handler_manager.h" #include "chrome/browser/web_applications/test/test_file_utils.h" @@ -180,6 +181,7 @@ install_manager_ = std::make_unique<WebAppInstallManager>(profile()); test_pending_app_manager_impl_ = std::make_unique<TestPendingAppManagerImpl>(profile()); + web_app_policy_manager_ = std::make_unique<WebAppPolicyManager>(profile()); test_system_web_app_manager_ = std::make_unique<TestSystemWebAppManager>(profile()); test_ui_manager_ = std::make_unique<TestWebAppUiManager>(); @@ -196,10 +198,14 @@ &controller().registrar(), &controller().os_integration_manager(), &ui_manager(), &install_finalizer(), &install_manager()); + web_app_policy_manager().SetSubsystems( + &pending_app_manager(), &controller().registrar(), + &controller().sync_bridge(), &system_web_app_manager()); + system_web_app_manager().SetSubsystems( &pending_app_manager(), &controller().registrar(), &controller().sync_bridge(), &ui_manager(), - &controller().os_integration_manager()); + &controller().os_integration_manager(), &web_app_policy_manager()); install_manager().Start(); install_finalizer().Start(); @@ -214,6 +220,7 @@ // The reverse order of creation: test_ui_manager_.reset(); test_system_web_app_manager_.reset(); + web_app_policy_manager_.reset(); test_pending_app_manager_impl_.reset(); install_manager_.reset(); install_finalizer_.reset(); @@ -247,6 +254,10 @@ TestWebAppUiManager& ui_manager() { return *test_ui_manager_; } + WebAppPolicyManager& web_app_policy_manager() { + return *web_app_policy_manager_; + } + bool IsInstalled(const GURL& install_url) { return controller().registrar().IsInstalled( GenerateAppIdFromURL(install_url)); @@ -313,6 +324,7 @@ std::unique_ptr<TestPendingAppManagerImpl> test_pending_app_manager_impl_; std::unique_ptr<TestSystemWebAppManager> test_system_web_app_manager_; std::unique_ptr<TestWebAppUiManager> test_ui_manager_; + std::unique_ptr<WebAppPolicyManager> web_app_policy_manager_; }; // Test that System Apps do install with the feature enabled. @@ -977,7 +989,7 @@ unsynced_system_web_app_manager->SetSubsystems( &pending_app_manager(), &controller().registrar(), &controller().sync_bridge(), &ui_manager(), - &controller().os_integration_manager()); + &controller().os_integration_manager(), &web_app_policy_manager()); EXPECT_TRUE(unsynced_system_web_app_manager->IsSystemWebApp( GenerateAppIdFromURL(AppUrl1())));
diff --git a/chrome/browser/web_applications/test/test_web_app_provider.cc b/chrome/browser/web_applications/test/test_web_app_provider.cc index fe5046e6..b85d80b 100644 --- a/chrome/browser/web_applications/test/test_web_app_provider.cc +++ b/chrome/browser/web_applications/test/test_web_app_provider.cc
@@ -12,9 +12,9 @@ #include "chrome/browser/web_applications/components/install_finalizer.h" #include "chrome/browser/web_applications/components/os_integration_manager.h" #include "chrome/browser/web_applications/components/pending_app_manager.h" -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/components/web_app_ui_manager.h" #include "chrome/browser/web_applications/components/web_app_utils.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/test/test_system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_install_manager.h"
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 97d5c40..d9034ba 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h" #include "chrome/browser/web_applications/components/install_bounce_metric.h" #include "chrome/browser/web_applications/components/os_integration_manager.h" -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/components/web_app_audio_focus_id_map.h" #include "chrome/browser/web_applications/components/web_app_prefs_utils.h" #include "chrome/browser/web_applications/components/web_app_ui_manager.h" @@ -22,6 +21,7 @@ #include "chrome/browser/web_applications/file_utils_wrapper.h" #include "chrome/browser/web_applications/manifest_update_manager.h" #include "chrome/browser/web_applications/pending_app_manager_impl.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_database_factory.h" #include "chrome/browser/web_applications/web_app_file_handler_manager.h" @@ -266,8 +266,11 @@ external_web_app_manager_->SetSubsystems(pending_app_manager_.get()); system_web_app_manager_->SetSubsystems( pending_app_manager_.get(), registrar_.get(), registry_controller_.get(), - ui_manager_.get(), os_integration_manager_.get()); - web_app_policy_manager_->SetSubsystems(pending_app_manager_.get()); + ui_manager_.get(), os_integration_manager_.get(), + web_app_policy_manager_.get()); + web_app_policy_manager_->SetSubsystems( + pending_app_manager_.get(), registrar_.get(), registry_controller_.get(), + system_web_app_manager_.get()); ui_manager_->SetSubsystems(registry_controller_.get()); os_integration_manager_->SetSubsystems(registrar_.get(), ui_manager_.get(), icon_manager_.get());
diff --git a/chrome/browser/web_applications/web_app_tab_helper.cc b/chrome/browser/web_applications/web_app_tab_helper.cc index c5548bf4..e91dae0 100644 --- a/chrome/browser/web_applications/web_app_tab_helper.cc +++ b/chrome/browser/web_applications/web_app_tab_helper.cc
@@ -10,11 +10,11 @@ #include "base/unguessable_token.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/components/os_integration_manager.h" -#include "chrome/browser/web_applications/components/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/components/web_app_audio_focus_id_map.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/components/web_app_ui_manager.h" #include "chrome/browser/web_applications/manifest_update_manager.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "content/public/browser/media_session.h" #include "content/public/browser/navigation_handle.h"
diff --git a/chrome/browser/webapps/android/BUILD.gn b/chrome/browser/webapps/android/BUILD.gn index 6de72cc..ce17c9de 100644 --- a/chrome/browser/webapps/android/BUILD.gn +++ b/chrome/browser/webapps/android/BUILD.gn
@@ -30,6 +30,7 @@ sources = [ "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenBottomSheetViewBinder.java", + "java/src/org/chromium/chrome/browser/webapps/ImageZoomView.java", "java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetController.java", "java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetControllerFactory.java", "java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetControllerProvider.java", @@ -43,6 +44,7 @@ "//base:base_java", "//base:jni_java", "//components/browser_ui/bottomsheet/android:java", + "//components/browser_ui/styles/android:java_resources", "//components/webapps/browser/android:java", "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", @@ -62,6 +64,7 @@ android_resources("java_resources") { sources = [ + "java/res/layout/image_zoom_view.xml", "java/res/layout/pwa_install_bottom_sheet_content.xml", "java/res/layout/pwa_install_bottom_sheet_toolbar.xml", "java/res/values/dimens.xml",
diff --git a/chrome/browser/webapps/android/java/res/layout/image_zoom_view.xml b/chrome/browser/webapps/android/java/res/layout/image_zoom_view.xml new file mode 100644 index 0000000..7fb0c352 --- /dev/null +++ b/chrome/browser/webapps/android/java/res/layout/image_zoom_view.xml
@@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2021 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/black" > + + <ImageView + android:id="@+id/image_zoom" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:scaleType="fitCenter" + android:contentDescription="@string/image_zoom_content_description"/> + +</RelativeLayout>
diff --git a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/ImageZoomView.java b/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/ImageZoomView.java new file mode 100644 index 0000000..8b36e9d4 --- /dev/null +++ b/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/ImageZoomView.java
@@ -0,0 +1,26 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.webapps; + +import android.app.AlertDialog; +import android.content.Context; +import android.graphics.Bitmap; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; + +/** + * UI for the zoomed image view used for screenshots in the bottom-sheet UI for PWA installs. + */ +public class ImageZoomView extends AlertDialog { + public ImageZoomView(Context context, Bitmap bitmap) { + super(context, R.style.Theme_Chromium_Fullscreen); + + View view = LayoutInflater.from(context).inflate(R.layout.image_zoom_view, null); + view.setOnClickListener(v -> dismiss()); + ((ImageView) view.findViewById(R.id.image_zoom)).setImageBitmap(bitmap); + setView(view); + } +}
diff --git a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetController.java b/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetController.java index 1384a82..f63983f 100644 --- a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetController.java +++ b/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/PwaBottomSheetController.java
@@ -96,11 +96,16 @@ @Override public void onBindViewHolder(ScreenshotViewHolder holder, int position) { + Bitmap bitmap = mScreenshots.get(position); ImageView view = (ImageView) holder.itemView; view.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)); view.setAdjustViewBounds(true); - view.setImageBitmap(mScreenshots.get(position)); + view.setImageBitmap(bitmap); + view.setOnClickListener(v -> { + final ImageZoomView dialog = new ImageZoomView(mContext, bitmap); + dialog.show(); + }); } @Override
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index f1c49691..c922aec 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1612374575-6184f3217a8add1609de115b2d337c421f22cd8e.profdata +chrome-linux-master-1612418006-140623c1006b973f40fbaf24de3681cf6a97b823.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index aea434c..255abcdd 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1612374575-63817629c7b408841dd340c4b714545974a7dd52.profdata +chrome-mac-master-1612418006-729861229468b02a711441251c659979edc1be61.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index c069c24..370fbbf 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1612374575-0d03e205c1c03ac97a6c0cba482ec5d9a6ee09b7.profdata +chrome-win32-master-1612418006-3487cc74164afe709deaf49d002eb495a971b8f2.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index f813904..654e9a8a 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1612385785-808d22cf6d008fb1ebde94dcad4d6769e1aa47e1.profdata +chrome-win64-master-1612429129-65e5ba3e04246b7cf302275fbc8e7da5aeea3112.profdata
diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn index 29366fb..35f01d0 100644 --- a/chrome/installer/linux/BUILD.gn +++ b/chrome/installer/linux/BUILD.gn
@@ -8,6 +8,7 @@ import("//build/config/features.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build/config/sysroot.gni") +import("//build/linux/strip_binary.gni") import("//build/util/lastchange.gni") import("//build/util/process_version.gni") import("//build/util/version.gni") @@ -169,29 +170,11 @@ root_build_dir) } -action("strip_chrome_binary") { - prog_name = "$root_out_dir/chrome" - debug_file = prog_name + ".debug" - stripped_file = prog_name + ".stripped" +strip_binary("strip_chrome_binary") { + binary_input = "$root_out_dir/chrome" + symbol_output = "$root_out_dir/chrome.debug" + stripped_binary_output = "$root_out_dir/chrome.stripped" deps = [ "//chrome" ] - script = "//build/gn_run_binary.py" - sources = [ - "//buildtools/third_party/eu-strip/bin/eu-strip", - prog_name, - ] - outputs = [ - debug_file, - stripped_file, - ] - args = [ - rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip", - root_build_dir), - "-o", - rebase_path(stripped_file, root_build_dir), - "-f", - rebase_path(debug_file, root_build_dir), - rebase_path(prog_name, root_build_dir), - ] } # This target builds all "normal" Linux installers. You must set
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7a11bde..48418ecb 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1408,11 +1408,11 @@ "../browser/translate/translate_manager_browsertest.cc", "../browser/translate/translate_model_service_browsertest.cc", "../browser/ui/ask_google_for_suggestions_dialog_browsertest.cc", - "../browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_browsertest.cc", "../browser/ui/autofill/payments/card_unmask_prompt_view_browsertest.cc", "../browser/ui/autofill/payments/card_unmask_prompt_view_tester.h", "../browser/ui/autofill/payments/save_card_bubble_controller_impl_browsertest.cc", "../browser/ui/autofill/payments/save_upi_bubble_controller_impl_browsertest.cc", + "../browser/ui/autofill/save_address_profile_bubble_controller_browsertest.cc", "../browser/ui/blocked_content/popup_opener_tab_helper_browsertest.cc", "../browser/ui/blocked_content/popup_tracker_browsertest.cc", "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc", @@ -4859,9 +4859,9 @@ "../browser/sharing/shared_clipboard/shared_clipboard_utils_unittest.cc", "../browser/sharing/sms/sms_fetch_request_handler_unittest.cc", "../browser/sharing/sms/sms_remote_fetcher_unittest.cc", - "../browser/ui/autofill/address_profiles/save_address_profile_bubble_controller_unittest.cc", "../browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc", "../browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc", + "../browser/ui/autofill/save_address_profile_bubble_controller_unittest.cc", "../browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc", "../browser/ui/bluetooth/bluetooth_scanning_prompt_controller_unittest.cc", "../browser/ui/media_router/cast_modes_with_media_sources_unittest.cc", @@ -4876,7 +4876,7 @@ "../browser/ui/toolbar/media_router_contextual_menu_unittest.cc", "../browser/ui/toolbar/mock_media_router_action_controller.cc", "../browser/ui/toolbar/mock_media_router_action_controller.h", - "../browser/ui/views/autofill/address_profiles/save_address_profile_view_unittest.cc", + "../browser/ui/views/autofill/save_address_profile_view_unittest.cc", "../browser/ui/views/passwords/move_to_account_store_bubble_view_unittest.cc", "../browser/ui/views/passwords/password_bubble_view_test_base.cc", "../browser/ui/views/passwords/password_bubble_view_test_base.h",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/main_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/main_view_test.js index f83c896..26533c1c 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/main_view_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/main_view_test.js
@@ -19,7 +19,8 @@ } function getAppItems() { - return mainView.$$('#app-list').querySelectorAll('app-management-app-item'); + return mainView.$$('app-management-expandable-app-list') + .querySelectorAll('app-management-app-item'); } setup(function() { @@ -38,11 +39,42 @@ const appItems = getAppItems(); expectEquals(1, appItems.length); - assertFalse(!!settings.Router.getInstance().getQueryParameters().get('id')); - store.setReducersEnabled(false); + expectEquals(app.id, appItems[0].app.id); + store.setReducersEnabled(false); appItems[0].click(); - fakeHandler.flushPipesForTesting(); - assertTrue(!!settings.Router.getInstance().getQueryParameters().get('id')); + const expected = app_management.actions.changePage(PageType.DETAIL, app.id); + assertDeepEquals(expected, store.lastAction); + }); + + // TODO(jshikaram) uncomment once more apps bar is added back. + test.skip('more apps bar visibility', async function() { + // The more apps bar shouldn't appear when there are 4 apps. + await addApps(NUMBER_OF_APPS_DISPLAYED_DEFAULT); + expectEquals(NUMBER_OF_APPS_DISPLAYED_DEFAULT, getAppItems().length); + expectTrue(mainView.$$('app-management-expandable-app-list') + .$['expander-row'] + .hidden); + + // The more apps bar appears when there are 5 apps. + await addApps(1); + expectEquals(NUMBER_OF_APPS_DISPLAYED_DEFAULT + 1, getAppItems().length); + expectFalse(mainView.$$('app-management-expandable-app-list') + .$['expander-row'] + .hidden); + }); + + test('notifications sublabel collapsibility', async function() { + // The three spans contains collapsible attribute. + await addApps(4); + const pieces = await mainView.getNotificationSublabelPieces_(); + expectTrue(pieces.filter(p => p.arg === '$1')[0].collapsible); + expectTrue(pieces.filter(p => p.arg === '$2')[0].collapsible); + expectTrue(pieces.filter(p => p.arg === '$3')[0].collapsible); + + // Checking ",and other x apps" is non-collapsible + await addApps(6); + const pieces2 = await mainView.getNotificationSublabelPieces_(); + expectFalse(pieces2.filter(p => p.arg === '$4')[0].collapsible); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 6b5e45c..4684332 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -561,27 +561,6 @@ mocha.run(); }); -// Test fixture for the app management main view element. -// eslint-disable-next-line no-var -var OSSettingsAppManagementMainViewTest = - class extends OSSettingsAppManagementBrowserTest { - /** @override */ - get browsePreload() { - return super.browsePreload + 'app_management/main_view.html'; - } - - /** @override */ - get extraLibraries() { - return super.extraLibraries.concat([ - 'app_management/main_view_test.js', - ]); - } -}; - -TEST_F('OSSettingsAppManagementMainViewTest', 'AllJsTests', () => { - mocha.run(); -}); - // Text fixture for the app management dom switch element. // eslint-disable-next-line no-var var OSSettingsAppManagementDomSwitchTest =
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc index f777e564..7984761 100644 --- a/chrome/updater/app/app_install.cc +++ b/chrome/updater/app/app_install.cc
@@ -21,7 +21,6 @@ #include "chrome/updater/constants.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" -#include "chrome/updater/registration_data.h" #include "chrome/updater/setup.h" #include "chrome/updater/tag.h" #include "chrome/updater/update_service.h" @@ -142,23 +141,6 @@ update_service_internal, base::WrapRefCounted(this))); } -void AppInstall::RegisterUpdater() { - RegistrationRequest registration_request; - registration_request.app_id = kUpdaterAppId; - registration_request.version = base::Version(UPDATER_VERSION_STRING); - - scoped_refptr<UpdateService> update_service = CreateUpdateService(); - update_service->RegisterApp( - registration_request, - base::BindOnce(&AppInstall::RegisterUpdaterDone, this, update_service)); -} - -void AppInstall::RegisterUpdaterDone(scoped_refptr<UpdateService>, - const RegistrationResponse& response) { - VLOG(1) << "Updater registration complete, code = " << response.status_code; - MaybeInstallApp(); -} - void AppInstall::MaybeInstallApp() { const std::string app_id = []() { // Returns the app id parsed from the tag, if the --tag is specified, or
diff --git a/chrome/updater/app/app_install.h b/chrome/updater/app/app_install.h index 9fbe1129..5997621 100644 --- a/chrome/updater/app/app_install.h +++ b/chrome/updater/app/app_install.h
@@ -21,7 +21,6 @@ namespace updater { -struct RegistrationResponse; class UpdateService; // This class defines an interface for installing an application. The interface @@ -66,11 +65,6 @@ void WakeCandidateDone(); - void RegisterUpdater(); - - void RegisterUpdaterDone(scoped_refptr<UpdateService>, - const RegistrationResponse& response); - // Handles the --tag and --app-id command line arguments, and triggers // installing of the corresponding application if either argument is present. void MaybeInstallApp();
diff --git a/chrome/updater/app/app_install_mac.mm b/chrome/updater/app/app_install_mac.mm index d35f76c..e7496ef 100644 --- a/chrome/updater/app/app_install_mac.mm +++ b/chrome/updater/app/app_install_mac.mm
@@ -18,7 +18,7 @@ kUpdateServiceLaunchdName, LaunchctlPresence::kPresent, base::TimeDelta::FromSeconds(kWaitForLaunchctlUpdateSec), base::BindOnce([](scoped_refptr<AppInstall> installer, - bool unused) { installer->RegisterUpdater(); }, + bool unused) { installer->MaybeInstallApp(); }, base::WrapRefCounted(this))); }
diff --git a/chrome/updater/app/app_install_win.cc b/chrome/updater/app/app_install_win.cc index f439c93..d85083a 100644 --- a/chrome/updater/app/app_install_win.cc +++ b/chrome/updater/app/app_install_win.cc
@@ -7,7 +7,7 @@ namespace updater { void AppInstall::WakeCandidateDone() { - RegisterUpdater(); + MaybeInstallApp(); } } // namespace updater
diff --git a/chrome/updater/app/app_server.cc b/chrome/updater/app/app_server.cc index 6f0d56f..e584c67 100644 --- a/chrome/updater/app/app_server.cc +++ b/chrome/updater/app/app_server.cc
@@ -5,10 +5,16 @@ #include "chrome/updater/app/app_server.h" #include <memory> +#include <string> +#include <vector> #include "base/bind.h" +#include "base/command_line.h" +#include "base/containers/contains.h" #include "base/logging.h" #include "base/memory/scoped_refptr.h" +#include "base/process/launch.h" +#include "base/process/process.h" #include "base/version.h" #include "chrome/updater/configurator.h" #include "chrome/updater/constants.h" @@ -48,7 +54,7 @@ if (this_version < active_version) { global_prefs = nullptr; - uninstall_ = true; + uninstall_self_ = true; return base::BindOnce(&AppServer::ActiveDuty, this, MakeInactiveUpdateService(), MakeInactiveUpdateServiceInternal()); @@ -77,9 +83,35 @@ void AppServer::Uninitialize() { if (config_) PrefsCommitPendingWrites(config_->GetPrefService()); - if (uninstall_) { + if (uninstall_self_) { VLOG(1) << "Uninstalling version " << UPDATER_VERSION_STRING; UninstallSelf(); + } else { + MaybeUninstall(); + } +} + +void AppServer::MaybeUninstall() { + if (!config_) + return; + + auto persisted_data = + base::MakeRefCounted<PersistedData>(config_->GetPrefService()); + const std::vector<std::string> app_ids = persisted_data->GetAppIds(); + if (app_ids.size() == 1 && base::Contains(app_ids, kUpdaterAppId)) { + base::CommandLine command_line( + base::CommandLine::ForCurrentProcess()->GetProgram()); + command_line.AppendSwitch(kUninstallIfUnusedSwitch); + command_line.AppendSwitch("--enable-logging"); + command_line.AppendSwitchASCII("--vmodule", "*/chrome/updater/*=2"); + DVLOG(2) << "Launching uninstall command: " + << command_line.GetCommandLineString(); + + base::Process process = base::LaunchProcess(command_line, {}); + if (!process.IsValid()) { + DVLOG(2) << "Invalid process launching command: " + << command_line.GetCommandLineString(); + } } } @@ -105,12 +137,6 @@ if (!result) return false; global_prefs->SetActiveVersion(UPDATER_VERSION_STRING); - scoped_refptr<PersistedData> persisted_data = - base::MakeRefCounted<PersistedData>(global_prefs->GetPrefService()); - if (!persisted_data->GetProductVersion(kUpdaterAppId).IsValid()) { - persisted_data->SetProductVersion(kUpdaterAppId, - base::Version(UPDATER_VERSION_STRING)); - } global_prefs->SetSwapping(false); PrefsCommitPendingWrites(global_prefs->GetPrefService()); return true;
diff --git a/chrome/updater/app/app_server.h b/chrome/updater/app/app_server.h index 1a12bc3d..566c405a 100644 --- a/chrome/updater/app/app_server.h +++ b/chrome/updater/app/app_server.h
@@ -41,17 +41,17 @@ void Initialize() final; void FirstTaskRun() final; - // Set up the server for normal active version functions using the provided + // Sets up the server for normal active version functions using the provided // services. virtual void ActiveDuty( scoped_refptr<UpdateService> update_service, scoped_refptr<UpdateServiceInternal> update_service_internal) = 0; - // Set up all non-side-by-side RPC interfaces to point to this candidate + // Sets up all non-side-by-side RPC interfaces to point to this candidate // server. virtual bool SwapRPCInterfaces() = 0; - // Uninstall this candidate version of the updater. + // Uninstalls this candidate version of the updater. virtual void UninstallSelf() = 0; // As part of initialization, an AppServer must do a mode check to determine @@ -67,12 +67,15 @@ void Qualify(std::unique_ptr<LocalPrefs> local_prefs); bool SwapVersions(GlobalPrefs* global_prefs); + // Uninstalls the updater if it doesn't manage any apps, aside from itself. + void MaybeUninstall(); + base::OnceClosure first_task_; scoped_refptr<Configurator> config_; // If true, this version of the updater should uninstall itself during // shutdown. - bool uninstall_ = false; + bool uninstall_self_ = false; }; scoped_refptr<App> AppServerInstance();
diff --git a/chrome/updater/app/app_uninstall.cc b/chrome/updater/app/app_uninstall.cc index a0fe64b..4111065 100644 --- a/chrome/updater/app/app_uninstall.cc +++ b/chrome/updater/app/app_uninstall.cc
@@ -4,13 +4,20 @@ #include "chrome/updater/app/app_uninstall.h" +#include <memory> +#include <string> +#include <vector> + #include "base/bind.h" #include "base/command_line.h" +#include "base/containers/contains.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "build/build_config.h" #include "chrome/updater/app/app.h" #include "chrome/updater/constants.h" +#include "chrome/updater/persisted_data.h" +#include "chrome/updater/prefs.h" #if defined(OS_WIN) #include "chrome/updater/win/setup/uninstall.h" @@ -29,25 +36,52 @@ private: ~AppUninstall() override = default; + void Initialize() override; void FirstTaskRun() override; + + std::unique_ptr<GlobalPrefs> global_prefs_; }; +void AppUninstall::Initialize() { + global_prefs_ = CreateGlobalPrefs(); +} + void AppUninstall::FirstTaskRun() { + if (!global_prefs_) { + return; + } + + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + #if defined(OS_MAC) - // TODO(crbug.com/1114719): Implement --uninstall=self for Win. - const std::string uninstall_switch_value = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - kUninstallSwitch); - if (!uninstall_switch_value.empty()) { + // TODO(crbug.com/1114719): Implement --uninstall-self for Win. + if (command_line->HasSwitch(kUninstallSelfSwitch)) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&UninstallCandidate), base::BindOnce(&AppUninstall::Shutdown, this)); - } else + return; + } #endif - { + + const bool has_uninstall_switch = command_line->HasSwitch(kUninstallSwitch); + const bool has_uninstall_if_unused_switch = + command_line->HasSwitch(kUninstallIfUnusedSwitch); + + const std::vector<std::string> app_ids = + base::MakeRefCounted<PersistedData>(global_prefs_->GetPrefService()) + ->GetAppIds(); + + const bool can_uninstall = + has_uninstall_switch || + (has_uninstall_if_unused_switch && app_ids.size() == 1 && + base::Contains(app_ids, kUpdaterAppId)); + + if (can_uninstall) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&Uninstall, false), base::BindOnce(&AppUninstall::Shutdown, this)); + return; } }
diff --git a/chrome/updater/app/app_update.cc b/chrome/updater/app/app_update.cc index 27e751e..e1678104 100644 --- a/chrome/updater/app/app_update.cc +++ b/chrome/updater/app/app_update.cc
@@ -15,7 +15,6 @@ #include "chrome/updater/constants.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" -#include "chrome/updater/registration_data.h" #include "chrome/updater/setup.h" #include "chrome/updater/updater_version.h" @@ -46,19 +45,7 @@ } void AppUpdate::SetupDone(int result) { - if (result != 0) { - Shutdown(result); - return; - } - - RegistrationRequest request; - request.app_id = kUpdaterAppId; - request.version = base::Version(UPDATER_VERSION_STRING); - - base::MakeRefCounted<PersistedData>(config_->GetPrefService()) - ->RegisterApp(request); - - Shutdown(0); + Shutdown(result); } scoped_refptr<App> MakeAppUpdate() {
diff --git a/chrome/updater/constants.cc b/chrome/updater/constants.cc index 5a42723b..fb6ac4f 100644 --- a/chrome/updater/constants.cc +++ b/chrome/updater/constants.cc
@@ -21,6 +21,8 @@ const char kUpdateSwitch[] = "update"; const char kInstallSwitch[] = "install"; const char kUninstallSwitch[] = "uninstall"; +const char kUninstallSelfSwitch[] = "uninstall-self"; +const char kUninstallIfUnusedSwitch[] = "uninstall-if-unused"; const char kSystemSwitch[] = "system"; const char kTestSwitch[] = "test"; const char kInitDoneNotifierSwitch[] = "init-done-notifier";
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h index 61ac7948..844a54ca 100644 --- a/chrome/updater/constants.h +++ b/chrome/updater/constants.h
@@ -83,6 +83,12 @@ // Uninstalls the updater. extern const char kUninstallSwitch[]; +// Uninstalls this version of the updater. +extern const char kUninstallSelfSwitch[]; + +// Uninstalls the updater if no apps are managed by it. +extern const char kUninstallIfUnusedSwitch[]; + // Kicks off the update service. This switch is typically used for by a // scheduled to invoke the updater periodically. extern const char kWakeSwitch[];
diff --git a/chrome/updater/mac/setup/setup.mm b/chrome/updater/mac/setup/setup.mm index f1dfa986..3a866e29 100644 --- a/chrome/updater/mac/setup/setup.mm +++ b/chrome/updater/mac/setup/setup.mm
@@ -158,7 +158,7 @@ kLoggingModuleSwitchValue), ], @LAUNCH_JOBKEY_MACHSERVICES : @{GetUpdateServiceInternalMachName() : @YES}, - @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @NO, + @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @YES, @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : @"Aqua" }; @@ -361,7 +361,7 @@ if (base::PathExists(version_executable_path)) { base::CommandLine command_line(version_executable_path); - command_line.AppendSwitchASCII(kUninstallSwitch, "self"); + command_line.AppendSwitch(kUninstallSelfSwitch); command_line.AppendSwitch("--enable-logging"); command_line.AppendSwitchASCII("--vmodule", "*/chrome/updater/*=2");
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index ed2aa21..207c31f3 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -5,6 +5,7 @@ #include "chrome/updater/test/integration_tests.h" #include <cstdlib> +#include <memory> #include "base/command_line.h" #include "base/files/file_path.h" @@ -283,6 +284,9 @@ ExpectActiveVersion(UPDATER_VERSION_STRING); ExpectActive(); + RegisterApp("test1"); + RegisterApp("test2"); + { std::unique_ptr<GlobalPrefs> global_prefs = CreateGlobalPrefs(); auto persisted_data = @@ -300,6 +304,9 @@ RunWake(0); + SleepFor(13); + ExpectInstalled(); + { std::unique_ptr<GlobalPrefs> global_prefs = CreateGlobalPrefs(); auto persisted_data = @@ -312,6 +319,35 @@ Clean(); } +TEST_F(IntegrationTest, UninstallUpdaterWhenAllAppsUninstalled) { + RegisterTestApp(); + ExpectInstalled(); + ExpectActiveVersion(UPDATER_VERSION_STRING); + ExpectActive(); + + { + std::unique_ptr<GlobalPrefs> global_prefs = CreateGlobalPrefs(); + auto persisted_data = + base::MakeRefCounted<PersistedData>(global_prefs->GetPrefService()); + const base::FilePath fake_ecp = + persisted_data->GetExistenceCheckerPath(kTestAppId) + .Append(FILE_PATH_LITERAL("NOT_THERE")); + persisted_data->SetExistenceCheckerPath(kTestAppId, fake_ecp); + + PrefsCommitPendingWrites(global_prefs->GetPrefService()); + + EXPECT_EQ(fake_ecp.value(), + persisted_data->GetExistenceCheckerPath(kTestAppId).value()); + } + + RunWake(0); + + SleepFor(13); + + ExpectClean(); + Clean(); +} + // TODO(https://crbug.com/1166196): Fix flaky timeouts. The timeout is in // RunWake(0). #if defined(OS_MAC)
diff --git a/chrome/updater/test/test_app/test_app_mac.mm b/chrome/updater/test/test_app/test_app_mac.mm index 3b95baa..9e06ce8 100644 --- a/chrome/updater/test/test_app/test_app_mac.mm +++ b/chrome/updater/test/test_app/test_app_mac.mm
@@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/logging.h" #include "base/mac/bundle_locations.h" #import "base/mac/foundation_util.h" #include "base/process/launch.h"
diff --git a/chrome/updater/update_service_impl.cc b/chrome/updater/update_service_impl.cc index eadf027..9a9846a 100644 --- a/chrome/updater/update_service_impl.cc +++ b/chrome/updater/update_service_impl.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" +#include "base/containers/contains.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" #include "base/task/post_task.h" @@ -167,6 +168,14 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); persisted_data_->RegisterApp(request); + if (!base::Contains(persisted_data_->GetAppIds(), kUpdaterAppId)) { + RegistrationRequest updater_request; + updater_request.app_id = kUpdaterAppId; + updater_request.version = base::Version(UPDATER_VERSION_STRING); + persisted_data_->RegisterApp(updater_request); + update_client_->SendRegistrationPing( + updater_request.app_id, updater_request.version, base::DoNothing()); + } update_client_->SendRegistrationPing(request.app_id, request.version, base::DoNothing());
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc index 19da4b18..233209fa 100644 --- a/chrome/updater/updater.cc +++ b/chrome/updater/updater.cc
@@ -113,7 +113,9 @@ return MakeAppInstall()->Run(); } - if (command_line->HasSwitch(kUninstallSwitch)) + if (command_line->HasSwitch(kUninstallSwitch) || + command_line->HasSwitch(kUninstallSelfSwitch) || + command_line->HasSwitch(kUninstallIfUnusedSwitch)) return MakeAppUninstall()->Run(); if (command_line->HasSwitch(kWakeSwitch)) {
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 86ce1f63..fcfd322 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -444,6 +444,7 @@ "//components/zoom", "//extensions/browser", "//extensions/browser:core_api_provider", + "//extensions/browser/api/messaging", "//extensions/common", "//extensions/common/api", "//google_apis:google_apis",
diff --git a/chromecast/media/api/monotonic_clock.h b/chromecast/media/api/monotonic_clock.h index 1122f37c..36c1205 100644 --- a/chromecast/media/api/monotonic_clock.h +++ b/chromecast/media/api/monotonic_clock.h
@@ -7,12 +7,16 @@ #include <stdint.h> +#include <memory> + namespace chromecast { namespace media { // Interface that provides the monotonic time. class MonotonicClock { public: + static std::unique_ptr<MonotonicClock> Create(); + virtual ~MonotonicClock() = default; // Returns the monotonic time in microseconds. virtual int64_t Now() const = 0;
diff --git a/chromecast/media/base/default_monotonic_clock.cc b/chromecast/media/base/default_monotonic_clock.cc index 71135b0..5beebb9 100644 --- a/chromecast/media/base/default_monotonic_clock.cc +++ b/chromecast/media/base/default_monotonic_clock.cc
@@ -6,6 +6,8 @@ #include <time.h> +#include <memory> + #include "base/time/time.h" #include "build/build_config.h" @@ -20,6 +22,11 @@ namespace chromecast { namespace media { +// static +std::unique_ptr<MonotonicClock> MonotonicClock::Create() { + return std::make_unique<DefaultMonotonicClock>(); +} + #if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) int64_t MonotonicClockNow() { timespec now = {0, 0};
diff --git a/chromecast/media/cma/backend/proxy/cma_proxy_handler.h b/chromecast/media/cma/backend/proxy/cma_proxy_handler.h index 4aace33a..d5c06b53 100644 --- a/chromecast/media/cma/backend/proxy/cma_proxy_handler.h +++ b/chromecast/media/cma/backend/proxy/cma_proxy_handler.h
@@ -6,6 +6,7 @@ #define CHROMECAST_MEDIA_CMA_BACKEND_PROXY_CMA_PROXY_HANDLER_H_ #include "base/memory/ref_counted.h" +#include "chromecast/media/cma/backend/proxy/buffer_id_manager.h" namespace chromecast { @@ -38,6 +39,16 @@ kPaused = 3, }; + // Timing information about a buffer to be targeted for playback changes. + struct TargetBufferInfo { + // The ID associated with the target buffer. + BufferIdManager::BufferId buffer_id; + + // The timestamp at which the target buffer is expected to play in + // microseconds, as returned by MonotonicClock::Now(). + int64_t timestamp_micros; + }; + // Observer for changes on the remote client. class Client { public: @@ -67,10 +78,11 @@ // any thread. virtual void Initialize(const std::string& cast_session_id, AudioDecoderOperationMode decoder_mode) = 0; - virtual void Start(int64_t start_pts) = 0; + virtual void Start(int64_t start_pts, + const TargetBufferInfo& target_buffer) = 0; virtual void Stop() = 0; virtual void Pause() = 0; - virtual void Resume() = 0; + virtual void Resume(const TargetBufferInfo& target_buffer) = 0; virtual void SetPlaybackRate(float rate) = 0; virtual void SetVolume(float multiplier) = 0; @@ -84,7 +96,8 @@ // - SetConfig may be called later on as-well, after which time the new config // will be used for all following PushBuffer calls. virtual bool SetConfig(const AudioConfig& config) = 0; - virtual bool PushBuffer(scoped_refptr<DecoderBufferBase> buffer) = 0; + virtual bool PushBuffer(scoped_refptr<DecoderBufferBase> buffer, + BufferIdManager::BufferId buffer_id) = 0; }; } // namespace media
diff --git a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc index 50e4aa3c..daf6749 100644 --- a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc +++ b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc
@@ -5,6 +5,7 @@ #include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h" #include "base/notreached.h" +#include "chromecast/media/api/monotonic_clock.h" #include "chromecast/public/media/decoder_config.h" #include "chromecast/public/media/media_pipeline_device_params.h" @@ -17,8 +18,11 @@ : MultizoneAudioDecoderProxy(downstream_decoder), cast_session_id_(params.session_id), decoder_mode_(CmaProxyHandler::AudioDecoderOperationMode::kMultiroomOnly), - proxy_handler_(CmaProxyHandler::Create(params.task_runner, this)) { + proxy_handler_(CmaProxyHandler::Create(params.task_runner, this)), + clock_(MonotonicClock::Create()), + buffer_id_manager_(this) { DCHECK(proxy_handler_); + DCHECK(clock_); } MultizoneAudioDecoderProxyImpl::MultizoneAudioDecoderProxyImpl( @@ -37,7 +41,7 @@ void MultizoneAudioDecoderProxyImpl::Start(int64_t start_pts) { CheckCalledOnCorrectThread(); - proxy_handler_->Start(start_pts); + proxy_handler_->Start(start_pts, CreateTargetBufferInfo()); } void MultizoneAudioDecoderProxyImpl::Stop() { @@ -52,7 +56,7 @@ void MultizoneAudioDecoderProxyImpl::Resume() { CheckCalledOnCorrectThread(); - proxy_handler_->Resume(); + proxy_handler_->Resume(CreateTargetBufferInfo()); } void MultizoneAudioDecoderProxyImpl::SetPlaybackRate(float rate) { @@ -78,10 +82,16 @@ return pts_offset_; } +CmaProxyHandler::TargetBufferInfo +MultizoneAudioDecoderProxyImpl::CreateTargetBufferInfo() { + return {buffer_id_manager_.GetCurrentlyProcessingBuffer(), clock_->Now()}; +} + MultizoneAudioDecoderProxy::BufferStatus MultizoneAudioDecoderProxyImpl::PushBuffer( scoped_refptr<DecoderBufferBase> buffer) { - if (!proxy_handler_->PushBuffer(buffer)) { + if (!proxy_handler_->PushBuffer( + buffer, buffer_id_manager_.AssignBufferId(buffer->data_size()))) { return BufferStatus::kBufferFailed; }
diff --git a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h index 25edf63a..330a625 100644 --- a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h +++ b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "chromecast/media/api/cma_backend.h" #include "chromecast/media/api/decoder_buffer_base.h" +#include "chromecast/media/cma/backend/proxy/buffer_id_manager.h" #include "chromecast/media/cma/backend/proxy/cma_proxy_handler.h" #include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h" @@ -18,6 +19,7 @@ struct AudioConfig; struct MediaPipelineDeviceParams; +class MonotonicClock; // This class is used to proxy audio data to an external // CmaBackend::AudioDecoder over gRPC. @@ -58,6 +60,9 @@ void GetStatistics(CmaBackend::AudioDecoder::Statistics* statistics) override; private: + // Helper for creating TargetBufferInfo types. + CmaProxyHandler::TargetBufferInfo CreateTargetBufferInfo(); + // CmaProxyHandler::Client overrides: void OnError() override; void OnPipelineStateChange(CmaProxyHandler::PipelineState state) override; @@ -79,6 +84,11 @@ // public method calls should call into this instance to proxy the call to // the remote backend. std::unique_ptr<CmaProxyHandler> proxy_handler_; + + // Clock used for timing information. + std::unique_ptr<MonotonicClock> clock_; + + BufferIdManager buffer_id_manager_; }; } // namespace media
diff --git a/chromecast/media/cma/backend/proxy/proxy_call_translator.cc b/chromecast/media/cma/backend/proxy/proxy_call_translator.cc index 566de547..bb1cc2e 100644 --- a/chromecast/media/cma/backend/proxy/proxy_call_translator.cc +++ b/chromecast/media/cma/backend/proxy/proxy_call_translator.cc
@@ -141,9 +141,11 @@ } CastRuntimeAudioChannelBroker::Handler::PushBufferRequest ToGrpcTypes( - scoped_refptr<DecoderBufferBase> buffer) { + scoped_refptr<DecoderBufferBase> buffer, + BufferIdManager::BufferId buffer_id) { auto* decode_buffer = new cast::media::AudioDecoderBuffer; + decode_buffer->set_id(buffer_id); decode_buffer->set_end_of_stream(buffer->end_of_stream()); if (!buffer->end_of_stream()) { decode_buffer->set_pts_micros(buffer->timestamp()); @@ -183,6 +185,16 @@ return request; } +CastRuntimeAudioChannelBroker::TimestampInfo ToGrpcTypes( + const CmaProxyHandler::TargetBufferInfo& target_buffer) { + CastRuntimeAudioChannelBroker::TimestampInfo ts_info; + ts_info.set_buffer_id(target_buffer.buffer_id); + *ts_info.mutable_system_timestamp() = + google::protobuf::util::TimeUtil::MicrosecondsToDuration( + target_buffer.timestamp_micros); + return ts_info; +} + // Helper to convert from Chromium callback type (OnceCallback) to Chromecast's // TaskRunner's Task type. class OnceCallbackTask : public TaskRunner::Task { @@ -235,8 +247,9 @@ decoder_channel_->InitializeAsync(cast_session_id, ToGrpcTypes(decoder_mode)); } -void ProxyCallTranslator::Start(int64_t start_pts) { - decoder_channel_->StartAsync(start_pts, {}); +void ProxyCallTranslator::Start(int64_t start_pts, + const TargetBufferInfo& target_buffer) { + decoder_channel_->StartAsync(start_pts, ToGrpcTypes(target_buffer)); } void ProxyCallTranslator::Stop() { @@ -247,8 +260,8 @@ decoder_channel_->PauseAsync(); } -void ProxyCallTranslator::Resume() { - decoder_channel_->ResumeAsync({}); +void ProxyCallTranslator::Resume(const TargetBufferInfo& target_buffer) { + decoder_channel_->ResumeAsync(ToGrpcTypes(target_buffer)); } void ProxyCallTranslator::SetPlaybackRate(float rate) { @@ -263,8 +276,10 @@ return push_buffer_queue_.PushBuffer(ToGrpcTypes(config)); } -bool ProxyCallTranslator::PushBuffer(scoped_refptr<DecoderBufferBase> buffer) { - return push_buffer_queue_.PushBuffer(ToGrpcTypes(std::move(buffer))); +bool ProxyCallTranslator::PushBuffer(scoped_refptr<DecoderBufferBase> buffer, + BufferIdManager::BufferId buffer_id) { + return push_buffer_queue_.PushBuffer( + ToGrpcTypes(std::move(buffer), buffer_id)); } base::Optional<ProxyCallTranslator::PushBufferRequest>
diff --git a/chromecast/media/cma/backend/proxy/proxy_call_translator.h b/chromecast/media/cma/backend/proxy/proxy_call_translator.h index 1eedbff..6ac4f17 100644 --- a/chromecast/media/cma/backend/proxy/proxy_call_translator.h +++ b/chromecast/media/cma/backend/proxy/proxy_call_translator.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "base/optional.h" #include "chromecast/media/api/decoder_buffer_base.h" +#include "chromecast/media/cma/backend/proxy/buffer_id_manager.h" #include "chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h" #include "chromecast/media/cma/backend/proxy/cma_proxy_handler.h" #include "chromecast/media/cma/backend/proxy/push_buffer_queue.h" @@ -39,14 +40,15 @@ void Initialize( const std::string& cast_session_id, CmaProxyHandler::AudioDecoderOperationMode decoder_mode) override; - void Start(int64_t start_pts) override; + void Start(int64_t start_pts, const TargetBufferInfo& target_buffer) override; void Stop() override; void Pause() override; - void Resume() override; + void Resume(const TargetBufferInfo& target_buffer) override; void SetPlaybackRate(float rate) override; void SetVolume(float multiplier) override; bool SetConfig(const AudioConfig& config) override; - bool PushBuffer(scoped_refptr<DecoderBufferBase> buffer) override; + bool PushBuffer(scoped_refptr<DecoderBufferBase> buffer, + BufferIdManager::BufferId buffer_id) override; private: friend class ProxyCallTranslatorTest;
diff --git a/chromecast/media/cma/backend/proxy/proxy_call_translator_unittest.cc b/chromecast/media/cma/backend/proxy/proxy_call_translator_unittest.cc index 17105f1..1e4540c 100644 --- a/chromecast/media/cma/backend/proxy/proxy_call_translator_unittest.cc +++ b/chromecast/media/cma/backend/proxy/proxy_call_translator_unittest.cc
@@ -8,6 +8,7 @@ #include "base/memory/scoped_refptr.h" #include "base/test/test_simple_task_runner.h" +#include "base/time/time.h" #include "chromecast/base/task_runner_impl.h" #include "chromecast/media/base/cast_decoder_buffer_impl.h" #include "chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h" @@ -21,6 +22,16 @@ namespace media { namespace { +ACTION_P(CompareTimestampInfos, buffer_id, timestamp) { + const CastRuntimeAudioChannelBroker::TimestampInfo& result = arg0; + EXPECT_EQ(result.buffer_id(), buffer_id); + const int64_t micros = + result.system_timestamp().seconds() * base::Time::kMicrosecondsPerSecond + + result.system_timestamp().nanos() / + base::Time::kNanosecondsPerMicrosecond; + EXPECT_EQ(micros, timestamp); +} + class MockTranslatorClient : public CmaProxyHandler::Client { public: ~MockTranslatorClient() override = default; @@ -112,8 +123,16 @@ TEST_F(ProxyCallTranslatorTest, TestExternalStart) { constexpr int64_t start_pts = 42; - EXPECT_CALL(*decoder_channel_, StartAsync(start_pts, testing::_)); - translator_.Start(start_pts); + ProxyCallTranslator::TargetBufferInfo target_buffer_info; + static constexpr int64_t timestamp = 112358; + static constexpr BufferIdManager::BufferId buffer_id = 12481516; + target_buffer_info.buffer_id = buffer_id; + target_buffer_info.timestamp_micros = timestamp; + + EXPECT_CALL(*decoder_channel_, StartAsync(start_pts, testing::_)) + .WillOnce( + testing::WithArgs<1>(CompareTimestampInfos(buffer_id, timestamp))); + translator_.Start(start_pts, target_buffer_info); } TEST_F(ProxyCallTranslatorTest, TestExternalStop) { @@ -127,8 +146,16 @@ } TEST_F(ProxyCallTranslatorTest, TestExternalResume) { - EXPECT_CALL(*decoder_channel_, ResumeAsync(testing::_)); - translator_.Resume(); + ProxyCallTranslator::TargetBufferInfo target_buffer_info; + static constexpr int64_t timestamp = 112358; + static constexpr BufferIdManager::BufferId buffer_id = 12481516; + target_buffer_info.buffer_id = buffer_id; + target_buffer_info.timestamp_micros = timestamp; + + EXPECT_CALL(*decoder_channel_, ResumeAsync(testing::_)) + .WillOnce( + testing::WithArgs<0>(CompareTimestampInfos(buffer_id, timestamp))); + translator_.Resume(target_buffer_info); } TEST_F(ProxyCallTranslatorTest, TestExternalSetPlaybackRate) { @@ -149,15 +176,17 @@ buffer->writable_data()[0] = 1; buffer->writable_data()[1] = 2; buffer->writable_data()[2] = 3; - EXPECT_TRUE(translator_.PushBuffer(buffer)); + EXPECT_TRUE(translator_.PushBuffer(buffer, 1)); - EXPECT_TRUE(translator_.PushBuffer(CastDecoderBufferImpl::CreateEOSBuffer())); + EXPECT_TRUE( + translator_.PushBuffer(CastDecoderBufferImpl::CreateEOSBuffer(), 2)); ASSERT_TRUE(translator_as_handler_->HasBufferedData()); auto result = translator_as_handler_->GetBufferedData(); ASSERT_TRUE(result.has_value()); EXPECT_FALSE(result.value().has_audio_config()); ASSERT_TRUE(result.value().has_buffer()); + EXPECT_EQ(result.value().buffer().id(), 1); EXPECT_FALSE(result.value().buffer().end_of_stream()); EXPECT_EQ(result.value().buffer().data().size(), size_t{3}); EXPECT_EQ(result.value().buffer().data()[0], 1); @@ -169,6 +198,7 @@ ASSERT_TRUE(result.has_value()); EXPECT_FALSE(result.value().has_audio_config()); ASSERT_TRUE(result.value().has_buffer()); + EXPECT_EQ(result.value().buffer().id(), 2); EXPECT_TRUE(result.value().buffer().end_of_stream()); EXPECT_EQ(result.value().buffer().data().size(), size_t{0}); }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index e6b9c086..873600e 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13766.0.0 \ No newline at end of file +13770.0.0 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/BUILD.gn b/chromeos/components/camera_app_ui/BUILD.gn index 5149c5b..749b77db 100644 --- a/chromeos/components/camera_app_ui/BUILD.gn +++ b/chromeos/components/camera_app_ui/BUILD.gn
@@ -52,7 +52,7 @@ group("closure_compile") { testonly = true - deps = [ "resources:closure_compile" ] + deps = [ "resources/js:closure_compile" ] } mojom("mojo_bindings") {
diff --git a/chromeos/components/camera_app_ui/resources/BUILD.gn b/chromeos/components/camera_app_ui/resources/BUILD.gn index 0a7c39113..298b828 100644 --- a/chromeos/components/camera_app_ui/resources/BUILD.gn +++ b/chromeos/components/camera_app_ui/resources/BUILD.gn
@@ -2,271 +2,14 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//chromeos/components/camera_app_ui/camera_app_ui.gni") - -group("closure_compile") { - deps = [ "js:closure_compile" ] -} +# We keep this file only for installing the Chrome app version of the camera app +# to migrate the pinned status to SWA version. group("chrome_camera_app") { - # According to crbug.com/855747, we should list all the files we want to copy - # rather than list only the folders to avoid potential building issue and ease - # the difficulty to diagnose. - deps = [ "strings" ] - - data_deps = [ - ":chrome_camera_app_base", - ":chrome_camera_app_css", - ":chrome_camera_app_images", - ":chrome_camera_app_js", - ":chrome_camera_app_js_browser_proxy", - ":chrome_camera_app_js_device", - ":chrome_camera_app_js_lib", - ":chrome_camera_app_js_models", - ":chrome_camera_app_js_mojo", - ":chrome_camera_app_js_views", - ":chrome_camera_app_js_views_camera", - ":chrome_camera_app_js_views_camera_mode", - ":chrome_camera_app_js_window_controller", - ":chrome_camera_app_mojo_generated", - ":chrome_camera_app_preload_images_js", - ":chrome_camera_app_sounds", - ":chrome_camera_app_views", - ] + data_deps = [ ":chrome_camera_app_base" ] } copy("chrome_camera_app_base") { sources = [ "manifest.json" ] - - outputs = [ "$out_camera_app_dir/{{source_file_part}}" ] -} - -copy("chrome_camera_app_css") { - sources = [ "css/main.css" ] - - outputs = [ "$out_camera_app_dir/css/{{source_file_part}}" ] -} - -import("images/images.gni") - -copy("chrome_camera_app_images") { - sources = [ - "images/camera_app_icons_128.png", - "images/camera_app_icons_48.png", - ] - foreach(asset, in_app_assets) { - sources += [ "images/$asset" ] - } - - outputs = [ "$out_camera_app_dir/images/{{source_file_part}}" ] -} - -copy("chrome_camera_app_preload_images_js") { - deps = [ "js:gen_preload_images_js" ] - js_gen_dir = get_label_info(deps[0], "target_gen_dir") - sources = [ "$js_gen_dir/preload_images.js" ] - - outputs = [ "$out_camera_app_dir/js/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js") { - sources = [ - "js/animation.js", - "js/app_window.js", - "js/async_job_queue.js", - "js/background.js", - "js/background_ops.js", - "js/barcode_chip.js", - "js/chrome_util.js", - "js/dom.js", - "js/dynamic_import.js", - "js/error.js", - "js/gallerybutton.js", - "js/h264.js", - "js/init.js", - "js/intent.js", - "js/main.js", - "js/metrics.js", - "js/nav.js", - "js/perf.js", - "js/snackbar.js", - "js/sound.js", - "js/state.js", - "js/test_bridge.js", - "js/timer.js", - "js/toast.js", - "js/tooltip.js", - "js/type.js", - "js/untrusted_ga_helper.js", - "js/untrusted_helper_interfaces.js", - "js/untrusted_script_loader.js", - "js/untrusted_video_processor_helper.js", - "js/util.js", - "js/waitable_event.js", - ] - - outputs = [ "$out_camera_app_dir/js/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_browser_proxy") { - sources = [ - # TODO(b/129956426): Remove dependency used only in closure compiler check. - "js/browser_proxy/browser_proxy.js", - "js/browser_proxy/browser_proxy_interface.js", - ] - - outputs = [ "$out_camera_app_dir/js/browser_proxy/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_device") { - sources = [ - "js/device/camera3_device_info.js", - "js/device/constraints_preferrer.js", - "js/device/device_info_updater.js", - ] - - outputs = [ "$out_camera_app_dir/js/device/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_lib") { - sources = [ - "js/lib/analytics.js", - "js/lib/comlink.js", - "js/lib/ffmpeg.js", - "js/lib/ffmpeg.wasm", - ] - - outputs = [ "$out_camera_app_dir/js/lib/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_models") { - sources = [ - "js/models/async_interval.js", - "js/models/async_writer.js", - "js/models/barcode.js", - "js/models/barcode_worker.js", - "js/models/barcode_worker_interface.js", - "js/models/chrome_file_system_entry.js", - "js/models/file_namer.js", - "js/models/file_system.js", - "js/models/file_system_entry.js", - "js/models/file_util.js", - "js/models/lazy_directory_entry.js", - "js/models/mp4_video_processor.js", - "js/models/result_saver.js", - "js/models/video_processor_interface.js", - "js/models/video_saver.js", - ] - - outputs = [ "$out_camera_app_dir/js/models/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_mojo") { - sources = [ - "js/mojo/chrome_helper.js", - "js/mojo/device_operator.js", - "js/mojo/image_capture.js", - ] - - outputs = [ "$out_camera_app_dir/js/mojo/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_views") { - sources = [ - "js/views/camera.js", - "js/views/camera_intent.js", - "js/views/dialog.js", - "js/views/settings.js", - "js/views/view.js", - "js/views/warning.js", - ] - - outputs = [ "$out_camera_app_dir/js/views/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_views_camera") { - sources = [ - "js/views/camera/layout.js", - "js/views/camera/options.js", - "js/views/camera/preview.js", - "js/views/camera/review_result.js", - "js/views/camera/timertick.js", - "js/views/camera/video_encoder_options.js", - ] - - outputs = [ "$out_camera_app_dir/js/views/camera/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_views_camera_mode") { - sources = [ - "js/views/camera/mode/index.js", - "js/views/camera/mode/mode_base.js", - "js/views/camera/mode/photo.js", - "js/views/camera/mode/portrait.js", - "js/views/camera/mode/record_time.js", - "js/views/camera/mode/square.js", - "js/views/camera/mode/video.js", - ] - - outputs = [ "$out_camera_app_dir/js/views/camera/mode/{{source_file_part}}" ] -} - -copy("chrome_camera_app_js_window_controller") { - sources = [ - "js/window_controller/mojo_window_controller.js", - "js/window_controller/window_controller.js", - "js/window_controller/window_controller_interface.js", - ] - - outputs = [ "$out_camera_app_dir/js/window_controller/{{source_file_part}}" ] -} - -copy("chrome_camera_app_sounds") { - sources = [ - "sounds/record_end.ogg", - "sounds/record_pause.ogg", - "sounds/record_start.ogg", - "sounds/shutter.ogg", - "sounds/tick_final.ogg", - "sounds/tick_inc.ogg", - "sounds/tick_start.ogg", - ] - - outputs = [ "$out_camera_app_dir/sounds/{{source_file_part}}" ] -} - -copy("chrome_camera_app_views") { - sources = [ - "views/background.html", - "views/main.html", - "views/untrusted_script_loader.html", - ] - - outputs = [ "$out_camera_app_dir/views/{{source_file_part}}" ] -} - -copy("chrome_camera_app_mojo_generated") { - sources = [ - "$root_gen_dir/chromeos/components/camera_app_ui/camera_app_helper.mojom-lite.js", - "$root_gen_dir/components/arc/mojom/camera_intent.mojom-lite.js", - "$root_gen_dir/media/capture/mojom/image_capture.mojom-lite.js", - "$root_gen_dir/media/capture/video/chromeos/mojom/camera_app.mojom-lite.js", - "$root_gen_dir/media/capture/video/chromeos/mojom/camera_common.mojom-lite.js", - "$root_gen_dir/media/capture/video/chromeos/mojom/camera_metadata.mojom-lite.js", - "$root_gen_dir/media/capture/video/chromeos/mojom/camera_metadata_tags.mojom-lite.js", - "$root_gen_dir/mojo/public/js/mojo_bindings_lite.js", - "$root_gen_dir/mojo/public/mojom/base/time.mojom-lite.js", - "$root_gen_dir/third_party/blink/public/mojom/idle/idle_manager.mojom-lite.js", - "$root_gen_dir/ui/gfx/geometry/mojom/geometry.mojom-lite.js", - "$root_gen_dir/ui/gfx/range/mojom/range.mojom-lite.js", - ] - - deps = [ - "//chromeos/components/camera_app_ui:mojo_bindings_js", - "//media/capture/video/chromeos/mojom:cros_camera_js", - "//mojo/public/js:bindings_lite", - "//third_party/blink/public/mojom:mojom_platform_js", - ] - - outputs = [ "$out_camera_app_dir/js/mojo/{{source_file_part}}" ] + outputs = [ "$root_out_dir/resources/chromeos/camera/{{source_file_part}}" ] }
diff --git a/chromeos/components/camera_app_ui/resources/js/externs/types.d.ts b/chromeos/components/camera_app_ui/resources/js/externs/types.d.ts index ea8a739..dc4f585 100644 --- a/chromeos/components/camera_app_ui/resources/js/externs/types.d.ts +++ b/chromeos/components/camera_app_ui/resources/js/externs/types.d.ts
@@ -10,8 +10,13 @@ declare var arc: MojomNamespace; declare var blink: MojomNamespace; +declare var chromeosCamera: MojomNamespace; declare var cros: MojomNamespace; +// TODO(b/172340451): Remove this once we fully removed the legacy Chrome app +// support. +declare var chrome: any; + // This is currently a Chrome only API, and the spec is still in working draft // stage. // https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/sourceCapabilities
diff --git a/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js b/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js index 78c7ad08..a0f1e4d 100644 --- a/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js +++ b/chromeos/components/camera_app_ui/resources/js/mojo/device_operator.js
@@ -174,6 +174,21 @@ } /** + * Gets metadata for the given device from its static characteristics. + * @param {string} deviceId The id of target camera device. + * @param {!cros.mojom.CameraMetadataTag} tag Camera metadata tag to query. + * @return {!Promise<!Array<number>>} Promise of the corresponding data + * array. + * @throws {!Error} Thrown when given device id is invalid. + */ + async getStaticMetadata(deviceId, tag) { + const device = await this.getDevice_(deviceId); + const {cameraInfo} = await device.getCameraInfo(); + const staticMetadata = cameraInfo.staticCameraCharacteristics; + return getMetadataData(staticMetadata, tag); + } + + /** * Gets supported photo resolutions for specific camera. * @param {string} deviceId The renderer-facing device id of the target camera * which could be retrieved from MediaDeviceInfo.deviceId. @@ -186,11 +201,8 @@ const typeOutputStream = 0; const numElementPerEntry = 4; - const device = await this.getDevice_(deviceId); - const {cameraInfo} = await device.getCameraInfo(); - const staticMetadata = cameraInfo.staticCameraCharacteristics; - const streamConfigs = getMetadataData( - staticMetadata, + const streamConfigs = await this.getStaticMetadata( + deviceId, cros.mojom.CameraMetadataTag .ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); // The data of |streamConfigs| looks like: @@ -226,11 +238,8 @@ const oneSecondInNs = 1e9; const numElementPerEntry = 4; - const device = await this.getDevice_(deviceId); - const {cameraInfo} = await device.getCameraInfo(); - const staticMetadata = cameraInfo.staticCameraCharacteristics; - const minFrameDurationConfigs = getMetadataData( - staticMetadata, + const minFrameDurationConfigs = await this.getStaticMetadata( + deviceId, cros.mojom.CameraMetadataTag .ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS); // The data of |minFrameDurationConfigs| looks like: @@ -288,11 +297,8 @@ async getSupportedFpsRanges(deviceId) { const numElementPerEntry = 2; - const device = await this.getDevice_(deviceId); - const {cameraInfo} = await device.getCameraInfo(); - const staticMetadata = cameraInfo.staticCameraCharacteristics; - const availableFpsRanges = getMetadataData( - staticMetadata, + const availableFpsRanges = await this.getStaticMetadata( + deviceId, cros.mojom.CameraMetadataTag .ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); // The data of |availableFpsRanges| looks like: @@ -367,11 +373,9 @@ const portraitModeTag = /** @type{!cros.mojom.CameraMetadataTag} */ (-0x80000000); - const device = await this.getDevice_(deviceId); - const {cameraInfo} = await device.getCameraInfo(); - return getMetadataData( - cameraInfo.staticCameraCharacteristics, portraitModeTag) - .length > 0; + const portraitMode = + await this.getStaticMetadata(deviceId, portraitModeTag); + return portraitMode.length > 0; } /**
diff --git a/chromeos/components/camera_app_ui/resources/manifest.json b/chromeos/components/camera_app_ui/resources/manifest.json index 3f8f979..b052ecc1 100644 --- a/chromeos/components/camera_app_ui/resources/manifest.json +++ b/chromeos/components/camera_app_ui/resources/manifest.json
@@ -3,31 +3,7 @@ "manifest_version": 2, "name": "__MSG_name__", "description": "__MSG_description__", - "version": "6.1.0", + "version": "6.2.0", "default_locale": "en", - "minimum_chrome_version": "60.0.0.0", - "icons": { - "48": "images/camera_app_icons_48.png", - "128": "images/camera_app_icons_128.png" - }, - "permissions": [ - "notifications", - "videoCapture", - "audioCapture", - "storage", - "system.display", - "unlimitedStorage", - "idle", - "chromeosInfoPrivate", - "metricsPrivate", - "fileManagerPrivate", - "fileSystem.requestDownloads", - {"fileSystem": ["write", "directory"]}, - "https://www.google-analytics.com/" - ], - "app": { - "background": { - "page": "views/background.html" - } - } + "minimum_chrome_version": "60.0.0.0" }
diff --git a/chromeos/components/drivefs/fake_drivefs.cc b/chromeos/components/drivefs/fake_drivefs.cc index 40aa893d..403c907c 100644 --- a/chromeos/components/drivefs/fake_drivefs.cc +++ b/chromeos/components/drivefs/fake_drivefs.cc
@@ -291,6 +291,13 @@ } } +void FakeDriveFs::DisplayConfirmDialog( + drivefs::mojom::DialogReasonPtr reason, + drivefs::mojom::DriveFsDelegate::DisplayConfirmDialogCallback callback) { + DCHECK(delegate_); + delegate_->DisplayConfirmDialog(std::move(reason), std::move(callback)); +} + void FakeDriveFs::Init( drivefs::mojom::DriveFsConfigurationPtr config, mojo::PendingReceiver<drivefs::mojom::DriveFs> receiver,
diff --git a/chromeos/components/drivefs/fake_drivefs.h b/chromeos/components/drivefs/fake_drivefs.h index 7bba931..0154ae4 100644 --- a/chromeos/components/drivefs/fake_drivefs.h +++ b/chromeos/components/drivefs/fake_drivefs.h
@@ -58,6 +58,10 @@ const mojom::FolderFeature& folder_feature, const std::string& doc_id); + void DisplayConfirmDialog( + drivefs::mojom::DialogReasonPtr reason, + drivefs::mojom::DriveFsDelegate::DisplayConfirmDialogCallback callback); + const base::FilePath& mount_path() { return mount_path_; } private:
diff --git a/chromeos/components/eche_app_ui/BUILD.gn b/chromeos/components/eche_app_ui/BUILD.gn index eac4716..ca7b93b7 100644 --- a/chromeos/components/eche_app_ui/BUILD.gn +++ b/chromeos/components/eche_app_ui/BUILD.gn
@@ -46,6 +46,7 @@ "index.html", "app.js", "app.css", + "eche_icon_256.png", ] manifest_files = [] grd_prefix = "chromeos_eche_app"
diff --git a/chromeos/components/eche_app_ui/resources/eche_icon_256.png b/chromeos/components/eche_app_ui/resources/eche_icon_256.png new file mode 100644 index 0000000..0e07192 --- /dev/null +++ b/chromeos/components/eche_app_ui/resources/eche_icon_256.png Binary files differ
diff --git a/chromeos/components/phonehub/BUILD.gn b/chromeos/components/phonehub/BUILD.gn index 06fea63..44eba1d 100644 --- a/chromeos/components/phonehub/BUILD.gn +++ b/chromeos/components/phonehub/BUILD.gn
@@ -63,6 +63,8 @@ "notification_manager.h", "notification_manager_impl.cc", "notification_manager_impl.h", + "notification_processor.cc", + "notification_processor.h", "onboarding_ui_tracker.cc", "onboarding_ui_tracker.h", "onboarding_ui_tracker_impl.cc", @@ -108,6 +110,7 @@ "//components/session_manager/core", "//device/bluetooth", "//net", + "//services/data_decoder/public/cpp", "//ui/gfx", "//url", ] @@ -192,6 +195,7 @@ "mutable_phone_model_unittest.cc", "notification_access_manager_impl_unittest.cc", "notification_manager_impl_unittest.cc", + "notification_processor_unittest.cc", "onboarding_ui_tracker_impl_unittest.cc", "phone_status_model_unittest.cc", "phone_status_processor_unittest.cc", @@ -223,5 +227,6 @@ "//device/bluetooth:mocks", "//testing/gtest", "//ui/gfx", + "//ui/gfx:test_support", ] }
diff --git a/chromeos/components/phonehub/DEPS b/chromeos/components/phonehub/DEPS index da4e7a4..3653ddc 100644 --- a/chromeos/components/phonehub/DEPS +++ b/chromeos/components/phonehub/DEPS
@@ -10,5 +10,6 @@ "+components/session_manager/core", "+device/bluetooth", "+net", + "+services/data_decoder/public/cpp", "+ui/gfx", ]
diff --git a/chromeos/components/phonehub/notification_manager.h b/chromeos/components/phonehub/notification_manager.h index 7b7ecbf..0fbc9200 100644 --- a/chromeos/components/phonehub/notification_manager.h +++ b/chromeos/components/phonehub/notification_manager.h
@@ -61,7 +61,8 @@ void RemoveObserver(Observer* observer); protected: - friend class PhoneStatusProcessor; + friend class FakeNotificationProcessor; + friend class NotificationProcessor; friend class NotificationManagerImplTest; NotificationManager();
diff --git a/chromeos/components/phonehub/notification_processor.cc b/chromeos/components/phonehub/notification_processor.cc new file mode 100644 index 0000000..777701a --- /dev/null +++ b/chromeos/components/phonehub/notification_processor.cc
@@ -0,0 +1,286 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/phonehub/notification_processor.h" + +#include "base/barrier_closure.h" +#include "base/callback.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "chromeos/components/multidevice/logging/logging.h" +#include "chromeos/components/phonehub/notification.h" +#include "chromeos/components/phonehub/notification_manager.h" +#include "services/data_decoder/public/cpp/decode_image.h" +#include "ui/gfx/image/image_skia.h" + +namespace chromeos { +namespace phonehub { +namespace { + +Notification::Importance GetNotificationImportanceFromProto( + proto::NotificationImportance importance) { + switch (importance) { + case proto::NotificationImportance::UNSPECIFIED: + return Notification::Importance::kUnspecified; + case proto::NotificationImportance::NONE: + return Notification::Importance::kNone; + case proto::NotificationImportance::MIN: + return Notification::Importance::kMin; + case proto::NotificationImportance::LOW: + return Notification::Importance::kLow; + case proto::NotificationImportance::DEFAULT: + return Notification::Importance::kDefault; + case proto::NotificationImportance::HIGH: + return Notification::Importance::kHigh; + default: + return Notification::Importance::kUnspecified; + } +} + +base::Optional<int64_t> GetInlineReplyIdFromProto( + const proto::Notification& proto) { + auto actions_it = std::find_if( + proto.actions().begin(), proto.actions().end(), [](const auto& action) { + return action.type() == proto::Action_InputType::Action_InputType_TEXT; + }); + + if (actions_it == proto.actions().end()) + return base::nullopt; + + return actions_it->id(); +} + +Notification CreateInlineReplyNotification(const proto::Notification& proto, + const gfx::Image& icon, + const gfx::Image& shared_image, + const gfx::Image& contact_image) { + base::Optional<int64_t> inline_reply_id = GetInlineReplyIdFromProto(proto); + DCHECK(inline_reply_id.has_value()); + + base::Optional<base::string16> title = base::nullopt; + if (!proto.title().empty()) + title = base::UTF8ToUTF16(proto.title()); + + base::Optional<base::string16> text_content = base::nullopt; + if (!proto.text_content().empty()) + text_content = base::UTF8ToUTF16(proto.text_content()); + + base::Optional<gfx::Image> opt_shared_image = base::nullopt; + if (!shared_image.IsEmpty()) + opt_shared_image = shared_image; + + base::Optional<gfx::Image> opt_contact_image = base::nullopt; + if (!contact_image.IsEmpty()) + opt_contact_image = contact_image; + + return Notification(proto.id(), + Notification::AppMetadata( + base::UTF8ToUTF16(proto.origin_app().visible_name()), + proto.origin_app().package_name(), icon), + base::Time::FromJsTime(proto.epoch_time_millis()), + GetNotificationImportanceFromProto(proto.importance()), + *inline_reply_id, title, text_content, opt_shared_image, + opt_contact_image); +} + +} // namespace + +NotificationProcessor::DecodeImageRequestMetadata::DecodeImageRequestMetadata( + int64_t notification_id, + NotificationImageField image_field, + const std::string& data) + : notification_id(notification_id), image_field(image_field), data(data) {} + +NotificationProcessor::NotificationProcessor( + NotificationManager* notification_manager) + : NotificationProcessor(notification_manager, + std::make_unique<ImageDecoderDelegate>()) {} + +NotificationProcessor::NotificationProcessor( + NotificationManager* notification_manager, + std::unique_ptr<ImageDecoderDelegate> delegate) + : notification_manager_(notification_manager), + delegate_(std::move(delegate)) {} + +NotificationProcessor::~NotificationProcessor() {} + +void NotificationProcessor::ClearNotificationsAndPendingUpdates() { + notification_manager_->ClearNotificationsInternal(); + + // Clear pending updates that may occur. + weak_ptr_factory_.InvalidateWeakPtrs(); + pending_notification_requests_ = base::queue<base::OnceClosure>(); + id_to_images_map_.clear(); +} + +void NotificationProcessor::AddNotifications( + const std::vector<proto::Notification>& notification_protos) { + if (notification_protos.empty()) + return; + + std::vector<proto::Notification> inline_replyable_notification_protos; + std::vector<DecodeImageRequestMetadata> decode_image_requests; + + for (const auto& proto : notification_protos) { + // Only process notifications that are messaging apps with inline-replies. + if (!GetInlineReplyIdFromProto(proto).has_value()) + continue; + + inline_replyable_notification_protos.emplace_back(proto); + + decode_image_requests.emplace_back( + proto.id(), NotificationImageField::kIcon, proto.origin_app().icon()); + + if (!proto.shared_image().empty()) { + decode_image_requests.emplace_back(proto.id(), + NotificationImageField::kSharedImage, + proto.shared_image()); + } + + if (!proto.contact_image().empty()) { + decode_image_requests.emplace_back(proto.id(), + NotificationImageField::kContactImage, + proto.contact_image()); + } + } + + base::RepeatingClosure barrier = base::BarrierClosure( + decode_image_requests.size(), + base::BindOnce(&NotificationProcessor::OnAllImagesDecoded, + weak_ptr_factory_.GetWeakPtr(), + std::move(inline_replyable_notification_protos))); + + base::OnceClosure add_request = + base::BindOnce(&NotificationProcessor::StartDecodingImages, + weak_ptr_factory_.GetWeakPtr(), + std::move(decode_image_requests), barrier); + + pending_notification_requests_.emplace(std::move(add_request)); + ProcessRequestQueue(); +} + +void NotificationProcessor::RemoveNotifications( + const base::flat_set<int64_t>& notification_ids) { + if (notification_ids.empty()) + return; + + base::flat_set<int64_t> removed_notification_ids; + for (const int64_t& id : notification_ids) { + removed_notification_ids.emplace(id); + } + + base::OnceClosure remove_request = base::BindOnce( + &NotificationProcessor::RemoveNotificationsAndProcessNextRequest, + weak_ptr_factory_.GetWeakPtr(), std::move(removed_notification_ids)); + + pending_notification_requests_.emplace(std::move(remove_request)); + ProcessRequestQueue(); +} + +void NotificationProcessor::StartDecodingImages( + const std::vector<DecodeImageRequestMetadata>& decode_image_requests, + base::RepeatingClosure done_closure) { + DCHECK(!decode_image_requests.empty()); + DCHECK(!done_closure.is_null()); + + id_to_images_map_.clear(); + + for (const auto& request : decode_image_requests) { + delegate_->PerformImageDecode( + request.data, + base::BindOnce(&NotificationProcessor::OnDecodedBitmapReady, + weak_ptr_factory_.GetWeakPtr(), request, done_closure)); + } +} + +void NotificationProcessor::ImageDecoderDelegate::PerformImageDecode( + const std::string& data, + DecodeImageCallback single_image_decoded_closure) { + std::vector<uint8_t> image_bytes(data.begin(), data.end()); + data_decoder::DecodeImage( + &data_decoder_, image_bytes, data_decoder::mojom::ImageCodec::DEFAULT, + /*shrink_to_fit=*/true, data_decoder::kDefaultMaxSizeInBytes, + /*desired_image_frame_size=*/gfx::Size(), + std::move(single_image_decoded_closure)); +} + +void NotificationProcessor::OnDecodedBitmapReady( + const DecodeImageRequestMetadata& request, + base::OnceClosure done_closure, + const SkBitmap& decoded_bitmap) { + gfx::ImageSkia image_skia = + gfx::ImageSkia::CreateFrom1xBitmap(decoded_bitmap); + image_skia.MakeThreadSafe(); + + auto it = id_to_images_map_.find(request.notification_id); + if (it == id_to_images_map_.end()) { + it = id_to_images_map_.insert( + it, std::pair<int64_t, NotificationImages>(request.notification_id, + NotificationImages())); + } + + switch (request.image_field) { + case NotificationImageField::kIcon: + it->second.icon = gfx::Image(image_skia); + break; + case NotificationImageField::kSharedImage: + it->second.shared_image = gfx::Image(image_skia); + break; + case NotificationImageField::kContactImage: + it->second.contact_image = gfx::Image(image_skia); + break; + } + + std::move(done_closure).Run(); +} + +void NotificationProcessor::OnAllImagesDecoded( + std::vector<proto::Notification> inline_replyable_notifications) { + base::flat_set<Notification> notifications; + for (const auto& proto : inline_replyable_notifications) { + auto it = id_to_images_map_.find(proto.id()); + if (it == id_to_images_map_.end()) + continue; + + NotificationImages notification_images = it->second; + notifications.emplace(CreateInlineReplyNotification( + proto, notification_images.icon, notification_images.shared_image, + notification_images.contact_image)); + } + + AddNotificationsAndProcessNextRequest(notifications); +} + +void NotificationProcessor::ProcessRequestQueue() { + if (pending_notification_requests_.empty()) + return; + + // Processing the latest request has not been completed. + if (pending_notification_requests_.front().is_null()) + return; + + std::move(pending_notification_requests_.front()).Run(); +} + +void NotificationProcessor::CompleteRequest() { + DCHECK(!pending_notification_requests_.empty()); + DCHECK(pending_notification_requests_.front().is_null()); + pending_notification_requests_.pop(); + ProcessRequestQueue(); +} + +void NotificationProcessor::AddNotificationsAndProcessNextRequest( + const base::flat_set<Notification>& notifications) { + notification_manager_->SetNotificationsInternal(notifications); + CompleteRequest(); +} + +void NotificationProcessor::RemoveNotificationsAndProcessNextRequest( + base::flat_set<int64_t> removed_notification_ids) { + notification_manager_->RemoveNotificationsInternal(removed_notification_ids); + CompleteRequest(); +} + +} // namespace phonehub +} // namespace chromeos \ No newline at end of file
diff --git a/chromeos/components/phonehub/notification_processor.h b/chromeos/components/phonehub/notification_processor.h new file mode 100644 index 0000000..aa25de7 --- /dev/null +++ b/chromeos/components/phonehub/notification_processor.h
@@ -0,0 +1,136 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_PHONEHUB_NOTIFICATION_PROCESSOR_H_ +#define CHROMEOS_COMPONENTS_PHONEHUB_NOTIFICATION_PROCESSOR_H_ + +#include <google/protobuf/repeated_field.h> + +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" +#include "base/containers/queue.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/components/phonehub/proto/phonehub_api.pb.h" +#include "services/data_decoder/public/cpp/data_decoder.h" +#include "ui/gfx/image/image.h" + +using google::protobuf::RepeatedPtrField; + +namespace chromeos { +namespace phonehub { + +class Notification; +class NotificationManager; + +// A helper class that processes inline reply-able notification protos and +// updates the notification manager with such notifications to add or remove. +// Since decoding image(s) included in every notification proto are asynchronous +// calls, this class ensures that additions and removals are scheduled and +// executed synchronously via a queue of requests without unexpected race +// conditions. Note that adding notifications requires using an image utility +// process asynchronously, but removals are carried out synchronously. +class NotificationProcessor { + public: + using DecodeImageCallback = + data_decoder::mojom::ImageDecoder::DecodeImageCallback; + + NotificationProcessor(NotificationManager* notification_manager); + virtual ~NotificationProcessor(); + + NotificationProcessor(const NotificationProcessor&) = delete; + NotificationProcessor& operator=(const NotificationProcessor&) = delete; + + // Removes all notifications and clears pending unfulfilled requests. + void ClearNotificationsAndPendingUpdates(); + + // Adds only inline reply-able notifications by extracting metadata from + // their protos and asynchronously decoding their associated images. + virtual void AddNotifications( + const std::vector<proto::Notification>& notification_protos); + + // Removes notifications with |notifications_ids|. + virtual void RemoveNotifications( + const base::flat_set<int64_t>& notification_ids); + + private: + friend class FakeNotificationProcessor; + friend class NotificationProcessorTest; + + // Used to track which image type is being processed. + enum class NotificationImageField { + kIcon = 0, + kSharedImage = 1, + kContactImage = 2, + }; + + // Each notification proto will be associated with one of these structs. + // |icon| will always be populated, but |shared_image| and |contact_image| may + // be empty. + struct NotificationImages { + gfx::Image icon; + gfx::Image shared_image; + gfx::Image contact_image; + }; + + // Each image to decode will be associated with one of these structs. Each + // request in |pending_notification_requests_| may be associated to multiple + // DecodeImageRequestMetadata with more than one |notification_id|. + struct DecodeImageRequestMetadata { + DecodeImageRequestMetadata(int64_t notification_id, + NotificationImageField image_field, + const std::string& data); + + int64_t notification_id; + NotificationImageField image_field; + std::string data; + }; + + // A delegate class that is faked out for testing purposes. + class ImageDecoderDelegate { + public: + ImageDecoderDelegate() = default; + virtual ~ImageDecoderDelegate() = default; + + virtual void PerformImageDecode( + const std::string& data, + DecodeImageCallback single_image_decoded_closure); + + private: + // The instance of the Data Decoder used by this ImageDecoderDelegate to + // perform any image decoding operations. The underlying service instance is + // started lazily when needed and torn down when not in use. + data_decoder::DataDecoder data_decoder_; + }; + + NotificationProcessor(NotificationManager* notification_manager, + std::unique_ptr<ImageDecoderDelegate> delegate); + + void StartDecodingImages( + const std::vector<DecodeImageRequestMetadata>& decode_image_requests, + base::RepeatingClosure done_closure); + void OnDecodedBitmapReady(const DecodeImageRequestMetadata& request, + base::OnceClosure done_closure, + const SkBitmap& decoded_bitmap); + void OnAllImagesDecoded( + std::vector<proto::Notification> inline_replyable_notifications); + + void ProcessRequestQueue(); + void CompleteRequest(); + void AddNotificationsAndProcessNextRequest( + const base::flat_set<Notification>& notifications); + void RemoveNotificationsAndProcessNextRequest( + base::flat_set<int64_t> removed_notification_ids); + + NotificationManager* notification_manager_; + base::queue<base::OnceClosure> pending_notification_requests_; + base::flat_map<int64_t, NotificationImages> id_to_images_map_; + std::unique_ptr<ImageDecoderDelegate> delegate_; + + base::WeakPtrFactory<NotificationProcessor> weak_ptr_factory_{this}; +}; + +} // namespace phonehub +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_PHONEHUB_NOTIFICATION_PROCESSOR_H_ \ No newline at end of file
diff --git a/chromeos/components/phonehub/notification_processor_unittest.cc b/chromeos/components/phonehub/notification_processor_unittest.cc new file mode 100644 index 0000000..581730d --- /dev/null +++ b/chromeos/components/phonehub/notification_processor_unittest.cc
@@ -0,0 +1,330 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/phonehub/notification_processor.h" + +#include "base/memory/ptr_util.h" +#include "base/test/task_environment.h" +#include "chromeos/components/phonehub/fake_notification_manager.h" +#include "chromeos/components/phonehub/phone_model_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_unittest_util.h" + +namespace chromeos { +namespace phonehub { +namespace { + +constexpr int64_t kNotificationIdA = 1; +constexpr int64_t kNotificationIdB = 2; + +constexpr int64_t kInlineReplyIdA = 3; +constexpr int64_t kInlineReplyIdB = 4; + +const char kIconDataA[] = "icon_a"; +const char kIconDataB[] = "icon_b"; + +const char kSharedImageA[] = "shared_image_a"; +const char kSharedImageB[] = "shared_image_b"; + +const char kContactImageA[] = "contact_image_a"; +const char kContactImageB[] = "contact_image_b"; + +SkBitmap TestBitmap() { + SkBitmap bitmap; + bitmap.allocN32Pixels(1, 1); + return bitmap; +} + +gfx::Image TestImage() { + gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(TestBitmap()); + image_skia.MakeThreadSafe(); + return gfx::Image(image_skia); +} + +} // namespace + +class NotificationProcessorTest : public testing::Test { + public: + friend class NotificationProcessor; + + NotificationProcessorTest() = default; + NotificationProcessorTest(const NotificationProcessorTest&) = delete; + NotificationProcessorTest& operator=(const NotificationProcessorTest&) = + delete; + ~NotificationProcessorTest() override = default; + + class FakeImageDecoderDelegate + : public NotificationProcessor::ImageDecoderDelegate { + public: + using DecodeImageCallback = NotificationProcessor::DecodeImageCallback; + + FakeImageDecoderDelegate() = default; + ~FakeImageDecoderDelegate() override = default; + + void PerformImageDecode( + const std::string& data, + DecodeImageCallback single_image_decoded_closure) override { + decode_image_callbacks_.push(std::move(single_image_decoded_closure)); + } + + size_t NumberOfDecodeImageCallbacks() { + return decode_image_callbacks_.size(); + } + + void RunNextCallback() { + std::move(decode_image_callbacks_.front()).Run(TestBitmap()); + decode_image_callbacks_.pop(); + } + + void RunAllCallbacks() { + while (!decode_image_callbacks_.empty()) + RunNextCallback(); + } + + std::queue<DecodeImageCallback> decode_image_callbacks_; + }; + + // testing::Test: + void SetUp() override { + fake_notification_manager_ = std::make_unique<FakeNotificationManager>(); + + notification_processor_ = base::WrapUnique(new NotificationProcessor( + fake_notification_manager_.get(), + std::make_unique<FakeImageDecoderDelegate>())); + } + + FakeImageDecoderDelegate* image_decoder_delegate() { + return static_cast<FakeImageDecoderDelegate*>( + notification_processor_->delegate_.get()); + } + + NotificationProcessor* notification_processor() { + return notification_processor_.get(); + } + + FakeNotificationManager* fake_notification_manager() { + return fake_notification_manager_.get(); + } + + size_t NumPendingRequests() { + return notification_processor()->pending_notification_requests_.size(); + } + + proto::Notification CreateNewInlineReplyableNotification( + int64_t notification_id, + int64_t inline_reply_id, + std::string icon = std::string(), + std::string shared_image = std::string(), + std::string contact_image = std::string()) { + auto origin_app = std::make_unique<proto::App>(); + origin_app->set_icon(icon); + + proto::Notification notification; + notification.set_id(notification_id); + notification.set_allocated_origin_app(origin_app.release()); + notification.set_contact_image(contact_image); + notification.set_shared_image(shared_image); + + notification.add_actions(); + proto::Action* mutable_action = notification.mutable_actions(0); + mutable_action->set_id(inline_reply_id); + mutable_action->set_type(proto::Action_InputType::Action_InputType_TEXT); + + return notification; + } + + private: + std::unique_ptr<FakeNotificationManager> fake_notification_manager_; + std::unique_ptr<NotificationProcessor> notification_processor_; + + base::test::SingleThreadTaskEnvironment task_environment_; +}; + +TEST_F(NotificationProcessorTest, ImageFieldPopulatedCorrectly) { + std::vector<proto::Notification> first_set_of_notifications; + + // The icon should be populated. The shared and contact image should be null. + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA)); + notification_processor()->AddNotifications(first_set_of_notifications); + image_decoder_delegate()->RunAllCallbacks(); + + const Notification* notification = + fake_notification_manager()->GetNotification(kNotificationIdA); + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + TestImage())); + EXPECT_FALSE(notification->shared_image().has_value()); + EXPECT_FALSE(notification->contact_image().has_value()); + + // The icon and shared image should be populated. The contact image should be + // null. + first_set_of_notifications.clear(); + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA, kSharedImageA)); + notification_processor()->AddNotifications(first_set_of_notifications); + image_decoder_delegate()->RunAllCallbacks(); + + notification = fake_notification_manager()->GetNotification(kNotificationIdA); + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + TestImage())); + EXPECT_TRUE( + gfx::test::AreImagesEqual(*notification->shared_image(), TestImage())); + EXPECT_FALSE(notification->contact_image().has_value()); + + // The icon and contact image should be populated. The shared image should be + // null. + first_set_of_notifications.clear(); + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA, std::string(), + kContactImageA)); + notification_processor()->AddNotifications(first_set_of_notifications); + image_decoder_delegate()->RunAllCallbacks(); + + notification = fake_notification_manager()->GetNotification(kNotificationIdA); + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + TestImage())); + EXPECT_FALSE(notification->shared_image().has_value()); + EXPECT_TRUE( + gfx::test::AreImagesEqual(*notification->contact_image(), TestImage())); + + // All images should be should be populated. + first_set_of_notifications.clear(); + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA, kSharedImageA, + kContactImageA)); + notification_processor()->AddNotifications(first_set_of_notifications); + image_decoder_delegate()->RunAllCallbacks(); + EXPECT_TRUE(gfx::test::AreImagesEqual(notification->app_metadata().icon, + TestImage())); + EXPECT_TRUE( + gfx::test::AreImagesEqual(*notification->shared_image(), TestImage())); + EXPECT_TRUE( + gfx::test::AreImagesEqual(*notification->contact_image(), TestImage())); +} + +TEST_F(NotificationProcessorTest, AddRemoveClearWithoutRace) { + // Add 2 notifications with all images populated. + std::vector<proto::Notification> first_set_of_notifications; + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA, kSharedImageA, + kContactImageA)); + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdB, kInlineReplyIdB, kIconDataB, kSharedImageB, + kContactImageB)); + + notification_processor()->AddNotifications(first_set_of_notifications); + + // 6 image decode callbacks will occur for kIconDataA, kSharedImageA, + // kContactImageA, kIconDataB, kSharedImageB, and kContactImageB. + EXPECT_EQ(6u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + image_decoder_delegate()->RunAllCallbacks(); + + EXPECT_EQ(2u, fake_notification_manager()->num_notifications()); + EXPECT_TRUE(fake_notification_manager()->GetNotification(kNotificationIdA)); + EXPECT_TRUE(fake_notification_manager()->GetNotification(kNotificationIdB)); + + // Remove notification with id kNotificationIdA. + base::flat_set<int64_t> ids_of_notifications_to_remove; + ids_of_notifications_to_remove.emplace(kNotificationIdA); + notification_processor()->RemoveNotifications(ids_of_notifications_to_remove); + EXPECT_EQ(1u, fake_notification_manager()->num_notifications()); + EXPECT_FALSE(fake_notification_manager()->GetNotification(kNotificationIdA)); + EXPECT_TRUE(fake_notification_manager()->GetNotification(kNotificationIdB)); + + // Clear all notifications. + notification_processor()->ClearNotificationsAndPendingUpdates(); + EXPECT_EQ(0u, fake_notification_manager()->num_notifications()); +} + +TEST_F(NotificationProcessorTest, AddRemoveWithRace) { + // Add 2 notifications. + std::vector<proto::Notification> first_set_of_notifications; + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA, kSharedImageA)); + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdB, kInlineReplyIdB, kIconDataB)); + + notification_processor()->AddNotifications(first_set_of_notifications); + + // One pending requests because |first_set_of_notifications| processing + // occurred immediately. + EXPECT_EQ(1u, NumPendingRequests()); + + // Remove notification with id kNotificationIdA while + // |first_set_of_notifications| is still being processed. + base::flat_set<int64_t> ids_of_notifications_to_remove; + ids_of_notifications_to_remove.emplace(kNotificationIdA); + notification_processor()->RemoveNotifications(ids_of_notifications_to_remove); + + // Pending delete request, first in the queue. + EXPECT_EQ(2u, NumPendingRequests()); + EXPECT_EQ(0u, fake_notification_manager()->num_notifications()); + + // Add a set of notifications such that only one image needs to be decoded, + // when neither the first set has completed processing more the remove request + // has been fully processed. + std::vector<proto::Notification> second_set_of_notifications; + second_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA)); + notification_processor()->AddNotifications(second_set_of_notifications); + + // Pending add request, second in the queue. + EXPECT_EQ(3u, NumPendingRequests()); + EXPECT_EQ(0u, fake_notification_manager()->num_notifications()); + + // 3 image decode callbacks will occur. When the last image decode callback is + // finished running, which in this case is icon2, it will cause the next + // notification edit request to be executed. + EXPECT_EQ(3u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + EXPECT_EQ(3u, NumPendingRequests()); + image_decoder_delegate()->RunNextCallback(); + + EXPECT_EQ(2u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + EXPECT_EQ(3u, NumPendingRequests()); + image_decoder_delegate()->RunNextCallback(); + + EXPECT_EQ(1u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + EXPECT_EQ(3u, NumPendingRequests()); + + // The scheduled remove callback will occur, then subsequently the add + // notification with 1 image. + image_decoder_delegate()->RunNextCallback(); + EXPECT_EQ(1u, NumPendingRequests()); + EXPECT_EQ(1u, image_decoder_delegate()->NumberOfDecodeImageCallbacks()); + + EXPECT_EQ(1u, fake_notification_manager()->num_notifications()); + EXPECT_FALSE(fake_notification_manager()->GetNotification(kNotificationIdA)); + EXPECT_TRUE(fake_notification_manager()->GetNotification(kNotificationIdB)); + + // 1 image decode callback will occur. + image_decoder_delegate()->RunAllCallbacks(); + EXPECT_EQ(0u, NumPendingRequests()); + EXPECT_EQ(2u, fake_notification_manager()->num_notifications()); + EXPECT_TRUE(fake_notification_manager()->GetNotification(kNotificationIdA)); + EXPECT_TRUE(fake_notification_manager()->GetNotification(kNotificationIdB)); +} + +TEST_F(NotificationProcessorTest, AddClearAllWithRace) { + std::vector<proto::Notification> first_set_of_notifications; + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdA, kInlineReplyIdA, kIconDataA, kSharedImageA)); + first_set_of_notifications.emplace_back(CreateNewInlineReplyableNotification( + kNotificationIdB, kInlineReplyIdB, kIconDataA)); + + notification_processor()->AddNotifications(first_set_of_notifications); + + // Clearing Notifications will invalidate all callbacks in process and + // immediately clear all pointers. + notification_processor()->ClearNotificationsAndPendingUpdates(); + EXPECT_EQ(0u, fake_notification_manager()->num_notifications()); + image_decoder_delegate()->RunAllCallbacks(); + EXPECT_EQ(0u, NumPendingRequests()); + EXPECT_EQ(0u, fake_notification_manager()->num_notifications()); + EXPECT_FALSE(fake_notification_manager()->GetNotification(kNotificationIdA)); + EXPECT_FALSE(fake_notification_manager()->GetNotification(kNotificationIdB)); +} + +} // namespace phonehub +} // namespace chromeos
diff --git a/chromeos/components/phonehub/phone_hub_manager_impl.cc b/chromeos/components/phonehub/phone_hub_manager_impl.cc index 53c65353..2c58b81 100644 --- a/chromeos/components/phonehub/phone_hub_manager_impl.cc +++ b/chromeos/components/phonehub/phone_hub_manager_impl.cc
@@ -20,6 +20,7 @@ #include "chromeos/components/phonehub/mutable_phone_model.h" #include "chromeos/components/phonehub/notification_access_manager_impl.h" #include "chromeos/components/phonehub/notification_manager_impl.h" +#include "chromeos/components/phonehub/notification_processor.h" #include "chromeos/components/phonehub/onboarding_ui_tracker_impl.h" #include "chromeos/components/phonehub/phone_model.h" #include "chromeos/components/phonehub/phone_status_processor.h" @@ -83,13 +84,15 @@ feature_status_provider_.get(), multidevice_setup_client, show_multidevice_setup_dialog_callback)), + notification_processor_( + std::make_unique<NotificationProcessor>(notification_manager_.get())), phone_status_processor_(std::make_unique<PhoneStatusProcessor>( do_not_disturb_controller_.get(), feature_status_provider_.get(), message_receiver_.get(), find_my_device_controller_.get(), notification_access_manager_.get(), - notification_manager_.get(), + notification_processor_.get(), multidevice_setup_client, phone_model_.get())), tether_controller_( @@ -167,6 +170,7 @@ browser_tabs_model_provider_.reset(); tether_controller_.reset(); phone_status_processor_.reset(); + notification_processor_.reset(); onboarding_ui_tracker_.reset(); notification_manager_.reset(); notification_access_manager_.reset();
diff --git a/chromeos/components/phonehub/phone_hub_manager_impl.h b/chromeos/components/phonehub/phone_hub_manager_impl.h index 757da736..d7300cf 100644 --- a/chromeos/components/phonehub/phone_hub_manager_impl.h +++ b/chromeos/components/phonehub/phone_hub_manager_impl.h
@@ -38,6 +38,7 @@ class MessageReceiver; class MultideviceSetupStateUpdater; class MutablePhoneModel; +class NotificationProcessor; class PhoneStatusProcessor; class UserActionRecorder; @@ -84,6 +85,7 @@ std::unique_ptr<NotificationAccessManager> notification_access_manager_; std::unique_ptr<NotificationManager> notification_manager_; std::unique_ptr<OnboardingUiTracker> onboarding_ui_tracker_; + std::unique_ptr<NotificationProcessor> notification_processor_; std::unique_ptr<PhoneStatusProcessor> phone_status_processor_; std::unique_ptr<TetherController> tether_controller_; std::unique_ptr<BrowserTabsModelProvider> browser_tabs_model_provider_;
diff --git a/chromeos/components/phonehub/phone_status_processor.cc b/chromeos/components/phonehub/phone_status_processor.cc index 7bcf0a78..7f2be09 100644 --- a/chromeos/components/phonehub/phone_status_processor.cc +++ b/chromeos/components/phonehub/phone_status_processor.cc
@@ -6,16 +6,13 @@ #include "base/containers/flat_set.h" #include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" #include "chromeos/components/phonehub/do_not_disturb_controller.h" #include "chromeos/components/phonehub/find_my_device_controller.h" #include "chromeos/components/phonehub/message_receiver.h" #include "chromeos/components/phonehub/mutable_phone_model.h" -#include "chromeos/components/phonehub/notification.h" #include "chromeos/components/phonehub/notification_access_manager.h" -#include "chromeos/components/phonehub/notification_manager.h" +#include "chromeos/components/phonehub/notification_processor.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" -#include "ui/gfx/image/image.h" #include <algorithm> #include <string> @@ -25,31 +22,6 @@ namespace { using multidevice_setup::MultiDeviceSetupClient; -gfx::Image CreateImageFromSerializedIcon(const std::string& bytes) { - return gfx::Image::CreateFrom1xPNGBytes( - reinterpret_cast<const unsigned char*>(bytes.c_str()), bytes.size()); -} - -Notification::Importance GetNotificationImportanceFromProto( - proto::NotificationImportance importance) { - switch (importance) { - case proto::NotificationImportance::UNSPECIFIED: - return Notification::Importance::kUnspecified; - case proto::NotificationImportance::NONE: - return Notification::Importance::kNone; - case proto::NotificationImportance::MIN: - return Notification::Importance::kMin; - case proto::NotificationImportance::LOW: - return Notification::Importance::kLow; - case proto::NotificationImportance::DEFAULT: - return Notification::Importance::kDefault; - case proto::NotificationImportance::HIGH: - return Notification::Importance::kHigh; - default: - return Notification::Importance::kUnspecified; - } -} - PhoneStatusModel::MobileStatus GetMobileStatusFromProto( proto::MobileConnectionState mobile_status) { switch (mobile_status) { @@ -138,44 +110,6 @@ : FindMyDeviceController::Status::kRingingOff; } -base::Optional<Notification> ProcessNotificationProto( - const proto::Notification& proto) { - // Only process notifications that are messaging apps with inline-replies. - auto actions_it = std::find_if( - proto.actions().begin(), proto.actions().end(), [](const auto& action) { - return action.type() == proto::Action_InputType::Action_InputType_TEXT; - }); - - if (actions_it == proto.actions().end()) - return base::nullopt; - - base::Optional<base::string16> title = base::nullopt; - if (!proto.title().empty()) - title = base::UTF8ToUTF16(proto.title()); - - base::Optional<base::string16> text_content = base::nullopt; - if (!proto.text_content().empty()) - text_content = base::UTF8ToUTF16(proto.text_content()); - - base::Optional<gfx::Image> shared_image = base::nullopt; - if (!proto.shared_image().empty()) - shared_image = CreateImageFromSerializedIcon(proto.shared_image()); - - base::Optional<gfx::Image> contact_image = base::nullopt; - if (!proto.contact_image().empty()) - contact_image = CreateImageFromSerializedIcon(proto.contact_image()); - - return Notification( - proto.id(), - Notification::AppMetadata( - base::UTF8ToUTF16(proto.origin_app().visible_name()), - proto.origin_app().package_name(), - CreateImageFromSerializedIcon(proto.origin_app().icon())), - base::Time::FromJsTime(proto.epoch_time_millis()), - GetNotificationImportanceFromProto(proto.importance()), actions_it->id(), - title, text_content, shared_image, contact_image); -} - PhoneStatusModel CreatePhoneStatusModel(const proto::PhoneProperties& proto) { return PhoneStatusModel( GetMobileStatusFromProto(proto.connection_state()), @@ -195,7 +129,7 @@ MessageReceiver* message_receiver, FindMyDeviceController* find_my_device_controller, NotificationAccessManager* notification_access_manager, - NotificationManager* notification_manager, + NotificationProcessor* notification_processor_, MultiDeviceSetupClient* multidevice_setup_client, MutablePhoneModel* phone_model) : do_not_disturb_controller_(do_not_disturb_controller), @@ -203,7 +137,7 @@ message_receiver_(message_receiver), find_my_device_controller_(find_my_device_controller), notification_access_manager_(notification_access_manager), - notification_manager_(notification_manager), + notification_processor_(notification_processor_), multidevice_setup_client_(multidevice_setup_client), phone_model_(phone_model) { DCHECK(do_not_disturb_controller_); @@ -211,7 +145,7 @@ DCHECK(message_receiver_); DCHECK(find_my_device_controller_); DCHECK(notification_access_manager_); - DCHECK(notification_manager_); + DCHECK(notification_processor_); DCHECK(multidevice_setup_client_); DCHECK(phone_model_); @@ -239,14 +173,12 @@ return; } - base::flat_set<Notification> notifications; + std::vector<proto::Notification> inline_replyable_protos; - for (const auto& proto : notification_protos) { - base::Optional<Notification> notif = ProcessNotificationProto(proto); - if (notif.has_value()) - notifications.emplace(*notif); - } - notification_manager_->SetNotificationsInternal(notifications); + for (const auto& proto : notification_protos) + inline_replyable_protos.emplace_back(proto); + + notification_processor_->AddNotifications(inline_replyable_protos); } void PhoneStatusProcessor::SetReceivedPhoneStatusModelStates( @@ -280,7 +212,7 @@ if (feature_status_provider_->GetStatus() != FeatureStatus::kEnabledAndConnected) { phone_model_->SetPhoneStatusModel(base::nullopt); - notification_manager_->ClearNotificationsInternal(); + notification_processor_->ClearNotificationsAndPendingUpdates(); } } @@ -300,8 +232,8 @@ for (auto& id : phone_status_update.removed_notification_ids()) { removed_notification_ids.emplace(id); } - notification_manager_->RemoveNotificationsInternal( - removed_notification_ids); + + notification_processor_->RemoveNotifications(removed_notification_ids); } }
diff --git a/chromeos/components/phonehub/phone_status_processor.h b/chromeos/components/phonehub/phone_status_processor.h index 4ddc1525..8626ad52 100644 --- a/chromeos/components/phonehub/phone_status_processor.h +++ b/chromeos/components/phonehub/phone_status_processor.h
@@ -5,13 +5,13 @@ #ifndef CHROMEOS_COMPONENTS_PHONEHUB_PHONE_STATUS_PROCESSOR_H_ #define CHROMEOS_COMPONENTS_PHONEHUB_PHONE_STATUS_PROCESSOR_H_ +#include <google/protobuf/repeated_field.h> + #include "chromeos/components/phonehub/feature_status_provider.h" #include "chromeos/components/phonehub/message_receiver.h" #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" #include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h" -#include <google/protobuf/repeated_field.h> - using google::protobuf::RepeatedPtrField; namespace chromeos { @@ -21,7 +21,7 @@ class FeatureStatusProvider; class FindMyDeviceController; class NotificationAccessManager; -class NotificationManager; +class NotificationProcessor; class MutablePhoneModel; // Responsible for receiving incoming protos and calling on clients to update @@ -37,7 +37,7 @@ MessageReceiver* message_receiver, FindMyDeviceController* find_my_device_controller, NotificationAccessManager* notification_access_manager, - NotificationManager* notification_manager, + NotificationProcessor* notification_processor_, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, MutablePhoneModel* phone_model); ~PhoneStatusProcessor() override; @@ -46,6 +46,8 @@ PhoneStatusProcessor& operator=(const PhoneStatusProcessor&) = delete; private: + friend class PhoneStatusProcessorTest; + // FeatureStatusProvider::Observer: void OnFeatureStatusChanged() override; @@ -76,7 +78,7 @@ MessageReceiver* message_receiver_; FindMyDeviceController* find_my_device_controller_; NotificationAccessManager* notification_access_manager_; - NotificationManager* notification_manager_; + NotificationProcessor* notification_processor_; multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_; MutablePhoneModel* phone_model_; };
diff --git a/chromeos/components/phonehub/phone_status_processor_unittest.cc b/chromeos/components/phonehub/phone_status_processor_unittest.cc index 7684d5e..dc4bf07 100644 --- a/chromeos/components/phonehub/phone_status_processor_unittest.cc +++ b/chromeos/components/phonehub/phone_status_processor_unittest.cc
@@ -10,6 +10,7 @@ #include <utility> #include "base/strings/utf_string_conversions.h" +#include "base/test/task_environment.h" #include "chromeos/components/multidevice/remote_device_test_util.h" #include "chromeos/components/phonehub/fake_do_not_disturb_controller.h" #include "chromeos/components/phonehub/fake_feature_status_provider.h" @@ -19,6 +20,8 @@ #include "chromeos/components/phonehub/fake_notification_manager.h" #include "chromeos/components/phonehub/mutable_phone_model.h" #include "chromeos/components/phonehub/notification_manager.h" +#include "chromeos/components/phonehub/notification_processor.h" +#include "chromeos/components/phonehub/phone_model_test_util.h" #include "chromeos/components/phonehub/phone_status_model.h" #include "chromeos/components/phonehub/proto/phonehub_api.pb.h" #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h" @@ -31,6 +34,30 @@ using multidevice_setup::mojom::FeatureState; using multidevice_setup::mojom::HostStatus; +// A fake processor that immediately adds or removes notifications. +class FakeNotificationProcessor : public NotificationProcessor { + public: + FakeNotificationProcessor(NotificationManager* notification_manager) + : NotificationProcessor(notification_manager) {} + + void AddNotifications( + const std::vector<proto::Notification>& notification_protos) override { + base::flat_set<Notification> notifications; + for (const auto& proto : notification_protos) { + notifications.emplace( + Notification(proto.id(), CreateFakeAppMetadata(), base::Time(), + Notification::Importance::kDefault, 0, base::nullopt, + base::nullopt, base::nullopt, base::nullopt)); + } + notification_manager_->SetNotificationsInternal(notifications); + } + + void RemoveNotifications( + const base::flat_set<int64_t>& notification_ids) override { + notification_manager_->RemoveNotificationsInternal(notification_ids); + } +}; + class PhoneStatusProcessorTest : public testing::Test { protected: PhoneStatusProcessorTest() @@ -51,6 +78,8 @@ fake_notification_access_manager_ = std::make_unique<FakeNotificationAccessManager>(); fake_notification_manager_ = std::make_unique<FakeNotificationManager>(); + fake_notification_processor_ = std::make_unique<FakeNotificationProcessor>( + fake_notification_manager_.get()); mutable_phone_model_ = std::make_unique<MutablePhoneModel>(); fake_multidevice_setup_client_ = std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>(); @@ -62,8 +91,8 @@ fake_feature_status_provider_.get(), fake_message_receiver_.get(), fake_find_my_device_controller_.get(), fake_notification_access_manager_.get(), - fake_notification_manager_.get(), fake_multidevice_setup_client_.get(), - mutable_phone_model_.get()); + fake_notification_processor_.get(), + fake_multidevice_setup_client_.get(), mutable_phone_model_.get()); } void InitializeNotificationProto(proto::Notification* notification, @@ -97,6 +126,7 @@ std::unique_ptr<FakeNotificationAccessManager> fake_notification_access_manager_; std::unique_ptr<FakeNotificationManager> fake_notification_manager_; + std::unique_ptr<FakeNotificationProcessor> fake_notification_processor_; std::unique_ptr<MutablePhoneModel> mutable_phone_model_; std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient> fake_multidevice_setup_client_;
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt index b4b5086..ad33dd7 100644 --- a/chromeos/profiles/atom.afdo.newest.txt +++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-atom-90-4384.0-1611574800-benchmark-90.0.4405.2-r1-redacted.afdo.xz +chromeos-chrome-amd64-atom-90-4384.0-1611574800-benchmark-90.0.4406.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index 6590e6c5..d46f8b4e 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-90-4389.16-1612180125-benchmark-90.0.4405.2-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-90-4389.16-1612180125-benchmark-90.0.4406.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/nearby/public/mojom/nearby_connections.mojom b/chromeos/services/nearby/public/mojom/nearby_connections.mojom index 9e6f4ed..7c44a914 100644 --- a/chromeos/services/nearby/public/mojom/nearby_connections.mojom +++ b/chromeos/services/nearby/public/mojom/nearby_connections.mojom
@@ -339,6 +339,14 @@ // Sends a request to initiate connection bandwidth upgrade. // + // Important note: Bandwidth upgrades may expose stable identifiers, + // which are only safe to expose after the caller has verified + // the sender's identity. If the caller is already performing + // high-visibility advertising (and thus already leaking the device + // name), then calling this method introduces no further privacy + // leaks -- in fact, the caller should consider instead requesting + // to auto-upgrade bandwidth when invoking StartAdvertising(). + // // service_id - Service ID used to discover the endpoint. // endpoint_id - The identifier for the remote endpoint which will be // switching to a higher connection data rate and possibly
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index f46a874..fe9522d 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -488,4 +488,9 @@ // A boolean pref controlling showing the low disk space notification. const char kDeviceShowLowDiskSpaceNotification[] = "cros.device.show_low_disk_space_notification"; + +// A list of dictionaries indicating USB devices that may be used by chrome.usb. +const char kUsbDetachableAllowlist[] = "cros.device.usb_detachable_allowlist"; +const char kUsbDetachableAllowlistKeyVid[] = "vid"; +const char kUsbDetachableAllowlistKeyPid[] = "pid"; } // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index b932ec3..b5a4b73 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -278,6 +278,12 @@ COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceShowLowDiskSpaceNotification[]; + +COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kUsbDetachableAllowlist[]; +COMPONENT_EXPORT(CHROMEOS_SETTINGS) +extern const char kUsbDetachableAllowlistKeyVid[]; +COMPONENT_EXPORT(CHROMEOS_SETTINGS) +extern const char kUsbDetachableAllowlistKeyPid[]; } // namespace chromeos // TODO(https://crbug.com/1164001): remove when migrated to ash/components/.
diff --git a/components/account_manager_core/account_addition_result.h b/components/account_manager_core/account_addition_result.h index 43761da..f4fc008 100644 --- a/components/account_manager_core/account_addition_result.h +++ b/components/account_manager_core/account_addition_result.h
@@ -13,6 +13,8 @@ // The result of account addition request. struct COMPONENT_EXPORT(ACCOUNT_MANAGER_CORE) AccountAdditionResult { + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. enum class Status { // The account was added successfully. kSuccess = 0, @@ -24,6 +26,7 @@ kNetworkError = 3, // Unexpected response (couldn't parse mojo struct). kUnexpectedResponse = 4, + kMaxValue = kUnexpectedResponse, }; Status status;
diff --git a/components/account_manager_core/account_manager_facade_impl.cc b/components/account_manager_core/account_manager_facade_impl.cc index 7487f37..935aedb3d 100644 --- a/components/account_manager_core/account_manager_facade_impl.cc +++ b/components/account_manager_core/account_manager_facade_impl.cc
@@ -17,6 +17,10 @@ namespace { +// UMA histogram name. +const char kAccountAdditionResultStatus[] = + "AccountManager.AccountAdditionResultStatus"; + // Interface versions in //chromeos/crosapi/mojom/account_manager.mojom: // MinVersion of crosapi::mojom::AccountManager::GetAccounts constexpr uint32_t kMinVersionWithGetAccounts = 2; @@ -102,8 +106,10 @@ LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: " << kMinVersionWithShowAddAccountDialog << " for ShowAddAccountDialog."; - std::move(callback).Run(account_manager::AccountAdditionResult( - account_manager::AccountAdditionResult::Status::kUnexpectedResponse)); + FinishAddAccount(std::move(callback), + account_manager::AccountAdditionResult( + account_manager::AccountAdditionResult::Status:: + kUnexpectedResponse)); return; } @@ -121,6 +127,7 @@ LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: " << kMinVersionWithShowAddAccountDialog << " for ShowReauthAccountDialog."; + return; } base::UmaHistogramEnumeration(kAccountAdditionSource, source); @@ -128,6 +135,12 @@ account_manager_remote_->ShowReauthAccountDialog(email, base::DoNothing()); } +// static +std::string AccountManagerFacadeImpl:: + GetAccountAdditionResultStatusHistogramNameForTesting() { + return kAccountAdditionResultStatus; +} + void AccountManagerFacadeImpl::OnReceiverReceived( mojo::PendingReceiver<AccountManagerObserver> receiver) { receiver_ = @@ -153,11 +166,21 @@ base::Optional<account_manager::AccountAdditionResult> result = account_manager::FromMojoAccountAdditionResult(mojo_result); if (!result.has_value()) { - std::move(callback).Run(account_manager::AccountAdditionResult( - account_manager::AccountAdditionResult::Status::kUnexpectedResponse)); + FinishAddAccount(std::move(callback), + account_manager::AccountAdditionResult( + account_manager::AccountAdditionResult::Status:: + kUnexpectedResponse)); return; } - std::move(callback).Run(result.value()); + FinishAddAccount(std::move(callback), result.value()); +} + +void AccountManagerFacadeImpl::FinishAddAccount( + base::OnceCallback< + void(const account_manager::AccountAdditionResult& result)> callback, + const account_manager::AccountAdditionResult& result) { + base::UmaHistogramEnumeration(kAccountAdditionResultStatus, result.status); + std::move(callback).Run(result); } void AccountManagerFacadeImpl::OnTokenUpserted(
diff --git a/components/account_manager_core/account_manager_facade_impl.h b/components/account_manager_core/account_manager_facade_impl.h index c51edd0f..b10f009 100644 --- a/components/account_manager_core/account_manager_facade_impl.h +++ b/components/account_manager_core/account_manager_facade_impl.h
@@ -57,7 +57,12 @@ FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest, ShowAddAccountDialogCallsMojo); FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest, + ShowAddAccountDialogUMA); + FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest, ShowReauthAccountDialogCallsMojo); + FRIEND_TEST_ALL_PREFIXES(AccountManagerFacadeImplTest, + ShowReauthAccountDialogUMA); + static std::string GetAccountAdditionResultStatusHistogramNameForTesting(); void OnReceiverReceived( mojo::PendingReceiver<AccountManagerObserver> receiver); @@ -67,6 +72,10 @@ base::OnceCallback< void(const account_manager::AccountAdditionResult& result)> callback, crosapi::mojom::AccountAdditionResultPtr mojo_result); + void FinishAddAccount( + base::OnceCallback< + void(const account_manager::AccountAdditionResult& result)> callback, + const account_manager::AccountAdditionResult& result); void FlushMojoForTesting();
diff --git a/components/account_manager_core/account_manager_facade_impl_unittest.cc b/components/account_manager_core/account_manager_facade_impl_unittest.cc index 3f24813..12e3463 100644 --- a/components/account_manager_core/account_manager_facade_impl_unittest.cc +++ b/components/account_manager_core/account_manager_facade_impl_unittest.cc
@@ -8,6 +8,7 @@ #include "base/test/bind.h" #include "base/test/gmock_callback_support.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" #include "chromeos/crosapi/mojom/account_manager.mojom.h" @@ -58,9 +59,8 @@ void ShowAddAccountDialog(ShowAddAccountDialogCallback callback) override { show_add_account_dialog_calls_++; - std::move(callback).Run(account_manager::ToMojoAccountAdditionResult( - account_manager::AccountAdditionResult( - account_manager::AccountAdditionResult::Status::kCancelledByUser))); + std::move(callback).Run( + account_manager::ToMojoAccountAdditionResult(add_account_result_)); } void ShowReauthAccountDialog(const std::string& email, @@ -92,6 +92,11 @@ accounts_ = accounts; } + void SetAccountAdditionResult( + const account_manager::AccountAdditionResult& result) { + add_account_result_ = result; + } + int show_add_account_dialog_calls() { return show_add_account_dialog_calls_; } int show_reauth_account_dialog_calls() { @@ -103,6 +108,8 @@ int show_reauth_account_dialog_calls_ = 0; bool is_initialized_{false}; std::vector<account_manager::Account> accounts_; + account_manager::AccountAdditionResult add_account_result_{ + account_manager::AccountAdditionResult::Status::kUnexpectedResponse}; mojo::ReceiverSet<crosapi::mojom::AccountManager> receivers_; mojo::RemoteSet<crosapi::mojom::AccountManagerObserver> observers_; }; @@ -311,6 +318,31 @@ EXPECT_EQ(1, account_manager().show_add_account_dialog_calls()); } +TEST_F(AccountManagerFacadeImplTest, ShowAddAccountDialogUMA) { + base::HistogramTester tester; + std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade = + CreateFacade(); + auto result = account_manager::AccountAdditionResult( + account_manager::AccountAdditionResult::Status::kAlreadyInProgress); + account_manager().SetAccountAdditionResult(result); + auto source = account_manager::AccountManagerFacade::AccountAdditionSource:: + kSettingsAddAccountButton; + + account_manager_facade->ShowAddAccountDialog( + source, base::BindOnce( + [](const account_manager::AccountAdditionResult& result) {})); + account_manager_facade->FlushMojoForTesting(); + + // Check that UMA stats were sent. + tester.ExpectUniqueSample( + account_manager::AccountManagerFacade::kAccountAdditionSource, + /*sample=*/source, /*expected_count=*/1); + tester.ExpectUniqueSample( + AccountManagerFacadeImpl:: + GetAccountAdditionResultStatusHistogramNameForTesting(), + /*sample=*/result.status, /*expected_count=*/1); +} + TEST_F(AccountManagerFacadeImplTest, ShowReauthAccountDialogCallsMojo) { std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade = CreateFacade(); @@ -322,3 +354,19 @@ account_manager_facade->FlushMojoForTesting(); EXPECT_EQ(1, account_manager().show_reauth_account_dialog_calls()); } + +TEST_F(AccountManagerFacadeImplTest, ShowReauthAccountDialogUMA) { + base::HistogramTester tester; + std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade = + CreateFacade(); + auto source = account_manager::AccountManagerFacade::AccountAdditionSource:: + kContentArea; + + account_manager_facade->ShowReauthAccountDialog(source, kFakeEmail); + account_manager_facade->FlushMojoForTesting(); + + // Check that UMA stats were sent. + tester.ExpectUniqueSample( + account_manager::AccountManagerFacade::kAccountAdditionSource, + /*sample=*/source, /*expected_count=*/1); +}
diff --git a/components/arc/arc_features.cc b/components/arc/arc_features.cc index 355fa15d..39f328c 100644 --- a/components/arc/arc_features.cc +++ b/components/arc/arc_features.cc
@@ -35,10 +35,6 @@ const base::Feature kEnableRegularToChildTransitionFeature{ "ArcEnableRegularToChildTransition", base::FEATURE_ENABLED_BY_DEFAULT}; -// Controls whether secondary accounts are added to ARC++ for child user. -const base::Feature kEnableSecondaryAccountsForChild{ - "ArcEnableSecondaryAccountForChild", base::FEATURE_ENABLED_BY_DEFAULT}; - // Controls whether we should delegate audio focus requests from ARC to Chrome. const base::Feature kEnableUnifiedAudioFocusFeature{ "ArcEnableUnifiedAudioFocus", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/arc/arc_features.h b/components/arc/arc_features.h index b1319f8..6c0e595 100644 --- a/components/arc/arc_features.h +++ b/components/arc/arc_features.h
@@ -18,7 +18,6 @@ extern const base::Feature kEnableChildToRegularTransitionFeature; extern const base::Feature kEnableDocumentsProviderInFilesAppFeature; extern const base::Feature kEnableRegularToChildTransitionFeature; -extern const base::Feature kEnableSecondaryAccountsForChild; extern const base::Feature kEnableUnifiedAudioFocusFeature; extern const base::Feature kFilePickerExperimentFeature; extern const base::Feature kNativeBridge64BitSupportExperimentFeature;
diff --git a/components/arc/test/fake_file_system_instance.cc b/components/arc/test/fake_file_system_instance.cc index ca796799..26a00f6 100644 --- a/components/arc/test/fake_file_system_instance.cc +++ b/components/arc/test/fake_file_system_instance.cc
@@ -73,6 +73,17 @@ Seekable seekable) : url(url), content(content), mime_type(mime_type), seekable(seekable) {} +FakeFileSystemInstance::File::File(const std::string& url, + const std::string& content, + const std::string& mime_type, + Seekable seekable, + int64_t size_override) + : url(url), + content(content), + mime_type(mime_type), + seekable(seekable), + size_override(size_override) {} + FakeFileSystemInstance::File::File(const File& that) = default; FakeFileSystemInstance::File::~File() = default; @@ -318,7 +329,7 @@ } const File& file = iter->second; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), file.content.size())); + FROM_HERE, base::BindOnce(std::move(callback), file.size())); } void FakeFileSystemInstance::GetMimeType(const std::string& url,
diff --git a/components/arc/test/fake_file_system_instance.h b/components/arc/test/fake_file_system_instance.h index af69a86a..81c1fc8 100644 --- a/components/arc/test/fake_file_system_instance.h +++ b/components/arc/test/fake_file_system_instance.h
@@ -89,6 +89,9 @@ // Whether this file is seekable or not. Seekable seekable; + // Override of |content| length in bytes. + base::Optional<int64_t> size_override; + // The thumbnail of a file, which can be read by OpenThumbnail(). std::string thumbnail_content; @@ -96,8 +99,17 @@ const std::string& content, const std::string& mime_type, Seekable seekable); + File(const std::string& url, + const std::string& content, + const std::string& mime_type, + Seekable seekable, + int64_t size_override); File(const File& that); ~File(); + + size_t size() const { + return size_override ? *size_override : content.size(); + } }; // Specification of a fake document available to documents provider based
diff --git a/components/crash/content/browser/error_reporting/javascript_error_report.h b/components/crash/content/browser/error_reporting/javascript_error_report.h index 83da8bc..506fc562 100644 --- a/components/crash/content/browser/error_reporting/javascript_error_report.h +++ b/components/crash/content/browser/error_reporting/javascript_error_report.h
@@ -37,6 +37,16 @@ // (e.g. http://www.example.com). std::string url; + // The system that created the error report. Useful for checking that each of + // the various different systems that generate JavaScript error reports is + // working as expected. + enum class SourceSystem { + kUnknown, + kCrashReportApi, + kWebUIObserver, + }; + SourceSystem source_system = SourceSystem::kUnknown; + // Name of the product where the error occurred. If empty, use the product // variant of Chrome that is hosting the extension. (e.g. "Chrome" or // "Chrome_ChromeOS").
diff --git a/components/exo/keyboard.cc b/components/exo/keyboard.cc index 2bee03d..620ce8b 100644 --- a/components/exo/keyboard.cc +++ b/components/exo/keyboard.cc
@@ -6,10 +6,12 @@ #include "ash/keyboard/ui/keyboard_ui_controller.h" #include "ash/keyboard/ui/keyboard_util.h" +#include "ash/public/cpp/accelerators.h" #include "ash/public/cpp/app_types.h" #include "ash/public/cpp/keyboard/keyboard_controller.h" #include "ash/shell.h" #include "base/bind.h" +#include "base/containers/contains.h" #include "base/threading/thread_task_runner_handle.h" #include "components/exo/input_trace.h" #include "components/exo/keyboard_delegate.h" @@ -97,6 +99,52 @@ return false; } +// Returns true if the surface can consume ash accelerators. +bool CanConsumeAshAccelerators(Surface* surface) { + aura::Window* window = surface->window(); + for (; window; window = window->parent()) { + const auto app_type = + static_cast<ash::AppType>(window->GetProperty(aura::client::kAppType)); + // TODO(fukino): Always returning false for Lacros window is a short-term + // solution. In reality, Lacros can consume ash accelerator's key + // combination when it is a deprecated ash accelerator or the window is + // running PWA. We need to let the wayland client dynamically decrlare + // whether it want to consume ash accelerators' key combinations. + // crbug.com/1174025. + if (app_type == ash::AppType::LACROS) + return false; + } + return true; +} + +// Returns true if an accelerator is an ash accelerator which can be handled +// before sending it to client and it is actually processed by ash-chrome. +bool ProcessAshAcceleratorIfPossible(Surface* surface, ui::KeyEvent* event) { + // Process ash accelerators before sending it to client only when the client + // should not consume ash accelerators. (e.g. Lacros-chrome) + if (CanConsumeAshAccelerators(surface)) + return false; + + // Ctrl-N (new window), Shift-Ctrl-N (new incognite window), Ctrl-T (new tab), + // and Shit-Ctrl-T (restore tab) need to be sent to the active client even + // when the active window is lacros-chrome, since the ash-chrome does not + // handle these new-window requests properly at this moment. + // TODO(fukino): Remove this workaround once ash-chrome has an implementation + // to handle new-window requests when lacros-chrome browser window is active. + // crbug.com/1172189. + const ui::Accelerator kAppHandlingAccelerators[] = { + {ui::VKEY_N, ui::EF_CONTROL_DOWN}, + {ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}, + {ui::VKEY_T, ui::EF_CONTROL_DOWN}, + {ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}, + }; + ui::Accelerator accelerator(*event); + if (base::Contains(kAppHandlingAccelerators, accelerator)) + return false; + + return ash::AcceleratorController::Get()->Process(accelerator); +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -206,10 +254,11 @@ TRACE_EXO_INPUT_EVENT(event); - // Process reserved accelerators before sending it to client. - if (ProcessAcceleratorIfReserved(focus_, event)) { - // Discard a key press event if it's a reserved accelerator and it's - // enabled. + // Process reserved accelerators or ash accelerators which need to be handled + // before sending it to client. + if (ProcessAcceleratorIfReserved(focus_, event) || + ProcessAshAcceleratorIfPossible(focus_, event)) { + // Discard a key press event if the corresponding accelerator is handled. event->SetHandled(); }
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 6f6f2fe5..54e8a089 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -224,8 +224,6 @@ "sync_credentials_filter.h", "ui/bulk_leak_check_service_adapter.cc", "ui/bulk_leak_check_service_adapter.h", - "ui/compromised_credentials_reader.cc", - "ui/compromised_credentials_reader.h", "ui/credential_provider_interface.h", "ui/credential_utils.h", "ui/export_flow.h", @@ -233,6 +231,8 @@ "ui/import_flow.h", "ui/insecure_credentials_manager.cc", "ui/insecure_credentials_manager.h", + "ui/insecure_credentials_reader.cc", + "ui/insecure_credentials_reader.h", "ui/password_check_referrer.cc", "ui/password_check_referrer.h", "ui/plaintext_reason.h", @@ -666,8 +666,8 @@ "sync/password_sync_bridge_unittest.cc", "sync_credentials_filter_unittest.cc", "ui/bulk_leak_check_service_adapter_unittest.cc", - "ui/compromised_credentials_reader_unittest.cc", "ui/insecure_credentials_manager_unittest.cc", + "ui/insecure_credentials_reader_unittest.cc", "ui/post_save_compromised_helper_unittest.cc", "ui/saved_passwords_presenter_unittest.cc", "ui/weak_check_utility_unittest.cc",
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 28d2096..6276fea 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -108,9 +108,9 @@ OnLoginsChanged(changes); } -void PasswordStore::DatabaseCompromisedCredentialsObserver:: - OnCompromisedCredentialsChangedIn(PasswordStore* store) { - OnCompromisedCredentialsChanged(); +void PasswordStore::DatabaseInsecureCredentialsObserver:: + OnInsecureCredentialsChangedIn(PasswordStore* store) { + OnInsecureCredentialsChanged(); } PasswordStore::CheckReuseRequest::CheckReuseRequest( @@ -493,14 +493,14 @@ observers_->RemoveObserver(observer); } -void PasswordStore::AddDatabaseCompromisedCredentialsObserver( - DatabaseCompromisedCredentialsObserver* observer) { - compromised_credentials_observers_->AddObserver(observer); +void PasswordStore::AddDatabaseInsecureCredentialsObserver( + DatabaseInsecureCredentialsObserver* observer) { + insecure_credentials_observers_->AddObserver(observer); } -void PasswordStore::RemoveDatabaseCompromisedCredentialsObserver( - DatabaseCompromisedCredentialsObserver* observer) { - compromised_credentials_observers_->RemoveObserver(observer); +void PasswordStore::RemoveDatabaseInsecureCredentialsObserver( + DatabaseInsecureCredentialsObserver* observer) { + insecure_credentials_observers_->RemoveObserver(observer); } bool PasswordStore::ScheduleTask(base::OnceClosure task) { @@ -812,10 +812,9 @@ DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); PasswordStoreChangeList changes = std::move(callback).Run(); if (!changes.empty()) { - compromised_credentials_observers_->Notify( + insecure_credentials_observers_->Notify( FROM_HERE, - &DatabaseCompromisedCredentialsObserver:: - OnCompromisedCredentialsChangedIn, + &DatabaseInsecureCredentialsObserver::OnInsecureCredentialsChangedIn, base::RetainedRef(this)); if (sync_bridge_) sync_bridge_->ActOnPasswordStoreChanges(changes);
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index 5b61ed1..9abc585d 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -95,25 +95,25 @@ virtual ~Observer() = default; }; - class DatabaseCompromisedCredentialsObserver { + class DatabaseInsecureCredentialsObserver { // An interface used to notify clients (observers) of this object that the - // list of compromised credentials in the password store has changed. + // list of insecure credentials in the password store has changed. // Register the observer via - // PasswordStore::AddDatabaseCompromisedCredentialsObserver. + // PasswordStore::AddDatabaseInsecureCredentialsObserver. public: - // Notifies the observer that the list of compromised credentials changed. + // Notifies the observer that the list of insecure credentials changed. // Will be called from the UI thread. - virtual void OnCompromisedCredentialsChanged() = 0; + virtual void OnInsecureCredentialsChanged() = 0; - // Like OnCompromisedCredentialsChanged(), but also receives the originating + // Like OnInsecureCredentialsChanged(), but also receives the originating // PasswordStore as a parameter. This is useful for observers that observe // changes in both the profile-scoped and the account-scoped store. The - // default implementation simply calls OnCompromisedCredentialsChanged(), so + // default implementation simply calls OnInsecureCredentialsChanged(), so // observers that don't care about the store can just ignore this. - virtual void OnCompromisedCredentialsChangedIn(PasswordStore* store); + virtual void OnInsecureCredentialsChangedIn(PasswordStore* store); protected: - virtual ~DatabaseCompromisedCredentialsObserver() = default; + virtual ~DatabaseInsecureCredentialsObserver() = default; }; // Used to notify that unsynced credentials are about to be deleted. @@ -327,12 +327,12 @@ // Adds an observer to be notified when the list of compromised passwords in // the password store changes. - void AddDatabaseCompromisedCredentialsObserver( - DatabaseCompromisedCredentialsObserver* observer); + void AddDatabaseInsecureCredentialsObserver( + DatabaseInsecureCredentialsObserver* observer); // Removes |observer| from the list of compromised credentials observer. - void RemoveDatabaseCompromisedCredentialsObserver( - DatabaseCompromisedCredentialsObserver* observer); + void RemoveDatabaseInsecureCredentialsObserver( + DatabaseInsecureCredentialsObserver* observer); // Schedules the given |task| to be run on the PasswordStore's TaskRunner. bool ScheduleTask(base::OnceClosure task); @@ -852,10 +852,9 @@ // The observers. scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_; scoped_refptr< - base::ObserverListThreadSafe<DatabaseCompromisedCredentialsObserver>> - compromised_credentials_observers_ = - base::MakeRefCounted<base::ObserverListThreadSafe< - DatabaseCompromisedCredentialsObserver>>(); + base::ObserverListThreadSafe<DatabaseInsecureCredentialsObserver>> + insecure_credentials_observers_ = base::MakeRefCounted< + base::ObserverListThreadSafe<DatabaseInsecureCredentialsObserver>>(); std::unique_ptr<PasswordSyncBridge> sync_bridge_;
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index c86e284f..25d92bb 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -116,8 +116,8 @@ }; struct MockDatabaseCompromisedCredentialsObserver - : PasswordStore::DatabaseCompromisedCredentialsObserver { - MOCK_METHOD0(OnCompromisedCredentialsChanged, void()); + : PasswordStore::DatabaseInsecureCredentialsObserver { + MOCK_METHOD0(OnInsecureCredentialsChanged, void()); }; class MockPasswordStoreSigninNotifier : public PasswordStoreSigninNotifier { @@ -579,15 +579,15 @@ scoped_refptr<PasswordStoreImpl> store = CreatePasswordStore(); store->Init(nullptr); store->AddLogin(*FillPasswordFormWithData(kTestCredentials)); - store->AddDatabaseCompromisedCredentialsObserver(&observer); + store->AddDatabaseInsecureCredentialsObserver(&observer); // Expect a notification after adding a credential. - EXPECT_CALL(observer, OnCompromisedCredentialsChanged); + EXPECT_CALL(observer, OnInsecureCredentialsChanged); store->AddCompromisedCredentials(compromised_credentials); WaitForPasswordStore(); // Adding the same credential should not result in another notification. - EXPECT_CALL(observer, OnCompromisedCredentialsChanged).Times(0); + EXPECT_CALL(observer, OnInsecureCredentialsChanged).Times(0); store->AddCompromisedCredentials(compromised_credentials); WaitForPasswordStore(); @@ -620,17 +620,17 @@ store->AddCompromisedCredentials(compromised_credentials); WaitForPasswordStore(); - store->AddDatabaseCompromisedCredentialsObserver(&observer); + store->AddDatabaseInsecureCredentialsObserver(&observer); // Expect a notification after removing a credential. - EXPECT_CALL(observer, OnCompromisedCredentialsChanged); + EXPECT_CALL(observer, OnInsecureCredentialsChanged); store->RemoveCompromisedCredentials(compromised_credentials.signon_realm, compromised_credentials.username, RemoveInsecureCredentialsReason::kRemove); WaitForPasswordStore(); // Removing the same credential should not result in another notification. - EXPECT_CALL(observer, OnCompromisedCredentialsChanged).Times(0); + EXPECT_CALL(observer, OnInsecureCredentialsChanged).Times(0); store->RemoveCompromisedCredentials(compromised_credentials.signon_realm, compromised_credentials.username, RemoveInsecureCredentialsReason::kRemove);
diff --git a/components/password_manager/core/browser/ui/compromised_credentials_reader.h b/components/password_manager/core/browser/ui/compromised_credentials_reader.h deleted file mode 100644 index e219fdc..0000000 --- a/components/password_manager/core/browser/ui/compromised_credentials_reader.h +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_UI_COMPROMISED_CREDENTIALS_READER_H_ -#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_UI_COMPROMISED_CREDENTIALS_READER_H_ - -#include "base/observer_list.h" -#include "base/scoped_multi_source_observation.h" -#include "components/password_manager/core/browser/compromised_credentials_consumer.h" -#include "components/password_manager/core/browser/password_store.h" - -namespace password_manager { -// This class is responsible for reading and listening to change in the -// compormised credentials in the underlying password stores. -class CompromisedCredentialsReader - : public PasswordStore::DatabaseCompromisedCredentialsObserver, - public CompromisedCredentialsConsumer { - public: - using GetCompromisedCredentialsCallback = - base::OnceCallback<void(std::vector<CompromisedCredentials>)>; - // Observer interface. Clients can implement this to get notified about - // changes to the list of compromised credentials. Clients can register and - // de-register themselves, and are expected to do so before the provider gets - // out of scope. - class Observer : public base::CheckedObserver { - public: - virtual void OnCompromisedCredentialsChanged( - const std::vector<CompromisedCredentials>& compromised_credentials) = 0; - }; - - // |profile_store| cannot be null, and must outlive this class. - explicit CompromisedCredentialsReader(PasswordStore* profile_store, - PasswordStore* account_store = nullptr); - CompromisedCredentialsReader(const CompromisedCredentialsReader&) = delete; - CompromisedCredentialsReader& operator=(const CompromisedCredentialsReader&) = - delete; - ~CompromisedCredentialsReader() override; - - void Init(); - - // `callback` must outlive this object. - void GetAllCompromisedCredentials(GetCompromisedCredentialsCallback callback); - - // Allows clients and register and de-register themselves. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - private: - // PasswordStore::DatabaseCompromisedCredentialsObserver: - void OnCompromisedCredentialsChanged() override; - void OnCompromisedCredentialsChangedIn(PasswordStore* store) override; - - // CompromisedCredentialsConsumer: - void OnGetCompromisedCredentials( - std::vector<CompromisedCredentials> compromised_credentials) override; - void OnGetCompromisedCredentialsFrom( - PasswordStore* store, - std::vector<CompromisedCredentials> compromised_credentials) override; - - // The password stores containing the compromised credentials. - // |profile_store_| must not be null and must outlive this class. - PasswordStore* profile_store_; - PasswordStore* account_store_; - - // Cache of the most recently obtained compromised credentials. - std::vector<CompromisedCredentials> compromised_credentials_; - - // A scoped observer for |profile_store_|, and |account_store_| that listens - // to changes related to CompromisedCredentials only. - base::ScopedMultiSourceObservation< - PasswordStore, - PasswordStore::DatabaseCompromisedCredentialsObserver, - &PasswordStore::AddDatabaseCompromisedCredentialsObserver, - &PasswordStore::RemoveDatabaseCompromisedCredentialsObserver> - observed_password_stores_{this}; - - base::ObserverList<Observer, /*check_empty=*/true> observers_; - std::vector<GetCompromisedCredentialsCallback> - get_all_compromised_credentials_callbacks_; - - // Whether we are still waiting for a first response from the profile and - // account stores. - bool profile_store_responded_ = false; - bool account_store_responded_ = false; -}; - -} // namespace password_manager - -#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_UI_COMPROMISED_CREDENTIALS_READER_H_
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager.cc b/components/password_manager/core/browser/ui/insecure_credentials_manager.cc index 5c57db3..7646a4f 100644 --- a/components/password_manager/core/browser/ui/insecure_credentials_manager.cc +++ b/components/password_manager/core/browser/ui/insecure_credentials_manager.cc
@@ -27,7 +27,7 @@ namespace password_manager { -// Extra information about InsecureCredentials which is required by UI. +// Extra information about InsecureCredential which is required by UI. struct CredentialMetadata { std::vector<PasswordForm> forms; InsecureCredentialTypeFlags type = InsecureCredentialTypeFlags::kSecure; @@ -39,7 +39,7 @@ using CredentialPasswordsMap = std::map<CredentialView, CredentialMetadata, PasswordCredentialLess>; -// Transparent comparator that can compare CompromisedCredentials and +// Transparent comparator that can compare InsecureCredential and // PasswordForm. struct CredentialWithoutPasswordLess { template <typename T, typename U> @@ -55,8 +55,7 @@ return std::tie(form.signon_realm, form.username_value, form.in_store); } - static auto CredentialOriginAndUsernameAndStore( - const CompromisedCredentials& c) { + static auto CredentialOriginAndUsernameAndStore(const InsecureCredential& c) { return std::tie(c.signon_realm, c.username, c.in_store); } }; @@ -75,12 +74,12 @@ NOTREACHED(); } -// This function takes three lists of compromised credentials, weak passwords +// This function takes three lists of insecure credentials, weak passwords // and saved passwords and joins them, producing a map that contains // CredentialWithPassword as keys and vector<PasswordForm> as values with // InsecureCredentialTypeFlags as values. CredentialPasswordsMap JoinInsecureCredentialsWithSavedPasswords( - const std::vector<CompromisedCredentials>& compromised_credentials, + const std::vector<InsecureCredential>& compromised_credentials, const base::flat_set<base::string16>& weak_passwords, SavedPasswordsPresenter::SavedPasswordsView saved_passwords) { CredentialPasswordsMap credentials_to_forms; @@ -210,7 +209,7 @@ CredentialWithPassword::CredentialWithPassword(CredentialWithPassword&& other) = default; CredentialWithPassword::CredentialWithPassword( - const CompromisedCredentials& credential) + const InsecureCredential& credential) : CredentialView(credential.signon_realm, GURL(credential.signon_realm), credential.username, @@ -230,17 +229,15 @@ : presenter_(presenter), profile_store_(std::move(profile_store)), account_store_(std::move(account_store)), - compromised_credentials_reader_(profile_store_.get(), - account_store_.get()) { - observed_compromised_credentials_reader_.Observe( - &compromised_credentials_reader_); + insecure_credentials_reader_(profile_store_.get(), account_store_.get()) { + observed_insecure_credentials_reader_.Observe(&insecure_credentials_reader_); observed_saved_password_presenter_.Observe(presenter_); } InsecureCredentialsManager::~InsecureCredentialsManager() = default; void InsecureCredentialsManager::Init() { - compromised_credentials_reader_.Init(); + insecure_credentials_reader_.Init(); } void InsecureCredentialsManager::StartWeakCheck( @@ -265,7 +262,7 @@ CanonicalizeUsername(saved_password.username_value) == canonicalized_username) { GetStoreFor(saved_password) - .AddCompromisedCredentials(CompromisedCredentials( + .AddCompromisedCredentials(InsecureCredential( saved_password.signon_realm, saved_password.username_value, base::Time::Now(), InsecureType::kLeaked, IsMuted(false))); } @@ -345,8 +342,7 @@ void InsecureCredentialsManager::UpdateInsecureCredentials() { credentials_to_forms_ = JoinInsecureCredentialsWithSavedPasswords( - compromised_credentials_, weak_passwords_, - presenter_->GetSavedPasswords()); + insecure_credentials_, weak_passwords_, presenter_->GetSavedPasswords()); } void InsecureCredentialsManager::OnWeakCheckDone( @@ -361,9 +357,9 @@ // Re-computes the list of compromised credentials with passwords after // obtaining a new list of compromised credentials. -void InsecureCredentialsManager::OnCompromisedCredentialsChanged( - const std::vector<CompromisedCredentials>& compromised_credentials) { - compromised_credentials_ = compromised_credentials; +void InsecureCredentialsManager::OnInsecureCredentialsChanged( + const std::vector<InsecureCredential>& insecure_credentials) { + insecure_credentials_ = insecure_credentials; UpdateInsecureCredentials(); NotifyCompromisedCredentialsChanged(); } @@ -390,7 +386,7 @@ void InsecureCredentialsManager::OnSavedPasswordsChanged( SavedPasswordsPresenter::SavedPasswordsView saved_passwords) { credentials_to_forms_ = JoinInsecureCredentialsWithSavedPasswords( - compromised_credentials_, weak_passwords_, saved_passwords); + insecure_credentials_, weak_passwords_, saved_passwords); NotifyCompromisedCredentialsChanged(); NotifyWeakCredentialsChanged(); }
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager.h b/components/password_manager/core/browser/ui/insecure_credentials_manager.h index c390e49..ffaf1ab 100644 --- a/components/password_manager/core/browser/ui/insecure_credentials_manager.h +++ b/components/password_manager/core/browser/ui/insecure_credentials_manager.h
@@ -22,8 +22,8 @@ #include "components/password_manager/core/browser/insecure_credentials_table.h" #include "components/password_manager/core/browser/leak_detection/bulk_leak_check.h" #include "components/password_manager/core/browser/password_store.h" -#include "components/password_manager/core/browser/ui/compromised_credentials_reader.h" #include "components/password_manager/core/browser/ui/credential_utils.h" +#include "components/password_manager/core/browser/ui/insecure_credentials_reader.h" #include "components/password_manager/core/browser/ui/saved_passwords_presenter.h" #include "url/gurl.h" @@ -85,7 +85,7 @@ InsecureCredentialTypeFlags::kSecure; } -// Simple struct that augments key values of InsecureCredentials and a password. +// Simple struct that augments key values of InsecureCredential and a password. struct CredentialView { CredentialView(std::string signon_realm, GURL url, @@ -106,13 +106,13 @@ }; // All information needed by UI to represent InsecureCredential. It's a result -// of deduplicating InsecureCredentials to have single entity for phished, +// of deduplicating InsecureCredential to have single entity for phished, // leaked and weak credentials with latest |create_time|, and after that joining // with autofill::PasswordForms to get passwords. If the credential is only // weak, |create_time| will be unset. struct CredentialWithPassword : CredentialView { explicit CredentialWithPassword(const CredentialView& credential); - explicit CredentialWithPassword(const CompromisedCredentials& credential); + explicit CredentialWithPassword(const InsecureCredential& credential); CredentialWithPassword(const CredentialWithPassword& other); CredentialWithPassword(CredentialWithPassword&& other); @@ -133,7 +133,7 @@ } }; -// Extra information about InsecureCredentials which is required by UI. +// Extra information about InsecureCredential which is required by UI. struct CredentialMetadata; // This class provides clients with saved insecure credentials and possibility @@ -141,9 +141,8 @@ // insecure credentials with corresponding autofill::PasswordForms. It supports // an observer interface, and clients can register themselves to get notified // about changes to the list. -class InsecureCredentialsManager - : public CompromisedCredentialsReader::Observer, - public SavedPasswordsPresenter::Observer { +class InsecureCredentialsManager : public InsecureCredentialsReader::Observer, + public SavedPasswordsPresenter::Observer { public: using CredentialsView = base::span<const CredentialWithPassword>; @@ -213,10 +212,9 @@ void OnWeakCheckDone(base::ElapsedTimer timer_since_weak_check_start, base::flat_set<base::string16> weak_passwords); - // CompromisedCredentialsReader::Observer: - void OnCompromisedCredentialsChanged( - const std::vector<CompromisedCredentials>& compromised_credentials) - override; + // InsecureCredentialsReader::Observer: + void OnInsecureCredentialsChanged( + const std::vector<InsecureCredential>& insecure_credentials) override; // SavedPasswordsPresenter::Observer: void OnEdited(const PasswordForm& form) override; @@ -243,10 +241,10 @@ // The reader used to read the compromised credentials from the password // stores. - CompromisedCredentialsReader compromised_credentials_reader_; + InsecureCredentialsReader insecure_credentials_reader_; - // Cache of the most recently obtained compromised credentials. - std::vector<CompromisedCredentials> compromised_credentials_; + // Cache of the most recently obtained insecure credentials. + std::vector<InsecureCredential> insecure_credentials_; // Cache of the most recently obtained weak passwords. base::flat_set<base::string16> weak_passwords_; @@ -255,11 +253,11 @@ // create_type and combined insecure type. CredentialPasswordsMap credentials_to_forms_; - // A scoped observer for |compromised_credentials_reader_| to listen changes - // related to CompromisedCredentials only. - base::ScopedObservation<CompromisedCredentialsReader, - CompromisedCredentialsReader::Observer> - observed_compromised_credentials_reader_{this}; + // A scoped observer for |insecure_credentials_reader_| to listen changes + // related to InsecureCredential only. + base::ScopedObservation<InsecureCredentialsReader, + InsecureCredentialsReader::Observer> + observed_insecure_credentials_reader_{this}; // A scoped observer for |presenter_|. base::ScopedObservation<SavedPasswordsPresenter,
diff --git a/components/password_manager/core/browser/ui/compromised_credentials_reader.cc b/components/password_manager/core/browser/ui/insecure_credentials_reader.cc similarity index 66% rename from components/password_manager/core/browser/ui/compromised_credentials_reader.cc rename to components/password_manager/core/browser/ui/insecure_credentials_reader.cc index 11342913..013b5d6 100644 --- a/components/password_manager/core/browser/ui/compromised_credentials_reader.cc +++ b/components/password_manager/core/browser/ui/insecure_credentials_reader.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/password_manager/core/browser/ui/compromised_credentials_reader.h" +#include "components/password_manager/core/browser/ui/insecure_credentials_reader.h" #include <iterator> @@ -11,7 +11,7 @@ #include "components/password_manager/core/browser/password_form.h" namespace password_manager { -CompromisedCredentialsReader::CompromisedCredentialsReader( +InsecureCredentialsReader::InsecureCredentialsReader( PasswordStore* profile_store, PasswordStore* account_store) : profile_store_(profile_store), account_store_(account_store) { @@ -27,80 +27,80 @@ } } -CompromisedCredentialsReader::~CompromisedCredentialsReader() = default; +InsecureCredentialsReader::~InsecureCredentialsReader() = default; -void CompromisedCredentialsReader::Init() { +void InsecureCredentialsReader::Init() { profile_store_->GetAllCompromisedCredentials(this); if (account_store_) account_store_->GetAllCompromisedCredentials(this); } -void CompromisedCredentialsReader::OnCompromisedCredentialsChanged() { +void InsecureCredentialsReader::OnInsecureCredentialsChanged() { // This class overrides OnCompromisedCredentialsChangedIn() (the version of // this method that also receives the originating store), so the store-less // version never gets called. NOTREACHED(); } -void CompromisedCredentialsReader::OnCompromisedCredentialsChangedIn( +void InsecureCredentialsReader::OnInsecureCredentialsChangedIn( PasswordStore* store) { store->GetAllCompromisedCredentials(this); } -void CompromisedCredentialsReader::OnGetCompromisedCredentials( - std::vector<CompromisedCredentials> compromised_credentials) { +void InsecureCredentialsReader::OnGetCompromisedCredentials( + std::vector<InsecureCredential> insecure_credentials) { // This class overrides OnGetCompromisedCredentialFrom() (the version of this // method that also receives the originating store), so the store-less version // never gets called. NOTREACHED(); } -void CompromisedCredentialsReader::OnGetCompromisedCredentialsFrom( +void InsecureCredentialsReader::OnGetCompromisedCredentialsFrom( PasswordStore* store, - std::vector<CompromisedCredentials> compromised_credentials) { + std::vector<InsecureCredential> insecure_credentials) { profile_store_responded_ |= store == profile_store_; account_store_responded_ |= store == account_store_; // Remove all previously cached credentials from `store` and then insert - // the just received `compromised_credentials`. + // the just received `insecure_credentials`. PasswordForm::Store to_remove = store == profile_store_ ? PasswordForm::Store::kProfileStore : PasswordForm::Store::kAccountStore; - base::EraseIf(compromised_credentials_, [to_remove](const auto& credential) { + base::EraseIf(insecure_credentials_, [to_remove](const auto& credential) { return credential.in_store == to_remove; }); - base::ranges::move(compromised_credentials, - std::back_inserter(compromised_credentials_)); + base::ranges::move(insecure_credentials, + std::back_inserter(insecure_credentials_)); // Observers are reptitively notified of compromised credentials, and hence // vbservers can expect partial view of the compromised credentials, so inform // the observers directly. for (auto& observer : observers_) - observer.OnCompromisedCredentialsChanged(compromised_credentials_); + observer.OnInsecureCredentialsChanged(insecure_credentials_); // For the callbacks waiting for the results of - // `GetAllCompromisedCredentials()`, they should be notified only when both + // `GetAllInsecureCredentials()`, they should be notified only when both // stores responded. if (!profile_store_responded_ || !account_store_responded_) return; for (auto& callback : - std::exchange(get_all_compromised_credentials_callbacks_, {})) { - std::move(callback).Run(compromised_credentials_); + std::exchange(get_all_insecure_credentials_callbacks_, {})) { + std::move(callback).Run(insecure_credentials_); } } -void CompromisedCredentialsReader::GetAllCompromisedCredentials( - GetCompromisedCredentialsCallback cb) { +void InsecureCredentialsReader::GetAllInsecureCredentials( + GetInsecureCredentialsCallback cb) { if (profile_store_responded_ && account_store_responded_) { - std::move(cb).Run(compromised_credentials_); + std::move(cb).Run(insecure_credentials_); return; } // Add the callback *before* triggering any of the fetches. This ensures // that we don't miss a notitication if the fetches return synchronously // (which is the case in tests). - get_all_compromised_credentials_callbacks_.push_back(std::move(cb)); + get_all_insecure_credentials_callbacks_.push_back(std::move(cb)); if (!profile_store_responded_) profile_store_->GetAllCompromisedCredentials(this); @@ -110,11 +110,11 @@ } } -void CompromisedCredentialsReader::AddObserver(Observer* observer) { +void InsecureCredentialsReader::AddObserver(Observer* observer) { observers_.AddObserver(observer); } -void CompromisedCredentialsReader::RemoveObserver(Observer* observer) { +void InsecureCredentialsReader::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); }
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_reader.h b/components/password_manager/core/browser/ui/insecure_credentials_reader.h new file mode 100644 index 0000000..0e452cfa --- /dev/null +++ b/components/password_manager/core/browser/ui/insecure_credentials_reader.h
@@ -0,0 +1,90 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_UI_INSECURE_CREDENTIALS_READER_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_UI_INSECURE_CREDENTIALS_READER_H_ + +#include "base/observer_list.h" +#include "base/scoped_multi_source_observation.h" +#include "components/password_manager/core/browser/compromised_credentials_consumer.h" +#include "components/password_manager/core/browser/password_store.h" + +namespace password_manager { +// This class is responsible for reading and listening to change in the +// insecure credentials in the underlying password stores. +class InsecureCredentialsReader + : public PasswordStore::DatabaseInsecureCredentialsObserver, + public CompromisedCredentialsConsumer { + public: + using GetInsecureCredentialsCallback = + base::OnceCallback<void(std::vector<InsecureCredential>)>; + // Observer interface. Clients can implement this to get notified about + // changes to the list of insecure credentials. Clients can register and + // de-register themselves, and are expected to do so before the provider gets + // out of scope. + class Observer : public base::CheckedObserver { + public: + virtual void OnInsecureCredentialsChanged( + const std::vector<InsecureCredential>& insecure_credentials) = 0; + }; + + // |profile_store| cannot be null, and must outlive this class. + explicit InsecureCredentialsReader(PasswordStore* profile_store, + PasswordStore* account_store = nullptr); + InsecureCredentialsReader(const InsecureCredentialsReader&) = delete; + InsecureCredentialsReader& operator=(const InsecureCredentialsReader&) = + delete; + ~InsecureCredentialsReader() override; + + void Init(); + + // `callback` must outlive this object. + void GetAllInsecureCredentials(GetInsecureCredentialsCallback callback); + + // Allows clients and register and de-register themselves. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + private: + // PasswordStore::DatabaseInsecureCredentialsObserver: + void OnInsecureCredentialsChanged() override; + void OnInsecureCredentialsChangedIn(PasswordStore* store) override; + + // CompromisedCredentialsConsumer: + void OnGetCompromisedCredentials( + std::vector<CompromisedCredentials> compromised_credentials) override; + void OnGetCompromisedCredentialsFrom( + PasswordStore* store, + std::vector<CompromisedCredentials> compromised_credentials) override; + + // The password stores containing the insecure credentials. + // |profile_store_| must not be null and must outlive this class. + PasswordStore* profile_store_; + PasswordStore* account_store_; + + // Cache of the most recently obtained insecure credentials. + std::vector<InsecureCredential> insecure_credentials_; + + // A scoped observer for |profile_store_|, and |account_store_| that listens + // to changes related to InsecureCredentials only. + base::ScopedMultiSourceObservation< + PasswordStore, + PasswordStore::DatabaseInsecureCredentialsObserver, + &PasswordStore::AddDatabaseInsecureCredentialsObserver, + &PasswordStore::RemoveDatabaseInsecureCredentialsObserver> + observed_password_stores_{this}; + + base::ObserverList<Observer, /*check_empty=*/true> observers_; + std::vector<GetInsecureCredentialsCallback> + get_all_insecure_credentials_callbacks_; + + // Whether we are still waiting for a first response from the profile and + // account stores. + bool profile_store_responded_ = false; + bool account_store_responded_ = false; +}; + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_UI_INSECURE_CREDENTIALS_READER_H_
diff --git a/components/password_manager/core/browser/ui/compromised_credentials_reader_unittest.cc b/components/password_manager/core/browser/ui/insecure_credentials_reader_unittest.cc similarity index 65% rename from components/password_manager/core/browser/ui/compromised_credentials_reader_unittest.cc rename to components/password_manager/core/browser/ui/insecure_credentials_reader_unittest.cc index 4dc0df6b..d508c0a 100644 --- a/components/password_manager/core/browser/ui/compromised_credentials_reader_unittest.cc +++ b/components/password_manager/core/browser/ui/insecure_credentials_reader_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/password_manager/core/browser/ui/compromised_credentials_reader.h" +#include "components/password_manager/core/browser/ui/insecure_credentials_reader.h" #include "base/memory/scoped_refptr.h" #include "base/scoped_observation.h" @@ -22,12 +22,12 @@ constexpr const char kTestWebRealm[] = "https://one.example.com/"; -class MockCompromisedCredentialsReaderObserver - : public CompromisedCredentialsReader::Observer { +class MockInsecureCredentialsReaderObserver + : public InsecureCredentialsReader::Observer { public: MOCK_METHOD(void, - OnCompromisedCredentialsChanged, - (const std::vector<CompromisedCredentials>&), + OnInsecureCredentialsChanged, + (const std::vector<InsecureCredential>&), (override)); }; @@ -41,14 +41,14 @@ return form; } -class CompromisedCredentialsReaderTest : public ::testing::Test { +class InsecureCredentialsReaderTest : public ::testing::Test { protected: - CompromisedCredentialsReaderTest() { + InsecureCredentialsReaderTest() { profile_store_->Init(/*prefs=*/nullptr); account_store_->Init(/*prefs=*/nullptr); } - ~CompromisedCredentialsReaderTest() override { + ~InsecureCredentialsReaderTest() override { account_store_->ShutdownOnUIThread(); profile_store_->ShutdownOnUIThread(); task_env_.RunUntilIdle(); @@ -56,7 +56,7 @@ TestPasswordStore& profile_store() { return *profile_store_; } TestPasswordStore& account_store() { return *account_store_; } - CompromisedCredentialsReader& reader() { return reader_; } + InsecureCredentialsReader& reader() { return reader_; } void RunUntilIdle() { task_env_.RunUntilIdle(); } @@ -66,77 +66,72 @@ base::MakeRefCounted<TestPasswordStore>(IsAccountStore(false)); scoped_refptr<TestPasswordStore> account_store_ = base::MakeRefCounted<TestPasswordStore>(IsAccountStore(true)); - CompromisedCredentialsReader reader_{profile_store_.get(), - account_store_.get()}; + InsecureCredentialsReader reader_{profile_store_.get(), account_store_.get()}; }; } // namespace -TEST_F(CompromisedCredentialsReaderTest, AddCredentialsToBothStores) { +TEST_F(InsecureCredentialsReaderTest, AddCredentialsToBothStores) { profile_store().AddLogin(MakeTestPassword("profile@gmail.com")); account_store().AddLogin(MakeTestPassword("account1@gmail.com")); account_store().AddLogin(MakeTestPassword("account2@gmail.com")); RunUntilIdle(); - CompromisedCredentials profile_cred; + InsecureCredential profile_cred; profile_cred.signon_realm = kTestWebRealm; profile_cred.username = base::ASCIIToUTF16("profile@gmail.com"); profile_cred.in_store = PasswordForm::Store::kProfileStore; - CompromisedCredentials account_cred1; + InsecureCredential account_cred1; account_cred1.signon_realm = kTestWebRealm; account_cred1.username = base::ASCIIToUTF16("account1@gmail.com"); account_cred1.in_store = PasswordForm::Store::kAccountStore; - CompromisedCredentials account_cred2; + InsecureCredential account_cred2; account_cred2.signon_realm = kTestWebRealm; account_cred2.username = base::ASCIIToUTF16("account2@gmail.com"); account_cred2.in_store = PasswordForm::Store::kAccountStore; - ::testing::NiceMock<MockCompromisedCredentialsReaderObserver> mock_observer; + ::testing::NiceMock<MockInsecureCredentialsReaderObserver> mock_observer; reader().AddObserver(&mock_observer); - EXPECT_CALL(mock_observer, OnCompromisedCredentialsChanged( - UnorderedElementsAre(profile_cred))); + EXPECT_CALL(mock_observer, + OnInsecureCredentialsChanged(UnorderedElementsAre(profile_cred))); profile_store().AddCompromisedCredentials(profile_cred); RunUntilIdle(); - EXPECT_CALL(mock_observer, - OnCompromisedCredentialsChanged( - UnorderedElementsAre(profile_cred, account_cred1))); + EXPECT_CALL(mock_observer, OnInsecureCredentialsChanged(UnorderedElementsAre( + profile_cred, account_cred1))); account_store().AddCompromisedCredentials(account_cred1); RunUntilIdle(); - EXPECT_CALL(mock_observer, - OnCompromisedCredentialsChanged(UnorderedElementsAre( - profile_cred, account_cred1, account_cred2))); + EXPECT_CALL(mock_observer, OnInsecureCredentialsChanged(UnorderedElementsAre( + profile_cred, account_cred1, account_cred2))); account_store().AddCompromisedCredentials(account_cred2); RunUntilIdle(); - EXPECT_CALL(mock_observer, - OnCompromisedCredentialsChanged( - UnorderedElementsAre(account_cred1, account_cred2))); + EXPECT_CALL(mock_observer, OnInsecureCredentialsChanged(UnorderedElementsAre( + account_cred1, account_cred2))); profile_store().RemoveCompromisedCredentials( profile_cred.signon_realm, profile_cred.username, RemoveInsecureCredentialsReason::kRemove); RunUntilIdle(); - EXPECT_CALL(mock_observer, - OnCompromisedCredentialsChanged(UnorderedElementsAre( - profile_cred, account_cred1, account_cred2))); + EXPECT_CALL(mock_observer, OnInsecureCredentialsChanged(UnorderedElementsAre( + profile_cred, account_cred1, account_cred2))); profile_store().AddCompromisedCredentials(profile_cred); RunUntilIdle(); reader().RemoveObserver(&mock_observer); } -TEST_F(CompromisedCredentialsReaderTest, GetAllCompromisedCredentials) { - CompromisedCredentials profile_cred; +TEST_F(InsecureCredentialsReaderTest, GetAllInsecureCredentials) { + InsecureCredential profile_cred; profile_cred.signon_realm = kTestWebRealm; profile_cred.username = base::ASCIIToUTF16("profile@gmail.com"); profile_cred.in_store = PasswordForm::Store::kProfileStore; - CompromisedCredentials account_cred; + InsecureCredential account_cred; account_cred.signon_realm = kTestWebRealm; account_cred.username = base::ASCIIToUTF16("account1@gmail.com"); account_cred.in_store = PasswordForm::Store::kAccountStore; @@ -144,15 +139,13 @@ profile_store().AddCompromisedCredentials(profile_cred); account_store().AddCompromisedCredentials(account_cred); - base::MockCallback< - CompromisedCredentialsReader::GetCompromisedCredentialsCallback> - get_all_compromised_credentials_cb; + base::MockCallback<InsecureCredentialsReader::GetInsecureCredentialsCallback> + get_all_insecure_credentials_cb; - reader().GetAllCompromisedCredentials( - get_all_compromised_credentials_cb.Get()); + reader().GetAllInsecureCredentials(get_all_insecure_credentials_cb.Get()); // The callback is run only after the stores respond in RunUntilIdle(). - EXPECT_CALL(get_all_compromised_credentials_cb, + EXPECT_CALL(get_all_insecure_credentials_cb, Run(UnorderedElementsAre(profile_cred, account_cred))); RunUntilIdle(); }
diff --git a/components/password_manager/core/browser/ui/post_save_compromised_helper.cc b/components/password_manager/core/browser/ui/post_save_compromised_helper.cc index f664b4e..e27ead6d 100644 --- a/components/password_manager/core/browser/ui/post_save_compromised_helper.cc +++ b/components/password_manager/core/browser/ui/post_save_compromised_helper.cc
@@ -16,9 +16,9 @@ constexpr auto kMaxTimeSinceLastCheck = base::TimeDelta::FromMinutes(30); PostSaveCompromisedHelper::PostSaveCompromisedHelper( - base::span<const CompromisedCredentials> compromised, + base::span<const InsecureCredential> compromised, const base::string16& current_username) { - for (const CompromisedCredentials& credential : compromised) { + for (const InsecureCredential& credential : compromised) { if (credential.username == current_username) current_leak_ = credential; } @@ -35,22 +35,21 @@ DCHECK(prefs); callback_ = std::move(callback); prefs_ = prefs; - compromised_credentials_reader_ = - std::make_unique<CompromisedCredentialsReader>(profile_store, - account_store); + insecure_credentials_reader_ = + std::make_unique<InsecureCredentialsReader>(profile_store, account_store); // Unretained(this) is safe here since `this` outlives - // `compromised_credentials_reader_`. - compromised_credentials_reader_->GetAllCompromisedCredentials( - base::BindOnce(&PostSaveCompromisedHelper::OnGetAllCompromisedCredentials, + // `insecure_credentials_reader_`. + insecure_credentials_reader_->GetAllInsecureCredentials( + base::BindOnce(&PostSaveCompromisedHelper::OnGetAllInsecureCredentials, base::Unretained(this))); } -void PostSaveCompromisedHelper::OnGetAllCompromisedCredentials( - std::vector<CompromisedCredentials> compromised_credentials) { +void PostSaveCompromisedHelper::OnGetAllInsecureCredentials( + std::vector<InsecureCredential> insecure_credentials) { const bool compromised_password_changed = - current_leak_ && !base::Contains(compromised_credentials, *current_leak_); + current_leak_ && !base::Contains(insecure_credentials, *current_leak_); bubble_type_ = BubbleType::kNoBubble; - if (compromised_credentials.empty()) { + if (insecure_credentials.empty()) { if (compromised_password_changed) { // Obtain the timestamp of the last completed check. This is 0.0 in case // the check never completely ran before. @@ -67,7 +66,7 @@ ? BubbleType::kPasswordUpdatedWithMoreToFix : BubbleType::kUnsafeState; } - compromised_count_ = compromised_credentials.size(); + compromised_count_ = insecure_credentials.size(); std::move(callback_).Run(bubble_type_, compromised_count_); }
diff --git a/components/password_manager/core/browser/ui/post_save_compromised_helper.h b/components/password_manager/core/browser/ui/post_save_compromised_helper.h index 3d0d224a..9e8bb8f 100644 --- a/components/password_manager/core/browser/ui/post_save_compromised_helper.h +++ b/components/password_manager/core/browser/ui/post_save_compromised_helper.h
@@ -11,7 +11,7 @@ #include "base/strings/string16.h" #include "base/time/time.h" #include "components/password_manager/core/browser/insecure_credentials_table.h" -#include "components/password_manager/core/browser/ui/compromised_credentials_reader.h" +#include "components/password_manager/core/browser/ui/insecure_credentials_reader.h" class PrefService; @@ -39,11 +39,10 @@ // credentials in total should be still fixed. using BubbleCallback = base::OnceCallback<void(BubbleType, size_t)>; - // |compromised| contains all compromised credentials for the current site. + // |compromised| contains all insecure credentials for the current site. // |current_username| is the username that was just saved or updated. - PostSaveCompromisedHelper( - base::span<const CompromisedCredentials> compromised, - const base::string16& current_username); + PostSaveCompromisedHelper(base::span<const InsecureCredential> compromised, + const base::string16& current_username); ~PostSaveCompromisedHelper(); PostSaveCompromisedHelper(const PostSaveCompromisedHelper&) = delete; @@ -61,11 +60,11 @@ size_t compromised_count() const { return compromised_count_; } private: - void OnGetAllCompromisedCredentials( - std::vector<CompromisedCredentials> compromised_credentials); + void OnGetAllInsecureCredentials( + std::vector<InsecureCredential> insecure_credentials); // Contains the entry for the currently leaked credentials if it was leaked. - base::Optional<CompromisedCredentials> current_leak_; + base::Optional<InsecureCredential> current_leak_; // Profile prefs. PrefService* prefs_ = nullptr; // Callback to notify the caller about the bubble type. @@ -75,7 +74,7 @@ // Count of compromised credentials after the callback was executed. size_t compromised_count_ = 0; - std::unique_ptr<CompromisedCredentialsReader> compromised_credentials_reader_; + std::unique_ptr<InsecureCredentialsReader> insecure_credentials_reader_; }; } // namespace password_manager
diff --git a/components/power_scheduler/power_mode_voter.cc b/components/power_scheduler/power_mode_voter.cc index 567bab9..b0be43e 100644 --- a/components/power_scheduler/power_mode_voter.cc +++ b/components/power_scheduler/power_mode_voter.cc
@@ -10,6 +10,9 @@ PowerModeVoter::PowerModeVoter(Delegate* delegate) : delegate_(delegate) {} +// static +constexpr base::TimeDelta PowerModeVoter::kResponseTimeout; + PowerModeVoter::~PowerModeVoter() { delegate_->OnVoterDestroyed(this); }
diff --git a/components/power_scheduler/power_mode_voter.h b/components/power_scheduler/power_mode_voter.h index 36330124..de1a7157 100644 --- a/components/power_scheduler/power_mode_voter.h +++ b/components/power_scheduler/power_mode_voter.h
@@ -27,6 +27,9 @@ base::TimeDelta timeout) = 0; }; + static constexpr base::TimeDelta kResponseTimeout = + base::TimeDelta::FromMilliseconds(100); + ~PowerModeVoter(); PowerModeVoter(const PowerModeVoter&) = delete;
diff --git a/components/services/storage/dom_storage/local_storage_impl.cc b/components/services/storage/dom_storage/local_storage_impl.cc index b5be68e..03289b9 100644 --- a/components/services/storage/dom_storage/local_storage_impl.cc +++ b/components/services/storage/dom_storage/local_storage_impl.cc
@@ -646,7 +646,7 @@ } void LocalStorageImpl::ApplyPolicyUpdates( - std::vector<mojom::LocalStoragePolicyUpdatePtr> policy_updates) { + std::vector<mojom::StoragePolicyUpdatePtr> policy_updates) { for (const auto& update : policy_updates) { GURL url = update->origin.GetURL(); if (!update->purge_on_shutdown)
diff --git a/components/services/storage/dom_storage/local_storage_impl.h b/components/services/storage/dom_storage/local_storage_impl.h index 410b65b..9c7075c 100644 --- a/components/services/storage/dom_storage/local_storage_impl.h +++ b/components/services/storage/dom_storage/local_storage_impl.h
@@ -22,6 +22,7 @@ #include "components/services/storage/dom_storage/async_dom_storage_database.h" #include "components/services/storage/dom_storage/dom_storage_database.h" #include "components/services/storage/public/mojom/local_storage_control.mojom.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -83,7 +84,7 @@ void Flush(FlushCallback callback) override; void PurgeMemory() override; void ApplyPolicyUpdates( - std::vector<mojom::LocalStoragePolicyUpdatePtr> policy_updates) override; + std::vector<mojom::StoragePolicyUpdatePtr> policy_updates) override; void ForceKeepSessionState() override; // base::trace_event::MemoryDumpProvider implementation.
diff --git a/components/services/storage/dom_storage/local_storage_impl_unittest.cc b/components/services/storage/dom_storage/local_storage_impl_unittest.cc index bab99f8..fc15b449 100644 --- a/components/services/storage/dom_storage/local_storage_impl_unittest.cc +++ b/components/services/storage/dom_storage/local_storage_impl_unittest.cc
@@ -831,9 +831,9 @@ // Make sure all data gets committed to the DB. RunUntilIdle(); - std::vector<mojom::LocalStoragePolicyUpdatePtr> updates; - updates.push_back(mojom::LocalStoragePolicyUpdate::New( - origin1, /*purge_on_shutdown=*/true)); + std::vector<mojom::StoragePolicyUpdatePtr> updates; + updates.emplace_back( + mojom::StoragePolicyUpdate::New(origin1, /*purge_on_shutdown=*/true)); context()->ApplyPolicyUpdates(std::move(updates)); // Data from origin2 should exist, including meta-data, but nothing should
diff --git a/components/services/storage/public/mojom/BUILD.gn b/components/services/storage/public/mojom/BUILD.gn index 4f52cded..df4c03b 100644 --- a/components/services/storage/public/mojom/BUILD.gn +++ b/components/services/storage/public/mojom/BUILD.gn
@@ -18,6 +18,7 @@ "service_worker_database.mojom", "service_worker_storage_control.mojom", "session_storage_control.mojom", + "storage_policy_update.mojom", "storage_service.mojom", "storage_usage_info.mojom", ]
diff --git a/components/services/storage/public/mojom/indexed_db_control.mojom b/components/services/storage/public/mojom/indexed_db_control.mojom index f655f84..7c85924 100644 --- a/components/services/storage/public/mojom/indexed_db_control.mojom +++ b/components/services/storage/public/mojom/indexed_db_control.mojom
@@ -5,6 +5,7 @@ module storage.mojom; import "components/services/storage/public/mojom/indexed_db_control_test.mojom"; +import "components/services/storage/public/mojom/storage_policy_update.mojom"; import "components/services/storage/public/mojom/storage_usage_info.mojom"; import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/string16.mojom"; @@ -24,15 +25,6 @@ // enums.xml. }; -// Indicates a policy update for a specific origin. -struct IndexedDBStoragePolicyUpdate { - // The origin to which this policy applies. - url.mojom.Origin origin; - - // Indicates whether data for this origin should be purged on shutdown. - bool purge_on_shutdown; -}; - // Communicates with IndexedDB clients about changes in IndexedDB. interface IndexedDBObserver { // This function is called when the size of the usage for a particular origin @@ -91,8 +83,8 @@ AddObserver(pending_remote<IndexedDBObserver> observer); // Applies changes to data retention policy which are relevant at shutdown. - // See IndexedDBStoragePolicyUpdate. - ApplyPolicyUpdates(array<IndexedDBStoragePolicyUpdate> policy_updates); + // See StoragePolicyUpdate. + ApplyPolicyUpdates(array<StoragePolicyUpdate> policy_updates); // Binds the testing interface for extra functionality only available in // tests.
diff --git a/components/services/storage/public/mojom/local_storage_control.mojom b/components/services/storage/public/mojom/local_storage_control.mojom index 56809ef..9c8f1ae 100644 --- a/components/services/storage/public/mojom/local_storage_control.mojom +++ b/components/services/storage/public/mojom/local_storage_control.mojom
@@ -4,20 +4,12 @@ module storage.mojom; +import "components/services/storage/public/mojom/storage_policy_update.mojom"; import "components/services/storage/public/mojom/storage_usage_info.mojom"; import "mojo/public/mojom/base/time.mojom"; import "third_party/blink/public/mojom/dom_storage/storage_area.mojom"; import "url/mojom/origin.mojom"; -// Indicates a policy update for a specific origin. -struct LocalStoragePolicyUpdate { - // The origin to which this policy applies. - url.mojom.Origin origin; - - // Indicates whether data for this origin should be purged on shutdown. - bool purge_on_shutdown; -}; - // Controls the state of Local Storage within a partition. This is a privileged // interface and must not be brokered to untrusted clients. // @@ -48,8 +40,8 @@ PurgeMemory(); // Applies changes to data retention policy which are relevant at shutdown. - // See LocalStoragePolicyUpdate. - ApplyPolicyUpdates(array<LocalStoragePolicyUpdate> policy_updates); + // See StoragePolicyUpdate. + ApplyPolicyUpdates(array<StoragePolicyUpdate> policy_updates); // Some origins may be configured to be purged at the end of a session rather // than persisted as in the default Local Storage behavior. If this is called,
diff --git a/components/services/storage/public/mojom/service_worker_storage_control.mojom b/components/services/storage/public/mojom/service_worker_storage_control.mojom index e5d8137..c35a4e4 100644 --- a/components/services/storage/public/mojom/service_worker_storage_control.mojom +++ b/components/services/storage/public/mojom/service_worker_storage_control.mojom
@@ -4,7 +4,7 @@ module storage.mojom; -import "components/services/storage/public/mojom/local_storage_control.mojom"; +import "components/services/storage/public/mojom/storage_policy_update.mojom"; import "components/services/storage/public/mojom/service_worker_database.mojom"; import "mojo/public/mojom/base/big_buffer.mojom"; import "mojo/public/mojom/base/time.mojom"; @@ -295,7 +295,7 @@ // Applies changes to data retention policy which are relevant at shutdown. // This is analogous to LocalStorageControl::ApplyPolicyUpdates. - ApplyPolicyUpdates(array<LocalStoragePolicyUpdate> policy_updates) => + ApplyPolicyUpdates(array<StoragePolicyUpdate> policy_updates) => (ServiceWorkerDatabaseStatus status); // Get resource ids which are scheduled to purge.
diff --git a/components/services/storage/public/mojom/storage_policy_update.mojom b/components/services/storage/public/mojom/storage_policy_update.mojom new file mode 100644 index 0000000..d22150b4 --- /dev/null +++ b/components/services/storage/public/mojom/storage_policy_update.mojom
@@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module storage.mojom; + +import "url/mojom/origin.mojom"; + +// Indicates a policy update for a specific origin. +struct StoragePolicyUpdate { + // The origin to which this policy applies. + url.mojom.Origin origin; + + // Indicates whether data for this origin should be purged on shutdown. + bool purge_on_shutdown; +};
diff --git a/components/services/storage/service_worker/service_worker_storage.cc b/components/services/storage/service_worker/service_worker_storage.cc index 8c197ea..6dc5043 100644 --- a/components/services/storage/service_worker/service_worker_storage.cc +++ b/components/services/storage/service_worker/service_worker_storage.cc
@@ -1179,8 +1179,7 @@ } void ServiceWorkerStorage::ApplyPolicyUpdates( - const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr>& - policy_updates, + const std::vector<storage::mojom::StoragePolicyUpdatePtr>& policy_updates, DatabaseStatusCallback callback) { switch (state_) { case STORAGE_STATE_DISABLED: @@ -1189,8 +1188,7 @@ case STORAGE_STATE_INITIALIZING: case STORAGE_STATE_UNINITIALIZED: { // An explicit clone is needed to pass `policy_updates` to LazyInitialize. - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> - cloned_policy_updates; + std::vector<storage::mojom::StoragePolicyUpdatePtr> cloned_policy_updates; for (const auto& entry : policy_updates) cloned_policy_updates.push_back(entry.Clone());
diff --git a/components/services/storage/service_worker/service_worker_storage.h b/components/services/storage/service_worker/service_worker_storage.h index dc3b01b6..1bd9d7e 100644 --- a/components/services/storage/service_worker/service_worker_storage.h +++ b/components/services/storage/service_worker/service_worker_storage.h
@@ -23,6 +23,7 @@ #include "base/memory/weak_ptr.h" #include "components/services/storage/public/mojom/local_storage_control.mojom.h" #include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "components/services/storage/service_worker/service_worker_database.h" #include "components/services/storage/service_worker/service_worker_resource_ops.h" #include "url/gurl.h" @@ -277,8 +278,7 @@ // Applies |policy_updates|. void ApplyPolicyUpdates( - const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr>& - policy_updates, + const std::vector<storage::mojom::StoragePolicyUpdatePtr>& policy_updates, DatabaseStatusCallback callback); void LazyInitializeForTest();
diff --git a/components/services/storage/service_worker/service_worker_storage_control_impl.cc b/components/services/storage/service_worker/service_worker_storage_control_impl.cc index fc83ebf7..6ad9672f 100644 --- a/components/services/storage/service_worker/service_worker_storage_control_impl.cc +++ b/components/services/storage/service_worker/service_worker_storage_control_impl.cc
@@ -77,20 +77,15 @@ }; ServiceWorkerStorageControlImpl::ServiceWorkerStorageControlImpl( - std::unique_ptr<ServiceWorkerStorage> storage) - : storage_(std::move(storage)) { - DCHECK(storage_); -} + const base::FilePath& user_data_directory, + scoped_refptr<base::SequencedTaskRunner> database_task_runner, + mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl> receiver) + : storage_(ServiceWorkerStorage::Create(user_data_directory, + std::move(database_task_runner))), + receiver_(this, std::move(receiver)) {} ServiceWorkerStorageControlImpl::~ServiceWorkerStorageControlImpl() = default; -void ServiceWorkerStorageControlImpl::Bind( - mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl> - receiver) { - DCHECK(!receiver_.is_bound()); - receiver_.Bind(std::move(receiver)); -} - void ServiceWorkerStorageControlImpl::OnNoLiveVersion(int64_t version_id) { auto it = live_versions_.find(version_id); DCHECK(it != live_versions_.end()); @@ -366,8 +361,7 @@ } void ServiceWorkerStorageControlImpl::ApplyPolicyUpdates( - const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> - policy_updates, + const std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates, ApplyPolicyUpdatesCallback callback) { storage_->ApplyPolicyUpdates(std::move(policy_updates), std::move(callback)); }
diff --git a/components/services/storage/service_worker/service_worker_storage_control_impl.h b/components/services/storage/service_worker/service_worker_storage_control_impl.h index 6c5ae9da..00e0423 100644 --- a/components/services/storage/service_worker/service_worker_storage_control_impl.h +++ b/components/services/storage/service_worker/service_worker_storage_control_impl.h
@@ -8,7 +8,9 @@ #include <memory> #include "base/containers/flat_map.h" +#include "base/files/file_path.h" #include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" #include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h" #include "components/services/storage/service_worker/service_worker_storage.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -25,8 +27,11 @@ class ServiceWorkerStorageControlImpl : public storage::mojom::ServiceWorkerStorageControl { public: - explicit ServiceWorkerStorageControlImpl( - std::unique_ptr<ServiceWorkerStorage> storage); + ServiceWorkerStorageControlImpl( + const base::FilePath& user_data_directory, + scoped_refptr<base::SequencedTaskRunner> database_task_runner, + mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl> + receiver); ServiceWorkerStorageControlImpl(const ServiceWorkerStorageControlImpl&) = delete; @@ -35,9 +40,6 @@ ~ServiceWorkerStorageControlImpl() override; - void Bind(mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl> - receiver); - void OnNoLiveVersion(int64_t version_id); void LazyInitializeForTest(); @@ -145,8 +147,7 @@ ClearUserDataForAllRegistrationsByKeyPrefixCallback callback) override; void PerformStorageCleanup(PerformStorageCleanupCallback callback) override; void ApplyPolicyUpdates( - const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> - policy_updates, + const std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates, ApplyPolicyUpdatesCallback callback) override; void GetPurgingResourceIdsForTest( GetPurgingResourceIdsForTestCallback callback) override; @@ -197,7 +198,7 @@ const std::unique_ptr<ServiceWorkerStorage> storage_; - mojo::Receiver<storage::mojom::ServiceWorkerStorageControl> receiver_{this}; + mojo::Receiver<storage::mojom::ServiceWorkerStorageControl> receiver_; base::flat_map<int64_t /*version_id*/, std::unique_ptr<ServiceWorkerLiveVersionRefImpl>>
diff --git a/components/services/storage/service_worker/service_worker_storage_control_impl_unittest.cc b/components/services/storage/service_worker/service_worker_storage_control_impl_unittest.cc index 6661c73..d7fde99 100644 --- a/components/services/storage/service_worker/service_worker_storage_control_impl_unittest.cc +++ b/components/services/storage/service_worker/service_worker_storage_control_impl_unittest.cc
@@ -15,7 +15,6 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "components/services/storage/service_worker/service_worker_storage.h" #include "components/services/storage/service_worker/service_worker_storage_test_utils.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe_utils.h" @@ -178,14 +177,14 @@ void TearDown() override { DestroyStorage(); } void SetUpStorage() { - auto storage = ServiceWorkerStorage::Create( + storage_impl_ = std::make_unique<ServiceWorkerStorageControlImpl>( user_data_directory_.GetPath(), - /*database_task_runner=*/base::ThreadTaskRunnerHandle::Get()); - storage_impl_ = - std::make_unique<ServiceWorkerStorageControlImpl>(std::move(storage)); + /*database_task_runner=*/base::ThreadTaskRunnerHandle::Get(), + remote_.BindNewPipeAndPassReceiver()); } void DestroyStorage() { + remote_.reset(); storage_impl_.reset(); disk_cache::FlushCacheThreadForTesting(); task_environment().RunUntilIdle(); @@ -684,6 +683,7 @@ base::ScopedTempDir user_data_directory_; base::test::TaskEnvironment task_environment_; std::unique_ptr<ServiceWorkerStorageControlImpl> storage_impl_; + mojo::Remote<mojom::ServiceWorkerStorageControl> remote_; }; // Tests that FindRegistration methods don't find anything without having stored @@ -1443,8 +1443,8 @@ ASSERT_EQ(status, DatabaseStatus::kOk); // Update policies to purge the registration for |kScope2| on shutdown. - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> updates; - updates.push_back(storage::mojom::LocalStoragePolicyUpdate::New( + std::vector<storage::mojom::StoragePolicyUpdatePtr> updates; + updates.emplace_back(storage::mojom::StoragePolicyUpdate::New( url::Origin::Create(kScope2.GetOrigin()), /*purge_on_shutdown=*/true)); base::RunLoop loop; storage()->ApplyPolicyUpdates(
diff --git a/components/sync_bookmarks/bookmark_local_changes_builder.cc b/components/sync_bookmarks/bookmark_local_changes_builder.cc index 72725e6..1f85aa70 100644 --- a/components/sync_bookmarks/bookmark_local_changes_builder.cc +++ b/components/sync_bookmarks/bookmark_local_changes_builder.cc
@@ -65,9 +65,7 @@ // committed once the favicon is loaded in // BookmarkModelObserverImpl::BookmarkNodeFaviconChanged. if (!node->is_folder() && !node->is_favicon_loaded() && - !node->is_permanent_node() && - base::FeatureList::IsEnabled( - switches::kSyncDoNotCommitBookmarksWithoutFavicon)) { + !node->is_permanent_node()) { // Force the favicon to be loaded. The worker will be nudged for commit // in BookmarkModelObserverImpl::BookmarkNodeFaviconChanged() once // favicon is loaded.
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl.cc b/components/sync_bookmarks/bookmark_model_observer_impl.cc index a4340bf..176078d 100644 --- a/components/sync_bookmarks/bookmark_model_observer_impl.cc +++ b/components/sync_bookmarks/bookmark_model_observer_impl.cc
@@ -12,10 +12,8 @@ #include "components/bookmarks/browser/bookmark_node.h" #include "components/sync/base/hash_util.h" #include "components/sync/base/unique_position.h" -#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/engine/commit_and_get_updates_types.h" #include "components/sync_bookmarks/bookmark_specifics_conversions.h" -#include "components/sync_bookmarks/switches.h" namespace sync_bookmarks { @@ -243,9 +241,7 @@ // The favicon content didn't actually change, which means this event is // almost certainly the result of favicon loading having completed. - if (entity->IsUnsynced() && - base::FeatureList::IsEnabled( - switches::kSyncDoNotCommitBookmarksWithoutFavicon)) { + if (entity->IsUnsynced()) { // When kSyncDoNotCommitBookmarksWithoutFavicon is enabled, nudge for // commit once favicon is loaded. This is needed in case when unsynced // entity was skipped while building commit requests (since favicon wasn't
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc b/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc index 80429c0..867fd3be 100644 --- a/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc +++ b/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc
@@ -14,15 +14,12 @@ #include "base/callback_helpers.h" #include "base/strings/utf_string_conversions.h" #include "base/test/mock_callback.h" -#include "base/test/scoped_feature_list.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/test/test_bookmark_client.h" #include "components/favicon_base/favicon_types.h" #include "components/sync/base/time.h" #include "components/sync/base/unique_position.h" -#include "components/sync/driver/sync_driver_switches.h" #include "components/sync_bookmarks/bookmark_specifics_conversions.h" -#include "components/sync_bookmarks/switches.h" #include "components/sync_bookmarks/synced_bookmark_tracker.h" #include "components/undo/bookmark_undo_service.h" #include "testing/gmock/include/gmock/gmock.h" @@ -799,10 +796,6 @@ TEST_F(BookmarkModelObserverImplTest, ShouldNudgeForCommitOnFaviconLoadAfterRestart) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - switches::kSyncDoNotCommitBookmarksWithoutFavicon); - const GURL kBookmarkUrl("http://www.url.com"); const GURL kIconUrl("http://www.url.com/favicon.ico"); const SkColor kColor = SK_ColorRED;
diff --git a/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc b/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc index 442f619..c8b4038 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc
@@ -676,10 +676,6 @@ TEST_F(BookmarkModelTypeProcessorTest, ShouldNotCommitEntitiesWithoutLoadedFavicons) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature( - switches::kSyncDoNotCommitBookmarksWithoutFavicon); - const std::string kNodeId = "node_id1"; const std::string kTitle = "title1"; const std::string kUrl = "http://www.url1.com";
diff --git a/components/sync_bookmarks/switches.cc b/components/sync_bookmarks/switches.cc index 8fb804f..09fcd6b7 100644 --- a/components/sync_bookmarks/switches.cc +++ b/components/sync_bookmarks/switches.cc
@@ -6,9 +6,6 @@ namespace switches { -const base::Feature kSyncDoNotCommitBookmarksWithoutFavicon = { - "SyncDoNotCommitBookmarksWithoutFavicon", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kSyncReuploadBookmarkFullTitles{ "SyncReuploadBookmarkFullTitles", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/sync_bookmarks/switches.h b/components/sync_bookmarks/switches.h index 37b0de4..4ff96413 100644 --- a/components/sync_bookmarks/switches.h +++ b/components/sync_bookmarks/switches.h
@@ -9,7 +9,6 @@ namespace switches { -extern const base::Feature kSyncDoNotCommitBookmarksWithoutFavicon; // TODO(crbug.com/1066962): remove this code when most of bookmarks are // reuploaded. extern const base::Feature kSyncReuploadBookmarkFullTitles;
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index a0f471e..b616e02d 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -32,9 +32,8 @@ // Use the SkiaRenderer. const base::Feature kUseSkiaRenderer { "UseSkiaRenderer", -#if defined(OS_WIN) || defined(OS_ANDROID) || \ - (defined(OS_LINUX) && \ - !(BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMECAST))) +#if defined(OS_WIN) || defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_LACROS) || \ + (defined(OS_LINUX) && !BUILDFLAG(IS_CHROMECAST)) base::FEATURE_ENABLED_BY_DEFAULT #else base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/content/DEPS b/content/DEPS index a5cca8b..02f35ee 100644 --- a/content/DEPS +++ b/content/DEPS
@@ -24,6 +24,7 @@ # as autofill or extensions, and chrome implementation details such as # settings, packaging details, installation or crash reporting. + "+components/power_scheduler", "+components/services/filesystem", "+components/services/font/public", "+components/variations",
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 7919662a..bd11bcf 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -77,6 +77,7 @@ "//components/payments/core", "//components/payments/core:error_strings", "//components/payments/mojom", + "//components/power_scheduler", "//components/rappor", "//components/services/filesystem:lib", "//components/services/quarantine:quarantine",
diff --git a/content/browser/accessibility/accessibility_auralinux_browsertest.cc b/content/browser/accessibility/accessibility_auralinux_browsertest.cc index 8bbb8990..69d1a55 100644 --- a/content/browser/accessibility/accessibility_auralinux_browsertest.cc +++ b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
@@ -234,8 +234,9 @@ host_view_parent)); } -IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest, - TestTextAtOffsetWithBoundaryCharacterAndEmbeddedObject) { +IN_PROC_BROWSER_TEST_F( + AccessibilityAuraLinuxBrowserTest, + DISABLED_TestTextAtOffsetWithBoundaryCharacterAndEmbeddedObject) { LoadInitialAccessibilityTreeFromHtml(R"HTML(<!DOCTYPE html> <div contenteditable> Before<img alt="image">after.
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index 5824701..a2b950e 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -3716,8 +3716,9 @@ } } -IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, - TestTextAtOffsetWithBoundaryCharacterAndEmbeddedObject) { +IN_PROC_BROWSER_TEST_F( + AccessibilityWinBrowserTest, + DISABLED_TestTextAtOffsetWithBoundaryCharacterAndEmbeddedObject) { LoadInitialAccessibilityTreeFromHtml(R"HTML(<!DOCTYPE html> <div contenteditable> Before<img alt="image">after.
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc index d07b3b8..4a6fce1 100644 --- a/content/browser/accessibility/browser_accessibility_win_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -1491,7 +1491,8 @@ } } -TEST_F(BrowserAccessibilityWinTest, TestTextBoundariesEmbeddedCharacterText) { +TEST_F(BrowserAccessibilityWinTest, + DISABLED_TestTextBoundariesEmbeddedCharacterText) { // Update the tree structure to test empty leaf text positions. // // +-1 root_data
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index a3171a40..e7e4b70 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -206,40 +206,27 @@ // static void RenderFrameDevToolsAgentHost::UpdateRawHeadersAccess( - RenderFrameHostImpl* old_rfh, - RenderFrameHostImpl* new_rfh) { - DCHECK_NE(old_rfh, new_rfh); - RenderProcessHost* old_rph = old_rfh ? old_rfh->GetProcess() : nullptr; - RenderProcessHost* new_rph = new_rfh ? new_rfh->GetProcess() : nullptr; - if (old_rph == new_rph) + RenderFrameHostImpl* rfh) { + if (!rfh) { return; - std::set<url::Origin> old_process_origins; - std::set<url::Origin> new_process_origins; + } + RenderProcessHost* rph = rfh->GetProcess(); + std::set<url::Origin> process_origins; for (const auto& entry : g_agent_host_instances.Get()) { RenderFrameHostImpl* frame_host = entry.second->frame_host_; if (!frame_host) continue; // Do not skip the nodes if they're about to get attached. - if (!entry.second->IsAttached() && - (!new_rfh || entry.first != new_rfh->frame_tree_node())) { + if (!entry.second->IsAttached() && entry.first != rfh->frame_tree_node()) { continue; } RenderProcessHost* process_host = frame_host->GetProcess(); - if (process_host == old_rph) - old_process_origins.insert(frame_host->GetLastCommittedOrigin()); - else if (process_host == new_rph) - new_process_origins.insert(frame_host->GetLastCommittedOrigin()); + if (process_host == rph) + process_origins.insert(frame_host->GetLastCommittedOrigin()); } - if (old_rph) { - GetNetworkService()->SetRawHeadersAccess( - old_rph->GetID(), std::vector<url::Origin>(old_process_origins.begin(), - old_process_origins.end())); - } - if (new_rph) { - GetNetworkService()->SetRawHeadersAccess( - new_rph->GetID(), std::vector<url::Origin>(new_process_origins.begin(), - new_process_origins.end())); - } + GetNetworkService()->SetRawHeadersAccess( + rph->GetID(), + std::vector<url::Origin>(process_origins.begin(), process_origins.end())); } RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost( @@ -361,7 +348,7 @@ if (!CompositorImpl::IsInitialized()) frame_trace_recorder_ = std::make_unique<DevToolsFrameTraceRecorder>(); #endif - UpdateRawHeadersAccess(nullptr, frame_host_); + UpdateRawHeadersAccess(frame_host_); #if defined(OS_ANDROID) if (acquire_wake_lock) GetWakeLock()->RequestWakeLock(); @@ -376,7 +363,7 @@ #if defined(OS_ANDROID) frame_trace_recorder_.reset(); #endif - UpdateRawHeadersAccess(frame_host_, nullptr); + UpdateRawHeadersAccess(frame_host_); #if defined(OS_ANDROID) GetWakeLock()->CancelWakeLock(); #endif @@ -442,6 +429,9 @@ if (request->HasCommitted()) NotifyNavigated(); + if (IsAttached()) { + UpdateRawHeadersAccess(frame_tree_node_->current_frame_host()); + } // UpdateFrameHost may destruct |this|. scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); UpdateFrameHost(frame_tree_node_->current_frame_host()); @@ -471,7 +461,7 @@ RenderFrameHostImpl* old_host = frame_host_; ChangeFrameHostAndObservedProcess(frame_host); if (IsAttached()) - UpdateRawHeadersAccess(old_host, frame_host); + UpdateRawHeadersAccess(old_host); std::vector<DevToolsSession*> restricted_sessions; for (DevToolsSession* session : sessions()) { @@ -528,7 +518,7 @@ scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); if (IsAttached()) { ForceDetachAllSessions(); - UpdateRawHeadersAccess(frame_host_, nullptr); + UpdateRawHeadersAccess(frame_host_); } ChangeFrameHostAndObservedProcess(nullptr); UpdateRendererChannel(IsAttached());
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h index 3da0330..16e54b6 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.h +++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -116,8 +116,7 @@ private: friend class DevToolsAgentHost; - static void UpdateRawHeadersAccess(RenderFrameHostImpl* old_rfh, - RenderFrameHostImpl* new_rfh); + static void UpdateRawHeadersAccess(RenderFrameHostImpl* rfh); RenderFrameDevToolsAgentHost(FrameTreeNode*, RenderFrameHostImpl*); ~RenderFrameDevToolsAgentHost() override;
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc index e2c4faa..91aee39b 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper.cc +++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -22,6 +22,7 @@ #include "components/services/storage/dom_storage/local_storage_impl.h" #include "components/services/storage/dom_storage/session_storage_impl.h" #include "components/services/storage/public/mojom/partition.mojom.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "components/services/storage/public/mojom/storage_usage_info.mojom.h" #include "content/browser/dom_storage/session_storage_namespace_impl.h" #include "content/browser/storage_partition_impl.h" @@ -68,66 +69,28 @@ } // namespace -class DOMStorageContextWrapper::StoragePolicyObserver - : public storage::SpecialStoragePolicy::Observer { - public: - explicit StoragePolicyObserver( - scoped_refptr<storage::SpecialStoragePolicy> storage_policy, - scoped_refptr<DOMStorageContextWrapper> context_wrapper) - : storage_policy_(std::move(storage_policy)), - context_wrapper_(std::move(context_wrapper)) { - storage_policy_->AddObserver(this); - } - - StoragePolicyObserver(const StoragePolicyObserver&) = delete; - StoragePolicyObserver& operator=(const StoragePolicyObserver&) = delete; - - ~StoragePolicyObserver() override { - DCHECK(!context_wrapper_); - storage_policy_->RemoveObserver(this); - } - - void DidShutdownContextWrapper() { context_wrapper_.reset(); } - - private: - // storage::SpecialStoragePolicy::Observer: - void OnPolicyChanged() override { - if (!context_wrapper_) - return; - - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&DOMStorageContextWrapper::OnStoragePolicyChanged, - context_wrapper_)); - } - - const scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; - scoped_refptr<DOMStorageContextWrapper> context_wrapper_; -}; - scoped_refptr<DOMStorageContextWrapper> DOMStorageContextWrapper::Create( StoragePartitionImpl* partition, - storage::SpecialStoragePolicy* special_storage_policy) { - auto wrapper = base::WrapRefCounted( - new DOMStorageContextWrapper(partition, special_storage_policy)); + scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy) { + auto wrapper = base::MakeRefCounted<DOMStorageContextWrapper>(partition); if (special_storage_policy) { - // If there's a SpecialStoragePolicy, ensure the wrapper is observing it on - // the IO thread and query the initial set of in-use origins ASAP. - wrapper->storage_policy_observer_ = - base::SequenceBound<StoragePolicyObserver>( - base::CreateSequencedTaskRunner(BrowserThread::IO), - base::WrapRefCounted(special_storage_policy), wrapper); - - wrapper->local_storage_control_->GetUsage(base::BindOnce( - &DOMStorageContextWrapper::OnStartupUsageRetrieved, wrapper)); + wrapper->storage_policy_observer_.emplace( + // `storage_policy_observer_` is owned by `wrapper` and so it is safe + // to use base::Unretained here. + base::BindRepeating(&DOMStorageContextWrapper::ApplyPolicyUpdates, + base::Unretained(wrapper.get())), + base::CreateSequencedTaskRunner(BrowserThread::IO), + std::move(special_storage_policy)); } + + wrapper->local_storage_control_->GetUsage(base::BindOnce( + &DOMStorageContextWrapper::OnStartupUsageRetrieved, wrapper)); return wrapper; } DOMStorageContextWrapper::DOMStorageContextWrapper( - StoragePartitionImpl* partition, - storage::SpecialStoragePolicy* special_storage_policy) - : partition_(partition), storage_policy_(special_storage_policy) { + StoragePartitionImpl* partition) + : partition_(partition) { memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>( FROM_HERE, base::BindRepeating(&DOMStorageContextWrapper::OnMemoryPressure, @@ -262,11 +225,8 @@ local_storage_control_.reset(); memory_pressure_listener_.reset(); - if (storage_policy_observer_) { - // Make sure the observer drops its reference to |this|. - storage_policy_observer_.Post( - FROM_HERE, &StoragePolicyObserver::DidShutdownContextWrapper); - } + // Make sure the observer drops its reference to |this|. + storage_policy_observer_.reset(); } void DOMStorageContextWrapper::Flush() { @@ -281,10 +241,8 @@ mojo::PendingReceiver<blink::mojom::StorageArea> receiver) { DCHECK(local_storage_control_); local_storage_control_->BindStorageArea(origin, std::move(receiver)); - if (storage_policy_) { - EnsureLocalStorageOriginIsTracked(origin); - OnStoragePolicyChanged(); - } + if (storage_policy_observer_) + storage_policy_observer_->StartTrackingOrigin(origin); } void DOMStorageContextWrapper::BindNamespace( @@ -391,47 +349,19 @@ void DOMStorageContextWrapper::OnStartupUsageRetrieved( std::vector<storage::mojom::StorageUsageInfoPtr> usage) { - for (const auto& info : usage) - EnsureLocalStorageOriginIsTracked(info->origin); - OnStoragePolicyChanged(); + for (const auto& info : usage) { + if (storage_policy_observer_) + storage_policy_observer_->StartTrackingOrigin(info->origin); + } } -void DOMStorageContextWrapper::EnsureLocalStorageOriginIsTracked( - const url::Origin& origin) { - DCHECK(storage_policy_); - auto it = local_storage_origins_.find(origin); - if (it == local_storage_origins_.end()) - local_storage_origins_[origin] = {}; -} - -void DOMStorageContextWrapper::OnStoragePolicyChanged() { +void DOMStorageContextWrapper::ApplyPolicyUpdates( + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates) { if (!local_storage_control_) return; - // Scan for any relevant changes to policy regarding origins we know we're - // managing. - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates; - for (auto& entry : local_storage_origins_) { - const url::Origin& origin = entry.first; - LocalStorageOriginState& state = entry.second; - state.should_purge_on_shutdown = ShouldPurgeLocalStorageOnShutdown(origin); - if (state.should_purge_on_shutdown != state.will_purge_on_shutdown) { - state.will_purge_on_shutdown = state.should_purge_on_shutdown; - policy_updates.push_back(storage::mojom::LocalStoragePolicyUpdate::New( - origin, state.should_purge_on_shutdown)); - } - } - if (!policy_updates.empty()) local_storage_control_->ApplyPolicyUpdates(std::move(policy_updates)); } -bool DOMStorageContextWrapper::ShouldPurgeLocalStorageOnShutdown( - const url::Origin& origin) { - if (!storage_policy_) - return false; - return storage_policy_->IsStorageSessionOnly(origin.GetURL()) && - !storage_policy_->IsStorageProtected(origin.GetURL()); -} - } // namespace content
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h index d99241a..17fb303 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper.h +++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -25,6 +25,7 @@ #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include "storage/browser/quota/storage_policy_observer.h" #include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h" #include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h" @@ -63,11 +64,9 @@ static scoped_refptr<DOMStorageContextWrapper> Create( StoragePartitionImpl* partition, - storage::SpecialStoragePolicy* special_storage_policy); + scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy); - DOMStorageContextWrapper( - StoragePartitionImpl* partition, - storage::SpecialStoragePolicy* special_storage_policy); + explicit DOMStorageContextWrapper(StoragePartitionImpl* partition); storage::mojom::SessionStorageControl* GetSessionStorageControl(); storage::mojom::LocalStorageControl* GetLocalStorageControl(); @@ -142,9 +141,8 @@ void OnStartupUsageRetrieved( std::vector<storage::mojom::StorageUsageInfoPtr> usage); - void EnsureLocalStorageOriginIsTracked(const url::Origin& origin); - void OnStoragePolicyChanged(); - bool ShouldPurgeLocalStorageOnShutdown(const url::Origin& origin); + void ApplyPolicyUpdates( + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates); // Since the tab restore code keeps a reference to the session namespaces // of recently closed tabs (see sessions::ContentPlatformSpecificTabData and @@ -173,29 +171,7 @@ mojo::Remote<storage::mojom::SessionStorageControl> session_storage_control_; mojo::Remote<storage::mojom::LocalStorageControl> local_storage_control_; - const scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; - - // This wrapper generally lives on the UI thread, but must observe the - // BrowserContext's SpecialStoragePolicy from the IO thread. This helper does - // that. - class StoragePolicyObserver; - base::SequenceBound<StoragePolicyObserver> storage_policy_observer_; - - // Tracks the total set of origins which may currently have Local Storage data - // in this partition. This set is synchronized on startup of Local Storage and - // maintained as new storage areas are bound. This mapping is used to - // efficiently deduce what policy changes to push to the Local Storage - // implementation any time a SpecialStoragePolicy change is observed. - struct LocalStorageOriginState { - // Indicates that storage for this origin should be purged on shutdown. - bool should_purge_on_shutdown = false; - - // Indicates the last value for |purge_on_shutdown| communicated to the - // Local Storage implementation. - bool will_purge_on_shutdown = false; - }; - // NOTE: The GURL key is specifically an origin GURL. - std::map<url::Origin, LocalStorageOriginState> local_storage_origins_; + base::Optional<storage::StoragePolicyObserver> storage_policy_observer_; DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageContextWrapper); };
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper_unittest.cc b/content/browser/dom_storage/dom_storage_context_wrapper_unittest.cc index 5eeed64..97423e37 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper_unittest.cc +++ b/content/browser/dom_storage/dom_storage_context_wrapper_unittest.cc
@@ -28,8 +28,8 @@ DOMStorageContextWrapperTest() = default; void SetUp() override { - context_ = new DOMStorageContextWrapper( - /*partition=*/nullptr, /*special_storage_policy=*/nullptr); + context_ = base::MakeRefCounted<DOMStorageContextWrapper>( + /*partition=*/nullptr); auto* security_policy = ChildProcessSecurityPolicyImpl::GetInstance(); security_policy->Add(kTestProcessIdOrigin1, &browser_context_);
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index fd11db5..b538e46 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -446,13 +446,12 @@ } void IndexedDBContextImpl::ApplyPolicyUpdates( - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> - policy_updates) { + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates) { idb_task_runner_->PostTask( FROM_HERE, base::BindOnce( [](IndexedDBContextImpl* context, - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates) { for (const auto& update : policy_updates) { if (!update->purge_on_shutdown)
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index 752f9f0..f22d963e 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -23,6 +23,7 @@ #include "components/services/storage/public/mojom/file_system_access_context.mojom.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom.h" #include "components/services/storage/public/mojom/indexed_db_control_test.mojom.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -91,9 +92,8 @@ DownloadOriginDataCallback callback) override; void GetAllOriginsDetails(GetAllOriginsDetailsCallback callback) override; void SetForceKeepSessionState() override; - void ApplyPolicyUpdates( - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> - policy_updates) override; + void ApplyPolicyUpdates(std::vector<storage::mojom::StoragePolicyUpdatePtr> + policy_updates) override; void BindTestInterface( mojo::PendingReceiver<storage::mojom::IndexedDBControlTest> receiver) override;
diff --git a/content/browser/indexed_db/indexed_db_control_wrapper.cc b/content/browser/indexed_db/indexed_db_control_wrapper.cc index 55b4c83..08b8c73b 100644 --- a/content/browser/indexed_db/indexed_db_control_wrapper.cc +++ b/content/browser/indexed_db/indexed_db_control_wrapper.cc
@@ -10,39 +10,6 @@ namespace content { -// Observer for the SpecialStoragePolicy on the IO thread. -class IndexedDBControlWrapper::StoragePolicyObserver - : public storage::SpecialStoragePolicy::Observer { - public: - explicit StoragePolicyObserver( - scoped_refptr<base::SequencedTaskRunner> reply_task_runner, - scoped_refptr<storage::SpecialStoragePolicy> storage_policy, - base::WeakPtr<IndexedDBControlWrapper> control_wrapper) - : reply_task_runner_(std::move(reply_task_runner)), - storage_policy_(std::move(storage_policy)), - control_wrapper_(std::move(control_wrapper)) { - storage_policy_->AddObserver(this); - } - - ~StoragePolicyObserver() override { storage_policy_->RemoveObserver(this); } - - // storage::SpecialStoragePolicy::Observer implementation: - void OnPolicyChanged() override { - reply_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&IndexedDBControlWrapper::OnSpecialStoragePolicyChanged, - control_wrapper_)); - } - - private: - scoped_refptr<base::SequencedTaskRunner> reply_task_runner_; - scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; - - // control_wrapper_ is bound to the reply_task_runner sequence, - // so should not be checked other than on that sequence. - base::WeakPtr<IndexedDBControlWrapper> control_wrapper_; -}; - IndexedDBControlWrapper::IndexedDBControlWrapper( const base::FilePath& data_path, scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy, @@ -53,18 +20,18 @@ mojo::PendingRemote<storage::mojom::FileSystemAccessContext> file_system_access_context, scoped_refptr<base::SequencedTaskRunner> io_task_runner, - scoped_refptr<base::SequencedTaskRunner> custom_task_runner) - : special_storage_policy_(std::move(special_storage_policy)) { + scoped_refptr<base::SequencedTaskRunner> custom_task_runner) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); context_ = base::MakeRefCounted<IndexedDBContextImpl>( data_path, std::move(quota_manager_proxy), clock, std::move(blob_storage_context), std::move(file_system_access_context), io_task_runner, std::move(custom_task_runner)); - if (special_storage_policy_) { - storage_policy_observer_ = base::SequenceBound<StoragePolicyObserver>( - io_task_runner, base::SequencedTaskRunnerHandle::Get(), - special_storage_policy_, weak_factory_.GetWeakPtr()); + if (special_storage_policy) { + storage_policy_observer_.emplace( + base::BindRepeating(&IndexedDBControlWrapper::ApplyPolicyUpdates, + weak_factory_.GetWeakPtr()), + io_task_runner, std::move(special_storage_policy)); } } @@ -80,7 +47,8 @@ mojo::PendingReceiver<blink::mojom::IDBFactory> receiver) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); BindRemoteIfNeeded(); - TrackOriginPolicyState(origin); + if (storage_policy_observer_) + storage_policy_observer_->StartTrackingOrigin(origin); indexed_db_control_->BindIndexedDB(origin, std::move(receiver)); } @@ -137,8 +105,7 @@ } void IndexedDBControlWrapper::ApplyPolicyUpdates( - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> - policy_updates) { + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); BindRemoteIfNeeded(); indexed_db_control_->ApplyPolicyUpdates(std::move(policy_updates)); @@ -158,48 +125,6 @@ indexed_db_control_->AddObserver(std::move(observer)); } -void IndexedDBControlWrapper::OnSpecialStoragePolicyChanged() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - BindRemoteIfNeeded(); - - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> policy_updates; - for (auto& entry : origin_state_) { - const GURL& origin = entry.first; - OriginState& state = entry.second; - state.should_purge_on_shutdown = ShouldPurgeOnShutdown(origin); - - if (state.should_purge_on_shutdown != state.will_purge_on_shutdown) { - state.will_purge_on_shutdown = state.should_purge_on_shutdown; - policy_updates.push_back( - storage::mojom::IndexedDBStoragePolicyUpdate::New( - url::Origin::Create(origin), state.should_purge_on_shutdown)); - } - } - if (!policy_updates.empty()) - ApplyPolicyUpdates(std::move(policy_updates)); -} - -void IndexedDBControlWrapper::TrackOriginPolicyState( - const url::Origin& origin) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const GURL origin_url = GURL(origin.Serialize()); - auto it = origin_state_.find(origin_url); - if (it == origin_state_.end()) - origin_state_[origin_url] = {}; - OnSpecialStoragePolicyChanged(); -} - -bool IndexedDBControlWrapper::ShouldPurgeOnShutdown(const GURL& origin) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!special_storage_policy_) - return false; - if (!special_storage_policy_->IsStorageSessionOnly(origin)) - return false; - if (special_storage_policy_->IsStorageProtected(origin)) - return false; - return true; -} - void IndexedDBControlWrapper::BindRemoteIfNeeded() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(
diff --git a/content/browser/indexed_db/indexed_db_control_wrapper.h b/content/browser/indexed_db/indexed_db_control_wrapper.h index 6e03757..8cd1b9e 100644 --- a/content/browser/indexed_db/indexed_db_control_wrapper.h +++ b/content/browser/indexed_db/indexed_db_control_wrapper.h
@@ -7,7 +7,9 @@ #include "base/threading/sequence_bound.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" +#include "storage/browser/quota/storage_policy_observer.h" namespace content { @@ -44,9 +46,8 @@ DownloadOriginDataCallback callback) override; void GetAllOriginsDetails(GetAllOriginsDetailsCallback callback) override; void SetForceKeepSessionState() override; - void ApplyPolicyUpdates( - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> - policy_updates) override; + void ApplyPolicyUpdates(std::vector<storage::mojom::StoragePolicyUpdatePtr> + policy_updates) override; void BindTestInterface( mojo::PendingReceiver<storage::mojom::IndexedDBControlTest> receiver) override; @@ -57,33 +58,13 @@ IndexedDBContextImpl* GetIndexedDBContextInternal() { return context_.get(); } private: - void OnSpecialStoragePolicyChanged(); - void TrackOriginPolicyState(const url::Origin& origin); - bool ShouldPurgeOnShutdown(const GURL& origin); void BindRemoteIfNeeded(); - // Special storage policy may be null. - scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; - - // Observer for the SpecialStoragePolicy on the IO thread. May be null. - class StoragePolicyObserver; - base::SequenceBound<StoragePolicyObserver> storage_policy_observer_; + base::Optional<storage::StoragePolicyObserver> storage_policy_observer_; mojo::Remote<storage::mojom::IndexedDBControl> indexed_db_control_; scoped_refptr<IndexedDBContextImpl> context_; - struct OriginState { - // Indicates that storage for this origin should be purged on shutdown. - bool should_purge_on_shutdown = false; - // Indicates the last value for |purge_on_shutdown| communicated to the - // IndexedDB implementation. - bool will_purge_on_shutdown = false; - }; - // NOTE: The GURL key is specifically an origin GURL. - // Special storage policy uses GURLs and not Origins, so it's simpler - // to store everything in GURL form. - std::map<GURL, OriginState> origin_state_; - SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<IndexedDBControlWrapper> weak_factory_{this};
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index 005f44b..cf366aa9 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -97,9 +97,9 @@ /*file_system_access_context=*/mojo::NullRemote(), base::SequencedTaskRunnerHandle::Get(), base::SequencedTaskRunnerHandle::Get())) { - std::vector<storage::mojom::IndexedDBStoragePolicyUpdatePtr> policy_updates; + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates; bool should_purge_on_shutdown = true; - policy_updates.push_back(storage::mojom::IndexedDBStoragePolicyUpdate::New( + policy_updates.emplace_back(storage::mojom::StoragePolicyUpdate::New( kSessionOnlyOrigin, should_purge_on_shutdown)); context_->ApplyPolicyUpdates(std::move(policy_updates)); }
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index fa81abd..7cd03038 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc
@@ -497,40 +497,6 @@ TestRenderFrameHostPrerenderingState(GetUrl("/page_with_blank_iframe.html")); } -// Tests that prerendering pages can access cookies. -IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, RestrictedCookieAccess) { - const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html"); - const GURL kPrerenderingUrl = GetUrl("/empty.html"); - // Navigate to an initial page. - ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); - // Set a cookie to the origin. - const std::string initial_cookie = "initial_cookie=exist"; - const std::string prerender_cookie = "prerender_cookie=exist"; - EvalJsResult result = - EvalJs(shell()->web_contents(), - "document.cookie='" + initial_cookie + "; path=/'"); - EXPECT_TRUE(result.error.empty()) << result.error; - - // Make a prerendered page. - AddPrerender(kPrerenderingUrl); - PrerenderHostRegistry& registry = GetPrerenderHostRegistry(); - PrerenderHost* prerender_host = - registry.FindHostByUrlForTesting(kPrerenderingUrl); - ASSERT_TRUE(prerender_host); - WebContents* prerender_contents = WebContents::FromRenderFrameHost( - prerender_host->GetPrerenderedMainFrameHostForTesting()); - - // Verify the prerendered page can read the cookie. - EXPECT_EQ(initial_cookie, EvalJs(prerender_contents, "document.cookie")); - - // Verify the prerendered page can update cookies. - EvalJsResult prerender_result = EvalJs( - prerender_contents, "document.cookie='" + prerender_cookie + "; path=/'"); - EXPECT_TRUE(prerender_result.error.empty()) << prerender_result.error; - // Read the updated cookie from the initial page. - EXPECT_EQ(initial_cookie + "; " + prerender_cookie, - EvalJs(shell()->web_contents(), "document.cookie")); -} class MojoCapabilityControlTestContentBrowserClient : public TestContentBrowserClient, @@ -734,6 +700,8 @@ // Tests for feature restrictions in prerendered pages ========================= +// - Tests for feature-specific code methodology restrictions ================== + // Tests that window.open() in a prerendering page fails. IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, FeatureRestriction_WindowOpen) { // Navigate to an initial page. @@ -789,5 +757,82 @@ EXPECT_TRUE(base::Contains(client_urls, kPrerenderingUrl)); } +// - Tests for Mojo capability control methodology restrictions ================ + +// Tests that prerendering pages can access cookies. +IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, CookieAccess) { + const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html"); + const GURL kPrerenderingUrl = GetUrl("/empty.html"); + // Navigate to an initial page. + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + // Set a cookie to the origin. + const std::string initial_cookie = "initial_cookie=exist"; + const std::string prerender_cookie = "prerender_cookie=exist"; + EvalJsResult result = + EvalJs(shell()->web_contents(), + "document.cookie='" + initial_cookie + "; path=/'"); + EXPECT_TRUE(result.error.empty()) << result.error; + + // Make a prerendered page. + AddPrerender(kPrerenderingUrl); + PrerenderHostRegistry& registry = GetPrerenderHostRegistry(); + PrerenderHost* prerender_host = + registry.FindHostByUrlForTesting(kPrerenderingUrl); + ASSERT_TRUE(prerender_host); + WebContents* prerender_contents = WebContents::FromRenderFrameHost( + prerender_host->GetPrerenderedMainFrameHostForTesting()); + + // Verify the prerendered page can read the cookie. + EXPECT_EQ(initial_cookie, EvalJs(prerender_contents, "document.cookie")); + + // Verify the prerendered page can update cookies. + EvalJsResult prerender_result = EvalJs( + prerender_contents, "document.cookie='" + prerender_cookie + "; path=/'"); + EXPECT_TRUE(prerender_result.error.empty()) << prerender_result.error; + // Read the updated cookie from the initial page. + EXPECT_EQ(initial_cookie + "; " + prerender_cookie, + EvalJs(shell()->web_contents(), "document.cookie")); +} + +// Tests that prerendering pages can access local storage. +IN_PROC_BROWSER_TEST_P(PrerenderBrowserTest, LocalStorageAccess) { + const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html"); + const GURL kPrerenderingUrl = GetUrl("/empty.html"); + // Navigate to an initial page. + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + // Add an item to local storage from the initial page. + const std::string key = "set_by"; + const std::string initial_value = "initial"; + const std::string prerender_value = "prerender"; + EvalJsResult result = EvalJs( + shell()->web_contents(), + JsReplace("window.localStorage.setItem($1, $2)", key, initial_value)); + EXPECT_TRUE(result.error.empty()) << result.error; + + // Make a prerendered page. + AddPrerender(kPrerenderingUrl); + PrerenderHostRegistry& registry = GetPrerenderHostRegistry(); + PrerenderHost* prerender_host = + registry.FindHostByUrlForTesting(kPrerenderingUrl); + ASSERT_TRUE(prerender_host); + WebContents* prerender_contents = WebContents::FromRenderFrameHost( + prerender_host->GetPrerenderedMainFrameHostForTesting()); + + // Verify the prerendered page can read the item that the initial page wrote. + EXPECT_EQ(initial_value, + EvalJs(prerender_contents, + JsReplace("window.localStorage.getItem($1)", key))); + + // Verify the prerendered page can update local storage. + EvalJsResult prerender_result = EvalJs( + prerender_contents, + JsReplace("window.localStorage.setItem($1, $2)", key, prerender_value)); + EXPECT_TRUE(prerender_result.error.empty()) << prerender_result.error; + // Read the updated item value from the initial page. + EXPECT_EQ(prerender_value, + EvalJs(shell()->web_contents(), + JsReplace("window.localStorage.getItem($1)", key))); +} + } // namespace } // namespace content
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index e790010..cb3d685 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -1826,11 +1826,8 @@ network::mojom::ContentSecurityPolicyPtr csp) { DCHECK(!required_csp_); required_csp_ = std::move(csp); - if (required_csp_) { - const std::string& header_value = required_csp_->header->header_value; - DCHECK(net::HttpUtil::IsValidHeaderValue(header_value)); - SetRequestHeader("Sec-Required-CSP", header_value); - } + if (required_csp_) + SetRequestHeader("Sec-Required-CSP", required_csp_->header->header_value); } network::mojom::ContentSecurityPolicyPtr NavigationRequest::TakeRequiredCSP() {
diff --git a/content/browser/renderer_host/navigation_request_unittest.cc b/content/browser/renderer_host/navigation_request_unittest.cc index b442d10..77a898c 100644 --- a/content/browser/renderer_host/navigation_request_unittest.cc +++ b/content/browser/renderer_host/navigation_request_unittest.cc
@@ -780,7 +780,7 @@ NavigateWithRequiredCSP(&child_document, "script-src 'none'"); TestRenderFrameHost* grand_child_document = AddChild(child_document); std::string sec_required_csp = - NavigateWithRequiredCSP(&grand_child_document, "invalid-directive"); + NavigateWithRequiredCSP(&grand_child_document, "report-to group"); EXPECT_EQ("script-src 'none'", sec_required_csp); EXPECT_TRUE(grand_child_document->required_csp()); EXPECT_EQ("script-src 'none'", @@ -794,7 +794,7 @@ NavigateWithRequiredCSP(&child_document, "script-src 'none'"); TestRenderFrameHost* grand_child_document = AddChild(child_document); std::string sec_required_csp = NavigateWithRequiredCSP( - &grand_child_document, "script-src 'none'; invalid-directive"); + &grand_child_document, "script-src 'none'; report-to group"); EXPECT_EQ("script-src 'none'", sec_required_csp); EXPECT_TRUE(grand_child_document->required_csp()); EXPECT_EQ("script-src 'none'", @@ -808,7 +808,7 @@ NavigateWithRequiredCSP(&child_document, "script-src 'none'"); TestRenderFrameHost* grand_child_document = AddChild(child_document); std::string sec_required_csp = NavigateWithRequiredCSP( - &grand_child_document, "sandbox; invalid-directive"); + &grand_child_document, "sandbox; report-to group"); EXPECT_EQ("script-src 'none'", sec_required_csp); EXPECT_TRUE(grand_child_document->required_csp()); EXPECT_EQ("script-src 'none'",
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 801245a..f6b9292 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -811,6 +811,16 @@ kMaxValue = kGesture, }; +bool ValidateCSPAttribute(const std::string& value) { + if (!base::IsStringASCII(value)) + return false; + if (value.find('\n') != std::string::npos || + value.find('\r') != std::string::npos) { + return false; + } + return true; +} + } // namespace #if BUILDFLAG(ENABLE_PLUGINS) @@ -5070,6 +5080,13 @@ void RenderFrameHostImpl::DidChangeCSPAttribute( const base::UnguessableToken& child_frame_token, network::mojom::ContentSecurityPolicyPtr parsed_csp_attribute) { + if (parsed_csp_attribute && + !ValidateCSPAttribute(parsed_csp_attribute->header->header_value)) { + bad_message::ReceivedBadMessage(GetProcess(), + bad_message::RFH_CSP_ATTRIBUTE); + return; + } + auto* child = FindAndVerifyChild(child_frame_token, bad_message::RFH_CSP_ATTRIBUTE); if (!child)
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 98fe575..d437259 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -40,6 +40,9 @@ #include "cc/base/switches.h" #include "cc/trees/browser_controls_params.h" #include "cc/trees/render_frame_metadata.h" +#include "components/power_scheduler/power_mode.h" +#include "components/power_scheduler/power_mode_arbiter.h" +#include "components/power_scheduler/power_mode_voter.h" #include "components/viz/common/features.h" #include "components/viz/host/host_frame_sink_manager.h" #include "content/browser/accessibility/browser_accessibility_manager.h" @@ -383,7 +386,13 @@ frame_token_message_queue_.get()), frame_sink_id_(base::checked_cast<uint32_t>( agent_scheduling_group.GetProcess()->GetID()), - base::checked_cast<uint32_t>(routing_id_)) { + base::checked_cast<uint32_t>(routing_id_)), + power_mode_input_voter_( + power_scheduler::PowerModeArbiter::GetInstance()->NewVoter( + "PowerModeVoter.Input")), + power_mode_loading_voter_( + power_scheduler::PowerModeArbiter::GetInstance()->NewVoter( + "PowerModeVoter.Loading")) { DCHECK(frame_token_message_queue_); frame_token_message_queue_->Init(this); @@ -714,6 +723,9 @@ void RenderWidgetHostImpl::SetIsLoading(bool is_loading) { is_loading_ = is_loading; + power_mode_loading_voter_->VoteFor(is_loading_ + ? power_scheduler::PowerMode::kLoading + : power_scheduler::PowerMode::kIdle); if (view_) view_->SetIsLoading(is_loading); } @@ -2866,6 +2878,8 @@ void RenderWidgetHostImpl::IncrementInFlightEventCount() { ++in_flight_event_count_; + if (in_flight_event_count_ == 1) + power_mode_input_voter_->VoteFor(power_scheduler::PowerMode::kResponse); if (!is_hidden_) StartInputEventAckTimeout(); } @@ -2876,6 +2890,8 @@ if (in_flight_event_count_ <= 0) { // Cancel pending hung renderer checks since the renderer is responsive. StopInputEventAckTimeout(); + power_mode_input_voter_->ResetVoteAfterTimeout( + power_scheduler::PowerModeVoter::kResponseTimeout); } else { // Only restart the hang monitor timer if we got a response from the // main thread.
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index a4bcbee..4ecd272b 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -33,6 +33,7 @@ #include "base/timer/timer.h" #include "build/build_config.h" #include "cc/mojom/render_frame_metadata.mojom.h" +#include "components/power_scheduler/power_mode_voter.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/frame_token_message_queue.h" @@ -1383,6 +1384,9 @@ mojo::Remote<blink::mojom::WidgetCompositor> widget_compositor_; + std::unique_ptr<power_scheduler::PowerModeVoter> power_mode_input_voter_; + std::unique_ptr<power_scheduler::PowerModeVoter> power_mode_loading_voter_; + base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index dea076d..95f11d52 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "components/services/storage/service_worker/service_worker_storage.h" #include "components/services/storage/service_worker/service_worker_storage_control_impl.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" @@ -219,9 +218,7 @@ mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl> receiver) { storage_control_ = std::make_unique<storage::ServiceWorkerStorageControlImpl>( - storage::ServiceWorkerStorage::Create(user_data_directory_, - database_task_runner_)); - storage_control_->Bind(std::move(receiver)); + user_data_directory_, database_task_runner_, std::move(receiver)); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 25c46b24..3ebb6517 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -24,7 +24,6 @@ #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/thread_task_runner_handle.h" -#include "components/services/storage/service_worker/service_worker_storage.h" #include "components/services/storage/service_worker/service_worker_storage_control_impl.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/navigation_url_loader_impl.h" @@ -1612,9 +1611,8 @@ {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); storage_control_ = std::make_unique<storage::ServiceWorkerStorageControlImpl>( - storage::ServiceWorkerStorage::Create( - user_data_directory_, std::move(database_task_runner))); - storage_control_->Bind(std::move(receiver)); + user_data_directory_, std::move(database_task_runner), + std::move(receiver)); } }
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc index 3bcc8e7..e026bb53 100644 --- a/content/browser/service_worker/service_worker_registry.cc +++ b/content/browser/service_worker/service_worker_registry.cc
@@ -12,7 +12,7 @@ #include "base/stl_util.h" #include "base/task/post_task.h" #include "base/trace_event/trace_event.h" -#include "components/services/storage/public/mojom/local_storage_control.mojom.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_info.h" @@ -184,7 +184,7 @@ : public ServiceWorkerRegistry::InflightCall { public: InflightCallApplyPolicyUpdates( - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates, + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates, base::RepeatingCallback< void(storage::mojom::ServiceWorkerDatabaseStatus status)> callback) : policy_updates_(std::move(policy_updates)), @@ -194,8 +194,7 @@ void Run(ServiceWorkerRegistry* registry) override { DCHECK(registry); DCHECK(registry->GetRemoteStorageControl().is_connected()); - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> - passed_policy_updates; + std::vector<storage::mojom::StoragePolicyUpdatePtr> passed_policy_updates; for (const auto& entry : policy_updates_) passed_policy_updates.push_back(entry.Clone()); @@ -204,48 +203,12 @@ } private: - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates_; + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates_; base::RepeatingCallback<void( storage::mojom::ServiceWorkerDatabaseStatus status)> callback_; }; -// A helper class that runs on the IO thread to observe storage policy updates. -class ServiceWorkerRegistry::StoragePolicyObserver - : public storage::SpecialStoragePolicy::Observer { - public: - StoragePolicyObserver( - base::WeakPtr<ServiceWorkerRegistry> owner, - scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy) - : owner_(owner), special_storage_policy_(special_storage_policy) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(special_storage_policy_); - special_storage_policy_->AddObserver(this); - } - - StoragePolicyObserver(const StoragePolicyObserver&) = delete; - StoragePolicyObserver& operator=(const StoragePolicyObserver&) = delete; - - ~StoragePolicyObserver() override { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - special_storage_policy_->RemoveObserver(this); - } - - private: - // storage::SpecialStoragePolicy::Observer: - void OnPolicyChanged() override { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&ServiceWorkerRegistry::OnStoragePolicyChanged, owner_)); - } - - // |owner_| is dereferenced on the UI thread. This shouldn't be dereferenced - // on the IO thread. - base::WeakPtr<ServiceWorkerRegistry> owner_; - const scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; -}; - ServiceWorkerRegistry::ServiceWorkerRegistry( ServiceWorkerContextCore* context, storage::QuotaManagerProxy* quota_manager_proxy, @@ -261,13 +224,9 @@ ServiceWorkerRegistry::ServiceWorkerRegistry( ServiceWorkerContextCore* context, ServiceWorkerRegistry* old_registry) - : context_(context), - quota_manager_proxy_(old_registry->quota_manager_proxy_), - special_storage_policy_(old_registry->special_storage_policy_) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(context_); - Start(); -} + : ServiceWorkerRegistry(context, + old_registry->quota_manager_proxy_.get(), + old_registry->special_storage_policy_.get()) {} ServiceWorkerRegistry::~ServiceWorkerRegistry() = default; @@ -820,16 +779,17 @@ void ServiceWorkerRegistry::Start() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (special_storage_policy_) { - storage_policy_observer_ = base::SequenceBound<StoragePolicyObserver>( - base::CreateSequencedTaskRunner(BrowserThread::IO), - weak_factory_.GetWeakPtr(), - base::WrapRefCounted(special_storage_policy_.get())); + if (!special_storage_policy_) + return; + storage_policy_observer_.emplace( + base::BindRepeating(&ServiceWorkerRegistry::ApplyPolicyUpdates, + weak_factory_.GetWeakPtr()), + base::CreateSequencedTaskRunner(BrowserThread::IO), + special_storage_policy_); - GetRegisteredOrigins( - base::BindOnce(&ServiceWorkerRegistry::DidGetRegisteredOriginsOnStartup, - weak_factory_.GetWeakPtr())); - } + GetRegisteredOrigins( + base::BindOnce(&ServiceWorkerRegistry::DidGetRegisteredOriginsOnStartup, + weak_factory_.GetWeakPtr())); } void ServiceWorkerRegistry::FindRegistrationForIdInternal( @@ -1309,10 +1269,8 @@ } context_->NotifyRegistrationStored(stored_registration_id, stored_scope); - if (special_storage_policy_) { - EnsureRegisteredOriginIsTracked(origin); - OnStoragePolicyChanged(); - } + if (storage_policy_observer_) + storage_policy_observer_->StartTrackingOrigin(origin); std::move(callback).Run(status); } @@ -1353,9 +1311,8 @@ storage::mojom::ServiceWorkerStorageOriginState::kDelete) { context_->NotifyAllRegistrationsDeletedForOrigin( url::Origin::Create(origin)); - if (special_storage_policy_) { - tracked_origins_for_policy_update_.erase(url::Origin::Create(origin)); - } + if (storage_policy_observer_) + storage_policy_observer_->StopTrackingOrigin(url::Origin::Create(origin)); } std::move(callback).Run(status); @@ -1573,51 +1530,34 @@ void ServiceWorkerRegistry::DidGetRegisteredOriginsOnStartup( const std::vector<url::Origin>& origins) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!special_storage_policy_) + return; for (const auto& origin : origins) - EnsureRegisteredOriginIsTracked(origin); - OnStoragePolicyChanged(); + storage_policy_observer_->StartTrackingOrigin(origin); } -void ServiceWorkerRegistry::EnsureRegisteredOriginIsTracked( - const url::Origin& origin) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto it = tracked_origins_for_policy_update_.find(origin); - if (it == tracked_origins_for_policy_update_.end()) - tracked_origins_for_policy_update_[origin] = {}; -} - -void ServiceWorkerRegistry::OnStoragePolicyChanged() { +void ServiceWorkerRegistry::ApplyPolicyUpdates( + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (is_storage_disabled_) return; + if (policy_updates.empty()) + return; - std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates; - for (auto& entry : tracked_origins_for_policy_update_) { - const url::Origin& origin = entry.first; - StorageOriginState& state = entry.second; - state.should_purge_on_shutdown = ShouldPurgeOnShutdown(origin); - if (state.should_purge_on_shutdown != state.will_purge_on_shutdown) { - state.will_purge_on_shutdown = state.should_purge_on_shutdown; - policy_updates.push_back(storage::mojom::LocalStoragePolicyUpdate::New( - origin, state.should_purge_on_shutdown)); - } - } - - if (!policy_updates.empty()) { - uint64_t call_id = GetNextCallId(); - auto call = std::make_unique<InflightCallApplyPolicyUpdates>( - std::move(policy_updates), - base::BindRepeating(&ServiceWorkerRegistry::DidApplyPolicyUpdates, - weak_factory_.GetWeakPtr(), call_id)); - StartRemoteCall(call_id, std::move(call)); - } + uint64_t call_id = GetNextCallId(); + auto call = std::make_unique<InflightCallApplyPolicyUpdates>( + std::move(policy_updates), + base::BindRepeating(&ServiceWorkerRegistry::DidApplyPolicyUpdates, + weak_factory_.GetWeakPtr(), call_id)); + StartRemoteCall(call_id, std::move(call)); } -bool ServiceWorkerRegistry::ShouldPurgeOnShutdown(const url::Origin& origin) { - if (!special_storage_policy_) +bool ServiceWorkerRegistry::ShouldPurgeOnShutdownForTesting( + const url::Origin& origin) { + if (!storage_policy_observer_) return false; - return special_storage_policy_->IsStorageSessionOnly(origin.GetURL()) && - !special_storage_policy_->IsStorageProtected(origin.GetURL()); + return storage_policy_observer_->ShouldPurgeOnShutdownForTesting( // IN-TEST + origin); } mojo::Remote<storage::mojom::ServiceWorkerStorageControl>&
diff --git a/content/browser/service_worker/service_worker_registry.h b/content/browser/service_worker/service_worker_registry.h index c631eba..6915680 100644 --- a/content/browser/service_worker/service_worker_registry.h +++ b/content/browser/service_worker/service_worker_registry.h
@@ -15,6 +15,7 @@ #include "content/browser/service_worker/service_worker_registration.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/remote.h" +#include "storage/browser/quota/storage_policy_observer.h" namespace storage { class QuotaManagerProxy; @@ -418,13 +419,11 @@ uint64_t call_id, storage::mojom::ServiceWorkerDatabaseStatus status); - // TODO(bashi): Consider introducing a helper class that handles the below. - // These are almost the same as DOMStorageContextWrapper. void DidGetRegisteredOriginsOnStartup( const std::vector<url::Origin>& origins); - void EnsureRegisteredOriginIsTracked(const url::Origin& origin); - void OnStoragePolicyChanged(); - bool ShouldPurgeOnShutdown(const url::Origin& origin); + void ApplyPolicyUpdates( + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates); + bool ShouldPurgeOnShutdownForTesting(const url::Origin& origin); void OnRemoteStorageDisconnected(); @@ -497,17 +496,7 @@ // ServiceWorkerStorage once QuotaManager gets mojofied. const scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_; const scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; - class StoragePolicyObserver; - base::SequenceBound<StoragePolicyObserver> storage_policy_observer_; - - // TODO(bashi): Avoid duplication. Merge this with LocalStorageOriginState. - struct StorageOriginState { - bool should_purge_on_shutdown = false; - bool will_purge_on_shutdown = false; - }; - // IMPORTANT: Don't use this other than updating storage policies. This can - // be out of sync with |registered_origins_| in ServiceWorkerStorage. - std::map<url::Origin, StorageOriginState> tracked_origins_for_policy_update_; + base::Optional<storage::StoragePolicyObserver> storage_policy_observer_; // For finding registrations being installed or uninstalled. using RegistrationRefsById =
diff --git a/content/browser/service_worker/service_worker_registry_unittest.cc b/content/browser/service_worker/service_worker_registry_unittest.cc index 34174a0..2932ca4 100644 --- a/content/browser/service_worker/service_worker_registry_unittest.cc +++ b/content/browser/service_worker/service_worker_registry_unittest.cc
@@ -1243,7 +1243,7 @@ ASSERT_EQ(StoreRegistration(registration, registration->waiting_version()), blink::ServiceWorkerStatusCode::kOk); - EXPECT_FALSE(registry()->ShouldPurgeOnShutdown(kOrigin)); + EXPECT_FALSE(registry()->ShouldPurgeOnShutdownForTesting(kOrigin)); { // Update storage policy to mark the origin should be purged on shutdown. @@ -1252,7 +1252,7 @@ base::RunLoop().RunUntilIdle(); } - EXPECT_TRUE(registry()->ShouldPurgeOnShutdown(kOrigin)); + EXPECT_TRUE(registry()->ShouldPurgeOnShutdownForTesting(kOrigin)); } // Tests that callbacks of storage operations are always called even when the @@ -1818,7 +1818,7 @@ ASSERT_EQ(StoreRegistration(registration, registration->waiting_version()), blink::ServiceWorkerStatusCode::kOk); - EXPECT_FALSE(registry()->ShouldPurgeOnShutdown(kOrigin)); + EXPECT_FALSE(registry()->ShouldPurgeOnShutdownForTesting(kOrigin)); // Update storage policy to mark the origin should be purged on shutdown. special_storage_policy()->AddSessionOnly(kOrigin.GetURL()); @@ -1830,7 +1830,7 @@ // All Mojo calls must be done at this point. EXPECT_EQ(inflight_call_count(), 0U); - EXPECT_TRUE(registry()->ShouldPurgeOnShutdown(kOrigin)); + EXPECT_TRUE(registry()->ShouldPurgeOnShutdownForTesting(kOrigin)); } // Regression test for https://crbug.com/1165784.
diff --git a/content/browser/webui/web_ui_main_frame_observer.cc b/content/browser/webui/web_ui_main_frame_observer.cc index aa698086..f578e8b 100644 --- a/content/browser/webui/web_ui_main_frame_observer.cc +++ b/content/browser/webui/web_ui_main_frame_observer.cc
@@ -119,6 +119,7 @@ report.message = base::UTF16ToUTF8(message); report.line_number = line_no; report.url = std::move(redacted_url); + report.source_system = JavaScriptErrorReport::SourceSystem::kWebUIObserver; if (untrusted_stack_trace) { report.stack_trace = base::UTF16ToUTF8(*untrusted_stack_trace); }
diff --git a/content/browser/webui/web_ui_main_frame_observer_unittest.cc b/content/browser/webui/web_ui_main_frame_observer_unittest.cc index 6678ef01..ea6b6cd 100644 --- a/content/browser/webui/web_ui_main_frame_observer_unittest.cc +++ b/content/browser/webui/web_ui_main_frame_observer_unittest.cc
@@ -188,6 +188,8 @@ EXPECT_EQ(processor_->error_report_count(), 1); EXPECT_EQ(processor_->last_error_report().message, kMessage8); EXPECT_EQ(processor_->last_error_report().url, kSourceURL8); + EXPECT_EQ(processor_->last_error_report().source_system, + JavaScriptErrorReport::SourceSystem::kWebUIObserver); EXPECT_THAT(processor_->last_error_report().stack_trace, Optional(Eq(kStackTrace8))); // WebUI should use default product & version.
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 73d8624..a9111c0 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -95,6 +95,7 @@ "input/input_event_ack_state.cc", "input/input_event_stream_validator.cc", "input/input_event_stream_validator.h", + "input/input_injector_mojom_traits.cc", "input/synthetic_gesture_params.cc", "input/synthetic_gesture_params.h", "input/synthetic_pinch_gesture_params.cc", @@ -539,6 +540,7 @@ traits_headers = [ "//cc/input/touch_action.h", + "//content/common/input/input_injector_mojom_traits.h", "//content/common/input/synthetic_pinch_gesture_params.h", "//content/common/input/synthetic_pointer_action_list_params.h", "//content/common/input/synthetic_smooth_drag_gesture_params.h",
diff --git a/content/common/input/input_injector.mojom b/content/common/input/input_injector.mojom index d43891c..83b8ba83 100644 --- a/content/common/input/input_injector.mojom +++ b/content/common/input/input_injector.mojom
@@ -5,6 +5,15 @@ module content.mojom; import "content/common/native_types.mojom"; +import "ui/gfx/geometry/mojom/geometry.mojom"; + +// The pinth parameters sent by the renderer to the browser, that are needed to +// queue the synthetic pinch. +struct SyntheticPinch { + float scale_factor; + gfx.mojom.PointF anchor; + float relative_pointer_speed_in_pixels_s; +}; // Host interface representing the ability to inject input // from a less priviledged application. Available when
diff --git a/content/common/input/input_injector_mojom_traits.cc b/content/common/input/input_injector_mojom_traits.cc new file mode 100644 index 0000000..c491544 --- /dev/null +++ b/content/common/input/input_injector_mojom_traits.cc
@@ -0,0 +1,23 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/input/input_injector_mojom_traits.h" + +namespace mojo { + +// static +bool StructTraits<content::mojom::SyntheticPinchDataView, + content::SyntheticPinchGestureParams>:: + Read(content::mojom::SyntheticPinchDataView data, + content::SyntheticPinchGestureParams* out) { + if (!data.ReadAnchor(&out->anchor)) + return false; + + out->scale_factor = data.scale_factor(); + out->relative_pointer_speed_in_pixels_s = + data.relative_pointer_speed_in_pixels_s(); + return true; +} + +} // namespace mojo \ No newline at end of file
diff --git a/content/common/input/input_injector_mojom_traits.h b/content/common/input/input_injector_mojom_traits.h new file mode 100644 index 0000000..ac7f152 --- /dev/null +++ b/content/common/input/input_injector_mojom_traits.h
@@ -0,0 +1,37 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_INPUT_INPUT_INJECTOR_MOJOM_TRAITS_H_ +#define CONTENT_COMMON_INPUT_INPUT_INJECTOR_MOJOM_TRAITS_H_ + +#include "content/common/input/input_injector.mojom.h" +#include "content/common/input/synthetic_pinch_gesture_params.h" +#include "ui/gfx/geometry/point_f.h" + +namespace mojo { + +template <> +struct CONTENT_EXPORT StructTraits<content::mojom::SyntheticPinchDataView, + content::SyntheticPinchGestureParams> { + static float scale_factor(const content::SyntheticPinchGestureParams& r) { + return r.scale_factor; + } + + static const gfx::PointF& anchor( + const content::SyntheticPinchGestureParams& r) { + return r.anchor; + } + + static float relative_pointer_speed_in_pixels_s( + const content::SyntheticPinchGestureParams& r) { + return r.relative_pointer_speed_in_pixels_s; + } + + static bool Read(content::mojom::SyntheticPinchDataView r, + content::SyntheticPinchGestureParams* out); +}; + +} // namespace mojo + +#endif // CONTENT_COMMON_INPUT_INPUT_INJECTOR_MOJOM_TRAITS_H_
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index e950670..4ebf68b 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -73,13 +73,6 @@ IPC_STRUCT_TRAITS_MEMBER(modifiers) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(content::SyntheticPinchGestureParams) - IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams) - IPC_STRUCT_TRAITS_MEMBER(scale_factor) - IPC_STRUCT_TRAITS_MEMBER(anchor) - IPC_STRUCT_TRAITS_MEMBER(relative_pointer_speed_in_pixels_s) -IPC_STRUCT_TRAITS_END() - IPC_STRUCT_TRAITS_BEGIN(content::SyntheticTapGestureParams) IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams) IPC_STRUCT_TRAITS_MEMBER(position)
diff --git a/content/common/native_types.mojom b/content/common/native_types.mojom index cb8db3b..067bc96 100644 --- a/content/common/native_types.mojom +++ b/content/common/native_types.mojom
@@ -28,9 +28,6 @@ struct SyntheticSmoothScroll; [Native] -struct SyntheticPinch; - -[Native] struct SyntheticTap; [Native]
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc index c994e5f..fec5938 100644 --- a/content/renderer/render_process_impl.cc +++ b/content/renderer/render_process_impl.cc
@@ -189,7 +189,15 @@ #if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(ARCH_CPU_X86_64) if (base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler)) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kDisableInProcessStackTraces)) { + if (!command_line->HasSwitch(switches::kEnableCrashReporter) && + !command_line->HasSwitch(switches::kEnableCrashReporterForTesting)) { + // If we are using WebAssembly trap handling but both Breakpad and + // in-process stack traces are disabled then there will be no signal + // handler. In this case, we fall back on V8's default handler + // (https://crbug.com/798150). + v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/true); + } else if (!command_line->HasSwitch( + switches::kDisableInProcessStackTraces)) { // Only enable WebAssembly trap handler if we can set the callback. if (base::debug::SetStackDumpFirstChanceCallback( v8::TryHandleWebAssemblyTrapPosix)) { @@ -198,14 +206,6 @@ // WebAssembly trap handler without using the V8 signal handler. v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/false); } - } else if (!command_line->HasSwitch(switches::kEnableCrashReporter) && - !command_line->HasSwitch( - switches::kEnableCrashReporterForTesting)) { - // If we are using WebAssembly trap handling but both Breakpad and - // in-process stack traces are disabled then there will be no signal - // handler. In this case, we fall back on V8's default handler - // (https://crbug.com/798150). - v8::V8::EnableWebAssemblyTrapHandler(/*use_v8_signal_handler=*/true); } } #endif
diff --git a/docs/accessibility/chromevox.md b/docs/accessibility/chromevox.md index 05f6928..1e9574c 100644 --- a/docs/accessibility/chromevox.md +++ b/docs/accessibility/chromevox.md
@@ -64,6 +64,41 @@ “options.html” path with “background.html”, and then open up the inspector. +### Debugging ChromeOS + +To debug ChromeVox in ChromeOS, you need to add the command-line flag to the +config file in device under test(DUT) instead of starting chrome from command +line. + +``` +(dut) $ echo " --remote-debugging-port=9222 " >> /etc/chrome_dev.conf +(dut) $ restart ui +``` + +This is also written in +[Simple Chrome Workflow Doc](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/simple_chrome_workflow.md#command_line-flags-and-environment-variables). + +You need to ssh from your development device into your DUT forwarding port 9222 +to open ChromeVox extension background page in your dev device, for example +``` +ssh my_crbook -L 3333:localhost:9222 +``` + +Then open the forwarded port in the development device, http://localhost:3333 in +the example. + +You may need to remove rootfs verification to write to `/etc/chrome_dev.conf`. + +``` +(dut) $ crossystem dev_boot_signed_only=0 +(dut) $ sudo /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification +(dut) $ reboot +``` + +See +[Chromium OS Doc](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_mode.md#disable-verity) +for more information about removing rootfs verification. + ### Running tests Build the browser_tests target. To run lots of tests in parallel, run it like
diff --git a/docs/threading_and_tasks.md b/docs/threading_and_tasks.md index d13dcd74..cf6335c 100644 --- a/docs/threading_and_tasks.md +++ b/docs/threading_and_tasks.md
@@ -27,8 +27,9 @@ ## Core Concepts * **Task**: A unit of work to be processed. Effectively a function pointer with - optionally associated state. In Chrome this is `base::Callback` created via - `base::Bind` + optionally associated state. In Chrome this is `base::OnceCallback` and + `base::RepeatingCallback` created via `base::BindOnce` and + `base::BindRepeating`, respectively. ([documentation](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/callback.md)). * **Task queue**: A queue of tasks to be processed. * **Physical thread**: An operating system provided thread (e.g. pthread on @@ -323,9 +324,9 @@ In order to write non-blocking code, many APIs in Chrome are asynchronous. Usually this means that they either need to be executed on a particular thread/sequence and will return results via a custom delegate interface, or they -take a `base::Callback<>` object that is called when the requested operation is -completed. Executing work on a specific thread/sequence is covered in the -PostTask sections above. +take a `base::OnceCallback<>` (or `base::RepeatingCallback<>`) object that is +called when the requested operation is completed. Executing work on a specific +thread/sequence is covered in the PostTask sections above. ## Posting Multiple Tasks to the Same Thread
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index fa65172..7275946 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -69,13 +69,11 @@ "//extensions/browser/api/hid", "//extensions/browser/api/idle", "//extensions/browser/api/management", - "//extensions/browser/api/messaging", "//extensions/browser/api/metrics_private", "//extensions/browser/api/mime_handler_private", "//extensions/browser/api/networking_private", "//extensions/browser/api/power", "//extensions/browser/api/printer_provider", - "//extensions/browser/api/printer_provider_internal", "//extensions/browser/api/runtime", "//extensions/browser/api/serial", "//extensions/browser/api/socket", @@ -177,7 +175,6 @@ "//extensions/browser/api/networking_private", "//extensions/browser/api/power", "//extensions/browser/api/printer_provider", - "//extensions/browser/api/printer_provider_internal", "//extensions/browser/api/runtime", "//extensions/browser/api/serial", "//extensions/browser/api/socket",
diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index 4304368..7aeb45c 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc
@@ -110,6 +110,12 @@ return nullptr; } +#if BUILDFLAG(IS_CHROMEOS_ASH) +bool ExtensionsAPIClient::ShouldAllowDetachingUsb(int vid, int pid) const { + return false; +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + std::unique_ptr<VirtualKeyboardDelegate> ExtensionsAPIClient::CreateVirtualKeyboardDelegate( content::BrowserContext* context) const {
diff --git a/extensions/browser/api/extensions_api_client.h b/extensions/browser/api/extensions_api_client.h index 2768f0e..5b3ea32c 100644 --- a/extensions/browser/api/extensions_api_client.h +++ b/extensions/browser/api/extensions_api_client.h
@@ -162,6 +162,11 @@ virtual std::unique_ptr<DevicePermissionsPrompt> CreateDevicePermissionsPrompt(content::WebContents* web_contents) const; +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Returns true if device policy allows detaching a given USB device. + virtual bool ShouldAllowDetachingUsb(int vid, int pid) const; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + // Returns a delegate for some of VirtualKeyboardAPI's behavior. virtual std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate(content::BrowserContext* browser_context) const;
diff --git a/extensions/browser/api/messaging/BUILD.gn b/extensions/browser/api/messaging/BUILD.gn index 0252290c..a644726 100644 --- a/extensions/browser/api/messaging/BUILD.gn +++ b/extensions/browser/api/messaging/BUILD.gn
@@ -28,6 +28,7 @@ "//base", "//content/public/browser", "//content/public/common", + "//extensions/browser/api", "//extensions/common", "//extensions/common/api", ]
diff --git a/extensions/browser/api/printer_provider/BUILD.gn b/extensions/browser/api/printer_provider/BUILD.gn index d8c7e5c2..1f203a3a 100644 --- a/extensions/browser/api/printer_provider/BUILD.gn +++ b/extensions/browser/api/printer_provider/BUILD.gn
@@ -13,11 +13,23 @@ "printer_provider_api.h", "printer_provider_api_factory.cc", "printer_provider_api_factory.h", + "printer_provider_internal_api.cc", + "printer_provider_internal_api.h", + "printer_provider_internal_api_observer.h", "printer_provider_print_job.cc", "printer_provider_print_job.h", ] + configs += [ + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + "//build/config/compiler:no_size_t_to_int_warning", + ] + deps = [ + "//components/keyed_service/content", + "//content/public/browser", + "//extensions/browser/api/usb", + "//extensions/common", "//extensions/common/api", "//services/device/public/cpp/usb", "//services/device/public/mojom:usb",
diff --git a/extensions/browser/api/printer_provider/printer_provider_api.cc b/extensions/browser/api/printer_provider/printer_provider_api.cc index 2c748ea8..f943b4b 100644 --- a/extensions/browser/api/printer_provider/printer_provider_api.cc +++ b/extensions/browser/api/printer_provider/printer_provider_api.cc
@@ -19,9 +19,9 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "extensions/browser/api/printer_provider/printer_provider_internal_api.h" +#include "extensions/browser/api/printer_provider/printer_provider_internal_api_observer.h" #include "extensions/browser/api/printer_provider/printer_provider_print_job.h" -#include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h" -#include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h" #include "extensions/browser/api/usb/usb_device_manager.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_registry.h"
diff --git a/extensions/browser/api/printer_provider/printer_provider_api_factory.cc b/extensions/browser/api/printer_provider/printer_provider_api_factory.cc index 9a99feb..34f4f36 100644 --- a/extensions/browser/api/printer_provider/printer_provider_api_factory.cc +++ b/extensions/browser/api/printer_provider/printer_provider_api_factory.cc
@@ -6,7 +6,7 @@ #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "extensions/browser/api/printer_provider/printer_provider_api.h" -#include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h" +#include "extensions/browser/api/printer_provider/printer_provider_internal_api.h" #include "extensions/browser/extension_registry_factory.h" #include "extensions/browser/extensions_browser_client.h"
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc b/extensions/browser/api/printer_provider/printer_provider_internal_api.cc similarity index 90% rename from extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc rename to extensions/browser/api/printer_provider/printer_provider_internal_api.cc index 93ca21a..bfb7e83 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc +++ b/extensions/browser/api/printer_provider/printer_provider_internal_api.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h" +#include "extensions/browser/api/printer_provider/printer_provider_internal_api.h" #include <memory> #include <string> @@ -47,11 +47,9 @@ } PrinterProviderInternalAPI::PrinterProviderInternalAPI( - content::BrowserContext* browser_context) { -} + content::BrowserContext* browser_context) {} -PrinterProviderInternalAPI::~PrinterProviderInternalAPI() { -} +PrinterProviderInternalAPI::~PrinterProviderInternalAPI() {} void PrinterProviderInternalAPI::AddObserver( PrinterProviderInternalAPIObserver* observer) { @@ -96,12 +94,10 @@ } PrinterProviderInternalReportPrintResultFunction:: - PrinterProviderInternalReportPrintResultFunction() { -} + PrinterProviderInternalReportPrintResultFunction() {} PrinterProviderInternalReportPrintResultFunction:: - ~PrinterProviderInternalReportPrintResultFunction() { -} + ~PrinterProviderInternalReportPrintResultFunction() {} ExtensionFunction::ResponseAction PrinterProviderInternalReportPrintResultFunction::Run() { @@ -116,12 +112,10 @@ } PrinterProviderInternalReportPrinterCapabilityFunction:: - PrinterProviderInternalReportPrinterCapabilityFunction() { -} + PrinterProviderInternalReportPrinterCapabilityFunction() {} PrinterProviderInternalReportPrinterCapabilityFunction:: - ~PrinterProviderInternalReportPrinterCapabilityFunction() { -} + ~PrinterProviderInternalReportPrinterCapabilityFunction() {} ExtensionFunction::ResponseAction PrinterProviderInternalReportPrinterCapabilityFunction::Run() { @@ -144,12 +138,10 @@ } PrinterProviderInternalReportPrintersFunction:: - PrinterProviderInternalReportPrintersFunction() { -} + PrinterProviderInternalReportPrintersFunction() {} PrinterProviderInternalReportPrintersFunction:: - ~PrinterProviderInternalReportPrintersFunction() { -} + ~PrinterProviderInternalReportPrintersFunction() {} ExtensionFunction::ResponseAction PrinterProviderInternalReportPrintersFunction::Run() { @@ -174,12 +166,10 @@ } PrinterProviderInternalGetPrintDataFunction:: - PrinterProviderInternalGetPrintDataFunction() { -} + PrinterProviderInternalGetPrintDataFunction() {} PrinterProviderInternalGetPrintDataFunction:: - ~PrinterProviderInternalGetPrintDataFunction() { -} + ~PrinterProviderInternalGetPrintDataFunction() {} ExtensionFunction::ResponseAction PrinterProviderInternalGetPrintDataFunction::Run() { @@ -238,12 +228,10 @@ } PrinterProviderInternalReportUsbPrinterInfoFunction:: - PrinterProviderInternalReportUsbPrinterInfoFunction() { -} + PrinterProviderInternalReportUsbPrinterInfoFunction() {} PrinterProviderInternalReportUsbPrinterInfoFunction:: - ~PrinterProviderInternalReportUsbPrinterInfoFunction() { -} + ~PrinterProviderInternalReportUsbPrinterInfoFunction() {} ExtensionFunction::ResponseAction PrinterProviderInternalReportUsbPrinterInfoFunction::Run() {
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h b/extensions/browser/api/printer_provider/printer_provider_internal_api.h similarity index 93% rename from extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h rename to extensions/browser/api/printer_provider/printer_provider_internal_api.h index dc1aef5d..0f7231c 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h +++ b/extensions/browser/api/printer_provider/printer_provider_internal_api.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_H_ -#define EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_H_ +#ifndef EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_PRINTER_PROVIDER_INTERNAL_API_H_ +#define EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_PRINTER_PROVIDER_INTERNAL_API_H_ #include <string> #include "base/macros.h" #include "base/observer_list.h" -#include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h" +#include "extensions/browser/api/printer_provider/printer_provider_internal_api_observer.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_function.h" #include "extensions/common/api/printer_provider_internal.h" @@ -17,12 +17,12 @@ namespace base { class DictionaryValue; class RefCountedMemory; -} +} // namespace base namespace content { class BlobHandle; class BrowserContext; -} +} // namespace content namespace extensions { class Extension; @@ -176,4 +176,4 @@ } // namespace extensions -#endif // EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_H_ +#endif // EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_PRINTER_PROVIDER_INTERNAL_API_H_
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h b/extensions/browser/api/printer_provider/printer_provider_internal_api_observer.h similarity index 89% rename from extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h rename to extensions/browser/api/printer_provider/printer_provider_internal_api_observer.h index 1284dae..8797b33b 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h +++ b/extensions/browser/api/printer_provider/printer_provider_internal_api_observer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ -#define EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ +#ifndef EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ +#define EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ #include <vector> @@ -67,4 +67,4 @@ } // namespace extensions -#endif // EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ +#endif // EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_
diff --git a/extensions/browser/api/printer_provider_internal/BUILD.gn b/extensions/browser/api/printer_provider_internal/BUILD.gn deleted file mode 100644 index 9b60358..0000000 --- a/extensions/browser/api/printer_provider_internal/BUILD.gn +++ /dev/null
@@ -1,28 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//extensions/buildflags/buildflags.gni") - -assert(enable_extensions, - "Cannot depend on extensions because enable_extensions=false.") - -source_set("printer_provider_internal") { - sources = [ - "printer_provider_internal_api.cc", - "printer_provider_internal_api.h", - "printer_provider_internal_api_observer.h", - ] - - configs += [ - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - "//build/config/compiler:no_size_t_to_int_warning", - ] - - deps = [ - "//content/public/browser", - "//extensions/common/api", - ] - - public_deps = [ "//extensions/browser:browser_sources" ] -}
diff --git a/extensions/browser/api/printer_provider_internal/DIR_METADATA b/extensions/browser/api/printer_provider_internal/DIR_METADATA deleted file mode 100644 index c6bf1f0..0000000 --- a/extensions/browser/api/printer_provider_internal/DIR_METADATA +++ /dev/null
@@ -1,3 +0,0 @@ -monorail { - component: "Internals>Printing" -}
diff --git a/extensions/browser/api/printer_provider_internal/OWNERS b/extensions/browser/api/printer_provider_internal/OWNERS deleted file mode 100644 index 0fa42c6a4..0000000 --- a/extensions/browser/api/printer_provider_internal/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -tbarzic@chromium.org -vitalybuka@chromium.org
diff --git a/extensions/browser/api/usb/usb_apitest.cc b/extensions/browser/api/usb/usb_apitest.cc index 6ea8c70..f78d9771 100644 --- a/extensions/browser/api/usb/usb_apitest.cc +++ b/extensions/browser/api/usb/usb_apitest.cc
@@ -113,6 +113,12 @@ content::WebContents* web_contents) const override { return std::make_unique<TestDevicePermissionsPrompt>(web_contents); } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + bool ShouldAllowDetachingUsb(int vid, int pid) const override { + return vid == 1 && pid == 2; + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) }; class UsbApiTest : public ShellApiTest { @@ -128,12 +134,10 @@ base::RunLoop().RunUntilIdle(); std::vector<device::mojom::UsbConfigurationInfoPtr> configs; - auto config_1 = device::mojom::UsbConfigurationInfo::New(); - config_1->configuration_value = 1; - configs.push_back(std::move(config_1)); - auto config_2 = device::mojom::UsbConfigurationInfo::New(); - config_2->configuration_value = 2; - configs.push_back(std::move(config_2)); + configs.push_back( + device::FakeUsbDeviceInfo::CreateConfiguration(0xff, 0x00, 0x00, 1)); + configs.push_back( + device::FakeUsbDeviceInfo::CreateConfiguration(0xff, 0x00, 0x00, 2)); fake_device_ = base::MakeRefCounted<device::FakeUsbDeviceInfo>( 0, 0, "Test Manufacturer", "Test Device", "ABC123", std::move(configs)); @@ -361,4 +365,38 @@ ASSERT_TRUE(result_listener.WaitUntilSatisfied()); } +#if BUILDFLAG(IS_CHROMEOS_ASH) +IN_PROC_BROWSER_TEST_F(UsbApiTest, MassStorage) { + ExtensionTestMessageListener ready_listener("ready", false); + ready_listener.set_failure_message("failure"); + ExtensionTestMessageListener result_listener("success", false); + result_listener.set_failure_message("failure"); + + // Mass storage devices should be hidden unless allowed in policy. + // The TestExtensionsAPIClient allows only vid=1, pid=2. + TestExtensionsAPIClient test_api_client; + std::vector<device::mojom::UsbConfigurationInfoPtr> storage_configs; + auto storage_config = device::FakeUsbDeviceInfo::CreateConfiguration( + /* mass storage */ 0x08, 0x06, 0x50); + storage_configs.push_back(storage_config->Clone()); + device::mojom::UsbDeviceInfoPtr device_1 = + fake_usb_manager_.CreateAndAddDevice(0x1, 0x2, 0x00, + std::move(storage_configs)); + + storage_configs.clear(); + storage_configs.push_back(storage_config->Clone()); + device::mojom::UsbDeviceInfoPtr device_2 = + fake_usb_manager_.CreateAndAddDevice(0x5, 0x6, 0x00, + std::move(storage_configs)); + + ASSERT_TRUE(LoadApp("api_test/usb/mass_storage")); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + + fake_usb_manager_.RemoveDevice(device_2->guid); + fake_usb_manager_.RemoveDevice(device_1->guid); + + ASSERT_TRUE(result_listener.WaitUntilSatisfied()); +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + } // namespace extensions
diff --git a/extensions/browser/api/usb/usb_device_manager.cc b/extensions/browser/api/usb/usb_device_manager.cc index 6cc496d..284eb54 100644 --- a/extensions/browser/api/usb/usb_device_manager.cc +++ b/extensions/browser/api/usb/usb_device_manager.cc
@@ -14,6 +14,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/device_service.h" #include "extensions/browser/api/device_permissions_manager.h" +#include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/event_router_factory.h" #include "extensions/common/api/usb.h" #include "extensions/common/permissions/permissions_data.h" @@ -29,6 +30,37 @@ namespace { +constexpr int kUsbClassMassStorage = 0x08; + +bool IsMassStorageInterface(const device::mojom::UsbInterfaceInfo& interface) { + for (auto& alternate : interface.alternates) { + if (alternate->class_code == kUsbClassMassStorage) + return true; + } + return false; +} + +bool ShouldExposeDevice(const device::mojom::UsbDeviceInfo& device_info) { + // ChromeOS always allows mass storage devices to be detached, but chrome.usb + // only gets access when the specific vid/pid is listed in device policy. + // This means that reloading policy can change the result of this function. + for (auto& configuration : device_info.configurations) { + for (auto& interface : configuration->interfaces) { + if (!IsMassStorageInterface(*interface)) + return true; + } + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ExtensionsAPIClient::Get()->ShouldAllowDetachingUsb( + device_info.vendor_id, device_info.product_id)) { + return true; + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + return false; +} + // Returns true if the given extension has permission to receive events // regarding this device. bool WillDispatchDeviceEvent(const device::mojom::UsbDeviceInfo& device_info, @@ -223,6 +255,8 @@ DCHECK(device_info); // Update the device list. DCHECK(!base::Contains(devices_, device_info->guid)); + if (!ShouldExposeDevice(*device_info)) + return; std::string guid = device_info->guid; auto result = devices_.insert(std::make_pair(std::move(guid), std::move(device_info))); @@ -238,8 +272,12 @@ void UsbDeviceManager::OnDeviceRemoved( device::mojom::UsbDeviceInfoPtr device_info) { DCHECK(device_info); + + // Handle if ShouldExposeDevice() returned false when the device was added. + if (!base::Contains(devices_, device_info->guid)) + return; + // Update the device list. - DCHECK(base::Contains(devices_, device_info->guid)); devices_.erase(device_info->guid); DispatchEvent(usb::OnDeviceRemoved::kEventName, *device_info); @@ -281,6 +319,8 @@ std::vector<device::mojom::UsbDeviceInfoPtr> devices) { for (auto& device_info : devices) { DCHECK(device_info); + if (!ShouldExposeDevice(*device_info)) + continue; std::string guid = device_info->guid; devices_.insert(std::make_pair(guid, std::move(device_info))); }
diff --git a/extensions/common/api/printer_provider_internal.idl b/extensions/common/api/printer_provider_internal.idl index d34e472..3d3ea202 100644 --- a/extensions/common/api/printer_provider_internal.idl +++ b/extensions/common/api/printer_provider_internal.idl
@@ -12,6 +12,7 @@ // is internally dispatched having a requestId argument (which is removed from // the argument list before the event actually reaches the event listeners). The // requestId is forwarded to the chrome.printerProviderInternal API functions. +[implemented_in="extensions/browser/api/printer_provider/printer_provider_internal_api.h"] namespace printerProviderInternal { // Same as in printerProvider.PrintError enum API. enum PrintError { OK, FAILED, INVALID_TICKET, INVALID_DATA };
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn index 2441d5d..b67f2fa 100644 --- a/extensions/shell/BUILD.gn +++ b/extensions/shell/BUILD.gn
@@ -60,6 +60,7 @@ "//extensions:shell_and_test_pak", "//extensions/browser", "//extensions/browser:core_api_provider", + "//extensions/browser/api/messaging", "//extensions/browser/kiosk", "//extensions/common", "//extensions/common:core_api_provider",
diff --git a/extensions/test/data/api_test/usb/mass_storage/background.js b/extensions/test/data/api_test/usb/mass_storage/background.js new file mode 100644 index 0000000..e412e18 --- /dev/null +++ b/extensions/test/data/api_test/usb/mass_storage/background.js
@@ -0,0 +1,29 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.usb.getDevices({}, devices => { + if (devices.length !== 1) { + console.error("Expected a single device, but got " + devices.length + "."); + chrome.test.sendMessage("failure"); + return; + } + device = devices[0]; + if (device.vendorId !== 1 || device.productId !== 2) { + console.error("Unexpected device was returned by getDevices."); + chrome.test.sendMessage("failure"); + return; + } + + chrome.test.sendMessage("ready"); +}); + +chrome.usb.onDeviceRemoved.addListener((device) => { + if (device.vendorId !== 1 || device.productId !== 2) { + console.error("Unexpected device was removed."); + chrome.test.sendMessage("failure"); + return; + } + + chrome.test.sendMessage("success"); +});
diff --git a/extensions/test/data/api_test/usb/mass_storage/manifest.json b/extensions/test/data/api_test/usb/mass_storage/manifest.json new file mode 100644 index 0000000..7bd1e3a --- /dev/null +++ b/extensions/test/data/api_test/usb/mass_storage/manifest.json
@@ -0,0 +1,17 @@ +{ + "name": "Mass storage devices in chrome.usb", + "manifest_version": 2, + "version": "0.1", + "description": "Mass storage devices in chrome.usb", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "usb", + // These are test devices emulated by the mocks enabled for the test. + { "usbDevices": [{ "vendorId": 1, "productId": 2 }, + { "vendorId": 5, "productId": 6 }]} + ] +}
diff --git a/gpu/command_buffer/build_webgpu_cmd_buffer.py b/gpu/command_buffer/build_webgpu_cmd_buffer.py index 2a10676..07b6c8e 100755 --- a/gpu/command_buffer/build_webgpu_cmd_buffer.py +++ b/gpu/command_buffer/build_webgpu_cmd_buffer.py
@@ -47,7 +47,7 @@ 'impl_func': False, 'internal': True, 'data_transfer_methods': ['shm'], - 'cmd_args': 'uint64_t device_client_id, uint32_t commands_shm_id, ' + 'cmd_args': 'uint32_t commands_shm_id, ' 'uint32_t commands_shm_offset, uint32_t size', 'size_args': { 'commands': 'size * sizeof(char)', @@ -72,8 +72,10 @@ 'impl_func': False, 'internal': True, 'data_transfer_methods': ['shm'], - 'cmd_args': 'uint64_t device_client_id, ' + 'cmd_args': 'uint64_t request_device_serial, ' 'uint32_t adapter_service_id, ' + 'uint32_t device_id, ' + 'uint32_t device_generation, ' 'uint32_t request_device_properties_shm_id, ' 'uint32_t request_device_properties_shm_offset, ' 'uint32_t request_device_properties_size', @@ -82,11 +84,6 @@ 'request_device_properties_size * sizeof(char)', }, }, - 'RemoveDevice': { - 'impl_func': False, - 'internal': True, - 'cmd_args': 'uint64_t device_client_id' - }, } def main(argv):
diff --git a/gpu/command_buffer/client/dawn_client_serializer.cc b/gpu/command_buffer/client/dawn_client_serializer.cc index a530393..f69ca37 100644 --- a/gpu/command_buffer/client/dawn_client_serializer.cc +++ b/gpu/command_buffer/client/dawn_client_serializer.cc
@@ -14,67 +14,45 @@ namespace gpu { namespace webgpu { -DawnClientSerializer::DawnClientSerializer( - DawnDeviceClientID device_client_id, +// static +std::unique_ptr<DawnClientSerializer> DawnClientSerializer::Create( + WebGPUImplementation* client, WebGPUCmdHelper* helper, DawnClientMemoryTransferService* memory_transfer_service, - std::unique_ptr<TransferBuffer> c2s_transfer_buffer) - : device_client_id_(device_client_id), + const SharedMemoryLimits& limits) { + std::unique_ptr<TransferBuffer> transfer_buffer = + std::make_unique<TransferBuffer>(helper); + if (!transfer_buffer->Initialize(limits.start_transfer_buffer_size, + /* start offset */ 0, + limits.min_transfer_buffer_size, + limits.max_transfer_buffer_size, + /* alignment */ 8)) { + return nullptr; + } + return std::make_unique<DawnClientSerializer>( + client, helper, memory_transfer_service, std::move(transfer_buffer), + limits.start_transfer_buffer_size); +} + +DawnClientSerializer::DawnClientSerializer( + WebGPUImplementation* client, + WebGPUCmdHelper* helper, + DawnClientMemoryTransferService* memory_transfer_service_, + std::unique_ptr<TransferBuffer> transfer_buffer, + uint32_t buffer_initial_size) + : client_(client), helper_(helper), - memory_transfer_service_(memory_transfer_service), - c2s_transfer_buffer_(std::move(c2s_transfer_buffer)), - c2s_buffer_(helper_, c2s_transfer_buffer_.get()) { - DCHECK(helper_); - DCHECK(c2s_transfer_buffer_ && c2s_transfer_buffer_->HaveBuffer()); - - const SharedMemoryLimits& limits = SharedMemoryLimits::ForWebGPUContext(); - c2s_buffer_default_size_ = limits.start_transfer_buffer_size; - DCHECK_GT(c2s_buffer_default_size_, 0u); - - DCHECK(memory_transfer_service_); - dawn_wire::WireClientDescriptor descriptor = {}; - descriptor.serializer = this; - descriptor.memoryTransferService = memory_transfer_service_; - wire_client_ = std::make_unique<dawn_wire::WireClient>(descriptor); + memory_transfer_service_(memory_transfer_service_), + transfer_buffer_(std::move(transfer_buffer)), + buffer_initial_size_(buffer_initial_size), + buffer_(helper_, transfer_buffer_.get()) { + DCHECK_GT(buffer_initial_size_, 0u); } -DawnClientSerializer::~DawnClientSerializer() { - // Destroy the wire client before anything else because it might still call - // GetCmdSpace so the rest of the serializer must still be valid. - wire_client_ = nullptr; -} - -// This function can only be called once for each DawnClientSerializer -// object (before any call of GetCmdSpace()). -void DawnClientSerializer::RequestDeviceCreation( - uint32_t requested_adapter_id, - const WGPUDeviceProperties& requested_device_properties) { - DCHECK(!c2s_buffer_.valid()); - DCHECK_EQ(0u, c2s_put_offset_); - - size_t serialized_device_properties_size = - dawn_wire::SerializedWGPUDevicePropertiesSize( - &requested_device_properties); - DCHECK_NE(0u, serialized_device_properties_size); - - DCHECK_LE(serialized_device_properties_size, - c2s_transfer_buffer_->GetMaxSize()); - c2s_buffer_.Reset(serialized_device_properties_size); - - dawn_wire::SerializeWGPUDeviceProperties( - &requested_device_properties, - reinterpret_cast<char*>(c2s_buffer_.address())); - - helper_->RequestDevice(device_client_id_, requested_adapter_id, - c2s_buffer_.shm_id(), c2s_buffer_.offset(), - serialized_device_properties_size); - c2s_buffer_.Release(); - - helper_->Flush(); -} +DawnClientSerializer::~DawnClientSerializer() = default; size_t DawnClientSerializer::GetMaximumAllocationSize() const { - return c2s_transfer_buffer_->GetMaxSize(); + return transfer_buffer_->GetMaxSize(); } void* DawnClientSerializer::GetCmdSpace(size_t size) { @@ -83,23 +61,23 @@ DCHECK_LE(size, GetMaximumAllocationSize()); // The buffer size must be initialized before any commands are serialized. - DCHECK_NE(c2s_buffer_default_size_, 0u); + DCHECK_NE(buffer_initial_size_, 0u); - DCHECK_LE(c2s_put_offset_, c2s_buffer_.size()); + DCHECK_LE(put_offset_, buffer_.size()); const bool overflows_remaining_space = - size > static_cast<size_t>(c2s_buffer_.size() - c2s_put_offset_); + size > static_cast<size_t>(buffer_.size() - put_offset_); - if (LIKELY(c2s_buffer_.valid() && !overflows_remaining_space)) { + if (LIKELY(buffer_.valid() && !overflows_remaining_space)) { // If the buffer is valid and has sufficient space, return the // pointer and increment the offset. - uint8_t* ptr = static_cast<uint8_t*>(c2s_buffer_.address()); - ptr += c2s_put_offset_; + uint8_t* ptr = static_cast<uint8_t*>(buffer_.address()); + ptr += put_offset_; - c2s_put_offset_ += static_cast<uint32_t>(size); + put_offset_ += static_cast<uint32_t>(size); return ptr; } - if (!c2s_transfer_buffer_) { + if (!transfer_buffer_) { // The serializer hit a fatal error and was disconnected. return nullptr; } @@ -108,74 +86,53 @@ Flush(); uint32_t allocation_size = - std::max(c2s_buffer_default_size_, static_cast<uint32_t>(size)); + std::max(buffer_initial_size_, static_cast<uint32_t>(size)); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "DawnClientSerializer::GetCmdSpace", "bytes", allocation_size); - c2s_buffer_.Reset(allocation_size); + buffer_.Reset(allocation_size); - if (!c2s_buffer_.valid() || c2s_buffer_.size() < size) { + if (!buffer_.valid() || buffer_.size() < size) { DLOG(ERROR) << "Dawn wire transfer buffer allocation failed"; - HandleGpuControlLostContext(); + Disconnect(); + client_->OnGpuControlLostContextMaybeReentrant(); return nullptr; } - c2s_put_offset_ = size; - return c2s_buffer_.address(); + put_offset_ = size; + return buffer_.address(); } bool DawnClientSerializer::Flush() { - if (c2s_buffer_.valid()) { + if (buffer_.valid()) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), - "DawnClientSerializer::Flush", "bytes", c2s_put_offset_); + "DawnClientSerializer::Flush", "bytes", put_offset_); - TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), - "DawnCommands", TRACE_EVENT_FLAG_FLOW_OUT, - (static_cast<uint64_t>(c2s_buffer_.shm_id()) << 32) + - c2s_buffer_.offset()); + TRACE_EVENT_WITH_FLOW0( + TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "DawnCommands", + TRACE_EVENT_FLAG_FLOW_OUT, + (static_cast<uint64_t>(buffer_.shm_id()) << 32) + buffer_.offset()); - c2s_buffer_.Shrink(c2s_put_offset_); - helper_->DawnCommands(device_client_id_, c2s_buffer_.shm_id(), - c2s_buffer_.offset(), c2s_put_offset_); - c2s_put_offset_ = 0; - c2s_buffer_.Release(); - client_awaiting_flush_ = false; + buffer_.Shrink(put_offset_); + helper_->DawnCommands(buffer_.shm_id(), buffer_.offset(), put_offset_); + put_offset_ = 0; + buffer_.Release(); + awaiting_flush_ = false; + + memory_transfer_service_->FreeHandles(helper_); } - - memory_transfer_service_->FreeHandles(helper_); return true; } -void DawnClientSerializer::SetClientAwaitingFlush(bool awaiting_flush) { - // If awaiting_flush is true, but the c2s_buffer_ is invalid (empty), that +void DawnClientSerializer::SetAwaitingFlush(bool awaiting_flush) { + // If awaiting_flush is true, but the buffer_ is invalid (empty), that // means the last command right before this caused a flush. Another flush is // not needed. - client_awaiting_flush_ = awaiting_flush && c2s_buffer_.valid(); + awaiting_flush_ = awaiting_flush && buffer_.valid(); } -void DawnClientSerializer::HandleGpuControlLostContext() { - // Immediately forget pending commands. - c2s_buffer_.Discard(); - c2s_transfer_buffer_ = nullptr; - - // Disconnect the wire client. WebGPU commands will become a noop, and the - // device will receive a Lost event. - // NOTE: This assumes single-threaded operation. - wire_client_->Disconnect(); -} - -WGPUDevice DawnClientSerializer::GetDevice() const { - return wire_client_->GetDevice(); -} - -ReservedTexture DawnClientSerializer::ReserveTexture() { - dawn_wire::ReservedTexture reservation = - wire_client_->ReserveTexture(GetDevice()); - return {reservation.texture, reservation.id, reservation.generation}; -} - -bool DawnClientSerializer::HandleCommands(const char* commands, - size_t command_size) { - return wire_client_->HandleCommands(commands, command_size); +void DawnClientSerializer::Disconnect() { + buffer_.Discard(); + transfer_buffer_ = nullptr; } } // namespace webgpu
diff --git a/gpu/command_buffer/client/dawn_client_serializer.h b/gpu/command_buffer/client/dawn_client_serializer.h index 8a4bc656..a377171 100644 --- a/gpu/command_buffer/client/dawn_client_serializer.h +++ b/gpu/command_buffer/client/dawn_client_serializer.h
@@ -10,61 +10,61 @@ #include <memory> #include "gpu/command_buffer/client/transfer_buffer.h" -#include "gpu/command_buffer/client/webgpu_interface.h" namespace gpu { +struct SharedMemoryLimits; class TransferBuffer; namespace webgpu { class DawnClientMemoryTransferService; class WebGPUCmdHelper; +class WebGPUImplementation; class DawnClientSerializer final : public dawn_wire::CommandSerializer { public: - DawnClientSerializer(DawnDeviceClientID device_client_id, + static std::unique_ptr<DawnClientSerializer> Create( + WebGPUImplementation* client, + WebGPUCmdHelper* helper, + DawnClientMemoryTransferService* memory_transfer_service, + const SharedMemoryLimits& limits); + + DawnClientSerializer(WebGPUImplementation* client, WebGPUCmdHelper* helper, DawnClientMemoryTransferService* memory_transfer_service, - std::unique_ptr<TransferBuffer> c2s_transfer_buffer); + std::unique_ptr<TransferBuffer> transfer_buffer, + uint32_t buffer_initial_size); ~DawnClientSerializer() override; - // Send WGPUDeviceProperties to the server side - // Note that this function should only be called once for each - // DawnClientSerializer object. - void RequestDeviceCreation( - uint32_t requested_adapter_id, - const WGPUDeviceProperties& requested_device_properties); - // dawn_wire::CommandSerializer implementation size_t GetMaximumAllocationSize() const final; void* GetCmdSpace(size_t size) final; bool Flush() final; - void SetClientAwaitingFlush(bool awaiting_flush); - bool ClientAwaitingFlush() const { return client_awaiting_flush_; } + // Signal that it's important that the previously encoded commands are + // flushed. Calling |AwaitingFlush| will return whether or not a flush still + // needs to occur. + void SetAwaitingFlush(bool awaiting_flush); - // Called upon context lost. - void HandleGpuControlLostContext(); + // Check if the serializer has commands that have been serialized but not + // flushed after |SetAwaitingFlush| was passed |true|. + bool AwaitingFlush() const { return awaiting_flush_; } - // For the WebGPUInterface implementation of WebGPUImplementation - WGPUDevice GetDevice() const; - ReservedTexture ReserveTexture(); - bool HandleCommands(const char* commands, size_t command_size); + // Disconnect the serializer. Commands are forgotten and future calls to + // |GetCmdSpace| will do nothing. + void Disconnect(); private: - DawnDeviceClientID device_client_id_; + WebGPUImplementation* client_; WebGPUCmdHelper* helper_; DawnClientMemoryTransferService* memory_transfer_service_; + uint32_t put_offset_ = 0; + std::unique_ptr<TransferBuffer> transfer_buffer_; + uint32_t buffer_initial_size_; + ScopedTransferBufferPtr buffer_; - std::unique_ptr<dawn_wire::WireClient> wire_client_; - - uint32_t c2s_buffer_default_size_ = 0; - uint32_t c2s_put_offset_ = 0; - std::unique_ptr<TransferBuffer> c2s_transfer_buffer_; - ScopedTransferBufferPtr c2s_buffer_; - - bool client_awaiting_flush_ = false; + bool awaiting_flush_ = false; }; } // namespace webgpu
diff --git a/gpu/command_buffer/client/webgpu_cmd_helper_autogen.h b/gpu/command_buffer/client/webgpu_cmd_helper_autogen.h index 750268f..e17e061 100644 --- a/gpu/command_buffer/client/webgpu_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/webgpu_cmd_helper_autogen.h
@@ -11,17 +11,16 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_CMD_HELPER_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_CMD_HELPER_AUTOGEN_H_ -void DawnCommands(uint64_t device_client_id, - uint32_t commands_shm_id, +void DawnCommands(uint32_t commands_shm_id, uint32_t commands_shm_offset, uint32_t size) { webgpu::cmds::DawnCommands* c = GetCmdSpace<webgpu::cmds::DawnCommands>(); if (c) { - c->Init(device_client_id, commands_shm_id, commands_shm_offset, size); + c->Init(commands_shm_id, commands_shm_offset, size); } } -void AssociateMailboxImmediate(GLuint64 device_client_id, +void AssociateMailboxImmediate(GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, @@ -32,18 +31,15 @@ GetImmediateCmdSpaceTotalSize<webgpu::cmds::AssociateMailboxImmediate>( size); if (c) { - c->Init(device_client_id, device_generation, id, generation, usage, - mailbox); + c->Init(device_id, device_generation, id, generation, usage, mailbox); } } -void DissociateMailbox(GLuint64 device_client_id, - GLuint texture_id, - GLuint texture_generation) { +void DissociateMailbox(GLuint texture_id, GLuint texture_generation) { webgpu::cmds::DissociateMailbox* c = GetCmdSpace<webgpu::cmds::DissociateMailbox>(); if (c) { - c->Init(device_client_id, texture_id, texture_generation); + c->Init(texture_id, texture_generation); } } @@ -55,23 +51,19 @@ } } -void RequestDevice(uint64_t device_client_id, +void RequestDevice(uint64_t request_device_serial, uint32_t adapter_service_id, + uint32_t device_id, + uint32_t device_generation, uint32_t request_device_properties_shm_id, uint32_t request_device_properties_shm_offset, uint32_t request_device_properties_size) { webgpu::cmds::RequestDevice* c = GetCmdSpace<webgpu::cmds::RequestDevice>(); if (c) { - c->Init( - device_client_id, adapter_service_id, request_device_properties_shm_id, - request_device_properties_shm_offset, request_device_properties_size); - } -} - -void RemoveDevice(uint64_t device_client_id) { - webgpu::cmds::RemoveDevice* c = GetCmdSpace<webgpu::cmds::RemoveDevice>(); - if (c) { - c->Init(device_client_id); + c->Init(request_device_serial, adapter_service_id, device_id, + device_generation, request_device_properties_shm_id, + request_device_properties_shm_offset, + request_device_properties_size); } }
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc index 189ad00..17fea6f 100644 --- a/gpu/command_buffer/client/webgpu_implementation.cc +++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -10,6 +10,7 @@ #include <dawn/dawn_proc.h> #include "base/numerics/checked_math.h" +#include "base/run_loop.h" #include "base/trace_event/trace_event.h" #include "gpu/command_buffer/client/dawn_client_memory_transfer_service.h" #include "gpu/command_buffer/client/dawn_client_serializer.h" @@ -35,16 +36,19 @@ WebGPUImplementation::~WebGPUImplementation() { #if BUILDFLAG(USE_DAWN) - // Wait for all commands to finish or we may free shared memory while - // commands are still in flight. - FlushAllCommandSerializers(); -#endif + if (!wire_client_) { + // Initialization failed. + return; + } + // Flush all commands and synchronously wait for them to finish. + // TODO(enga): Investigate if we can just Disconnect() instead. + wire_serializer_->Flush(); helper_->Finish(); -#if BUILDFLAG(USE_DAWN) - // Now that commands are finished, free the wire client. - ClearAllCommandSerializers(); + // Now that commands are finished, free the wire and serializers. + wire_client_.reset(); + wire_serializer_.reset(); // All client-side Dawn objects are now destroyed. // Shared memory allocations for buffers that were still mapped at the time @@ -66,12 +70,18 @@ memory_transfer_service_ = std::make_unique<DawnClientMemoryTransferService>(mapped_memory_.get()); - procs_ = dawn_wire::client::GetProcs(); + wire_serializer_ = DawnClientSerializer::Create( + this, helper_, memory_transfer_service_.get(), limits); + + dawn_wire::WireClientDescriptor descriptor = {}; + descriptor.serializer = wire_serializer_.get(); + descriptor.memoryTransferService = memory_transfer_service_.get(); + wire_client_ = std::make_unique<dawn_wire::WireClient>(descriptor); // TODO(senorblanco): Do this only once per process. Doing it once per // WebGPUImplementation is non-optimal but valid, since the returned // procs are always the same. - dawnProcSetProcs(&procs_); + dawnProcSetProcs(&dawn_wire::client::GetProcs()); #endif return gpu::ContextResult::kSuccess; @@ -226,9 +236,8 @@ void WebGPUImplementation::OnGpuControlLostContextMaybeReentrant() { lost_ = true; #if BUILDFLAG(USE_DAWN) - for (auto& iter : command_serializers_) { - iter.second->HandleGpuControlLostContext(); - } + wire_client_->Disconnect(); + wire_serializer_->Disconnect(); #endif } void WebGPUImplementation::OnGpuControlErrorMessage(const char* message, @@ -271,16 +280,10 @@ const cmds::DawnReturnCommandsInfo* dawn_return_commands_info = reinterpret_cast<const cmds::DawnReturnCommandsInfo*>(data.data()); - DawnDeviceClientID device_client_id = - dawn_return_commands_info->header.device_client_id; - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - CHECK(command_serializer); - // TODO(enga): Instead of a CHECK, this could generate a device lost // event on just that device. It doesn't seem worth doing right now // since a failure here is likely not recoverable. - CHECK(command_serializer->HandleCommands( + CHECK(wire_client_->HandleCommands( reinterpret_cast<const char*>( dawn_return_commands_info->deserialized_buffer), data.size() - @@ -326,22 +329,16 @@ reinterpret_cast<const cmds::DawnReturnRequestDeviceInfo*>( data.data()); - DawnDeviceClientID device_client_id = - returned_request_device_info->device_client_id; + DawnRequestDeviceSerial request_device_serial = + returned_request_device_info->request_device_serial; auto request_callback_iter = - request_device_callback_map_.find(device_client_id); + request_device_callback_map_.find(request_device_serial); CHECK(request_callback_iter != request_device_callback_map_.end()); auto& request_callback = request_callback_iter->second; bool is_request_device_success = returned_request_device_info->is_request_device_success; - if (!is_request_device_success) { - auto iter = command_serializers_.find(device_client_id); - DCHECK(iter != command_serializers_.end()); - command_serializers_.erase(iter); - } - std::move(request_callback) - .Run(is_request_device_success, device_client_id); + std::move(request_callback).Run(is_request_device_success); request_device_callback_map_.erase(request_callback_iter); } break; default: @@ -353,100 +350,43 @@ const DawnProcTable& WebGPUImplementation::GetProcs() const { #if !BUILDFLAG(USE_DAWN) NOTREACHED(); + static DawnProcTable null_procs = {}; + return null_procs; +#else + return dawn_wire::client::GetProcs(); #endif - return procs_; } -#if BUILDFLAG(USE_DAWN) -DawnClientSerializer* -WebGPUImplementation::GetCommandSerializerWithDeviceClientID( - DawnDeviceClientID device_client_id) const { - auto command_serializer = command_serializers_.find(device_client_id); - if (command_serializer == command_serializers_.end()) { - return nullptr; - } - return command_serializer->second.get(); -} - -void WebGPUImplementation::FlushAllCommandSerializers() { - for (auto& iter : command_serializers_) { - iter.second->Flush(); - } -} - -void WebGPUImplementation::ClearAllCommandSerializers() { - command_serializers_.clear(); -} - -bool WebGPUImplementation::AddNewCommandSerializer( - DawnDeviceClientID device_client_id) { - std::unique_ptr<TransferBuffer> c2s_transfer_buffer = - std::make_unique<TransferBuffer>(helper_); - const SharedMemoryLimits& limits = SharedMemoryLimits::ForWebGPUContext(); - if (!c2s_transfer_buffer->Initialize( - limits.start_transfer_buffer_size, - ImplementationBase::kStartingOffset, limits.min_transfer_buffer_size, - limits.max_transfer_buffer_size, ImplementationBase::kAlignment)) { - return false; - } - command_serializers_[device_client_id] = - std::make_unique<DawnClientSerializer>(device_client_id, helper_, - memory_transfer_service_.get(), - std::move(c2s_transfer_buffer)); - return true; -} -#endif - void WebGPUImplementation::FlushCommands() { #if BUILDFLAG(USE_DAWN) - FlushAllCommandSerializers(); -#endif - helper_->Flush(); -} - -void WebGPUImplementation::FlushCommands(DawnDeviceClientID device_client_id) { -#if BUILDFLAG(USE_DAWN) - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - command_serializer->Flush(); + wire_serializer_->Flush(); helper_->Flush(); #endif } -void WebGPUImplementation::EnsureAwaitingFlush( - DawnDeviceClientID device_client_id, - bool* needs_flush) { +void WebGPUImplementation::EnsureAwaitingFlush(bool* needs_flush) { #if BUILDFLAG(USE_DAWN) - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - // If there is already a flush waiting, we don't need to flush. // We only want to set |needs_flush| on state transition from // false -> true. - if (command_serializer->ClientAwaitingFlush()) { + if (wire_serializer_->AwaitingFlush()) { *needs_flush = false; return; } // Set the state to waiting for flush, and then write |needs_flush|. // Could still be false if there's no data to flush. - command_serializer->SetClientAwaitingFlush(true); - *needs_flush = command_serializer->ClientAwaitingFlush(); + wire_serializer_->SetAwaitingFlush(true); + *needs_flush = wire_serializer_->AwaitingFlush(); #else *needs_flush = false; #endif } -void WebGPUImplementation::FlushAwaitingCommands( - DawnDeviceClientID device_client_id) { +void WebGPUImplementation::FlushAwaitingCommands() { #if BUILDFLAG(USE_DAWN) - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - if (command_serializer->ClientAwaitingFlush()) { - command_serializer->Flush(); + if (wire_serializer_->AwaitingFlush()) { + wire_serializer_->Flush(); helper_->Flush(); } #endif @@ -459,26 +399,20 @@ OnGpuControlLostContextMaybeReentrant(); } -WGPUDevice WebGPUImplementation::GetDevice( - DawnDeviceClientID device_client_id) { +ReservedTexture WebGPUImplementation::ReserveTexture(WGPUDevice device) { #if BUILDFLAG(USE_DAWN) - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - return command_serializer->GetDevice(); -#else - NOTREACHED(); - return {}; -#endif -} + // Flush because we need to make sure messages that free a previously used + // texture are seen first. ReserveTexture may reuse an existing ID. + wire_serializer_->Flush(); -ReservedTexture WebGPUImplementation::ReserveTexture( - DawnDeviceClientID device_client_id) { -#if BUILDFLAG(USE_DAWN) - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - return command_serializer->ReserveTexture(); + auto reservation = wire_client_->ReserveTexture(device); + ReservedTexture result; + result.texture = reservation.texture; + result.id = reservation.id; + result.generation = reservation.generation; + result.deviceId = reservation.deviceId; + result.deviceGeneration = reservation.deviceGeneration; + return result; #else NOTREACHED(); return {}; @@ -489,12 +423,13 @@ return ++request_adapter_serial_; } -bool WebGPUImplementation::RequestAdapterAsync( +void WebGPUImplementation::RequestAdapterAsync( PowerPreference power_preference, base::OnceCallback<void(int32_t, const WGPUDeviceProperties&, const char*)> request_adapter_callback) { if (lost_) { - return false; + std::move(request_adapter_callback).Run(-1, {}, "Context Lost"); + return; } // Now that we declare request_adapter_serial as an uint64, it can't overflow @@ -503,58 +438,118 @@ DCHECK(request_adapter_callback_map_.find(request_adapter_serial) == request_adapter_callback_map_.end()); - helper_->RequestAdapter(request_adapter_serial, - static_cast<uint32_t>(power_preference)); - helper_->Flush(); - request_adapter_callback_map_[request_adapter_serial] = std::move(request_adapter_callback); - return true; + helper_->RequestAdapter(request_adapter_serial, + static_cast<uint32_t>(power_preference)); + helper_->Flush(); } -DawnDeviceClientID WebGPUImplementation::NextDeviceClientID() { - return ++device_client_id_; +DawnRequestDeviceSerial WebGPUImplementation::NextRequestDeviceSerial() { + return ++request_device_serial_; } -bool WebGPUImplementation::RequestDeviceAsync( +void WebGPUImplementation::RequestDeviceAsync( uint32_t requested_adapter_id, const WGPUDeviceProperties& requested_device_properties, - base::OnceCallback<void(bool, DawnDeviceClientID)> - request_device_callback) { + base::OnceCallback<void(WGPUDevice)> request_device_callback) { #if BUILDFLAG(USE_DAWN) if (lost_) { - return false; + std::move(request_device_callback).Run(nullptr); + return; } - // Now that we declare device_client_id as an uint64, it can't overflow + size_t serialized_device_properties_size = + dawn_wire::SerializedWGPUDevicePropertiesSize( + &requested_device_properties); + DCHECK_NE(0u, serialized_device_properties_size); + + DCHECK_LE(serialized_device_properties_size, transfer_buffer_->GetMaxSize()); + + ScopedTransferBufferPtr buffer(serialized_device_properties_size, helper_, + transfer_buffer_); + + if (!buffer.valid() || buffer.size() < serialized_device_properties_size) { + std::move(request_device_callback).Run(nullptr); + return; + } + + // We declare DawnRequestDeviceSerial as an uint64, so it can't overflow // because we just increment an uint64 by one. - DawnDeviceClientID device_client_id = NextDeviceClientID(); - DCHECK(request_device_callback_map_.find(device_client_id) == + DawnRequestDeviceSerial request_device_serial = NextRequestDeviceSerial(); + DCHECK(request_device_callback_map_.find(request_device_serial) == request_device_callback_map_.end()); - DCHECK(command_serializers_.find(device_client_id) == - command_serializers_.end()); - if (!AddNewCommandSerializer(device_client_id)) { - return false; - } - request_device_callback_map_[device_client_id] = - std::move(request_device_callback); + // Flush because we need to make sure messages that free a previously used + // device are seen first. ReserveDevice may reuse an existing ID. + wire_serializer_->Flush(); - command_serializers_[device_client_id]->RequestDeviceCreation( - requested_adapter_id, requested_device_properties); + dawn_wire::ReservedDevice reservation = wire_client_->ReserveDevice(); - return true; -#else - NOTREACHED(); - return false; + request_device_callback_map_[request_device_serial] = base::BindOnce( + [](dawn_wire::WireClient* wire_client, + dawn_wire::ReservedDevice reservation, + base::OnceCallback<void(WGPUDevice)> callback, bool success) { + WGPUDevice device = reservation.device; + if (!success) { + wire_client->ReclaimDeviceReservation(reservation); + device = nullptr; + } + std::move(callback).Run(device); + }, + wire_client_.get(), reservation, std::move(request_device_callback)); + + dawn_wire::SerializeWGPUDeviceProperties( + &requested_device_properties, reinterpret_cast<char*>(buffer.address())); + + helper_->RequestDevice(request_device_serial, requested_adapter_id, + reservation.id, reservation.generation, + buffer.shm_id(), buffer.offset(), + serialized_device_properties_size); + buffer.Release(); + helper_->Flush(); #endif } -void WebGPUImplementation::AssociateMailbox(GLuint64 device_client_id, +WGPUDevice WebGPUImplementation::DeprecatedEnsureDefaultDeviceSync() { + if (deprecated_default_device_ != nullptr) { + return deprecated_default_device_; + } + + DLOG(WARNING) << "Using deprecated WebGPU device initialization"; + + base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); + RequestAdapterAsync( + PowerPreference::kDefault, + base::BindOnce( + [](WebGPUImplementation* self, WGPUDevice* result, + base::OnceCallback<void()> done, int32_t adapter_id, + const WGPUDeviceProperties& properties, const char* name) { + if (adapter_id < 0) { + std::move(done).Run(); + return; + } + self->RequestDeviceAsync( + static_cast<uint32_t>(adapter_id), properties, + base::BindOnce( + [](WGPUDevice* result, base::OnceCallback<void()> done, + WGPUDevice device) { + *result = device; + std::move(done).Run(); + }, + result, std::move(done))); + }, + this, &deprecated_default_device_, run_loop.QuitClosure())); + run_loop.Run(); + + return deprecated_default_device_; +} + +void WebGPUImplementation::AssociateMailbox(GLuint device_id, GLuint device_generation, - GLuint id, - GLuint generation, + GLuint texture_id, + GLuint texture_generation, GLuint usage, const GLbyte* mailbox) { #if BUILDFLAG(USE_DAWN) @@ -562,37 +557,19 @@ // and need to be resolved prior to the AssociateMailbox command. Otherwise // the service side might not know, for example that the previous texture // using that ID has been released. - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - command_serializer->Flush(); - - helper_->AssociateMailboxImmediate(device_client_id, device_generation, id, - generation, usage, mailbox); + wire_serializer_->Flush(); + helper_->AssociateMailboxImmediate(device_id, device_generation, texture_id, + texture_generation, usage, mailbox); #endif } -void WebGPUImplementation::DissociateMailbox(GLuint64 device_client_id, - GLuint texture_id, +void WebGPUImplementation::DissociateMailbox(GLuint texture_id, GLuint texture_generation) { #if BUILDFLAG(USE_DAWN) // Flush previous Dawn commands that might be rendering to the texture, prior // to Dissociating the shared image from that texture. - DawnClientSerializer* command_serializer = - GetCommandSerializerWithDeviceClientID(device_client_id); - DCHECK(command_serializer); - command_serializer->Flush(); - - helper_->DissociateMailbox(device_client_id, texture_id, texture_generation); -#endif -} - -void WebGPUImplementation::RemoveDevice(DawnDeviceClientID device_client_id) { -#if BUILDFLAG(USE_DAWN) - auto it = command_serializers_.find(device_client_id); - DCHECK(it != command_serializers_.end()); - helper_->RemoveDevice(device_client_id); - command_serializers_.erase(it); + wire_serializer_->Flush(); + helper_->DissociateMailbox(texture_id, texture_generation); #endif }
diff --git a/gpu/command_buffer/client/webgpu_implementation.h b/gpu/command_buffer/client/webgpu_implementation.h index ac288f8a..44422cb 100644 --- a/gpu/command_buffer/client/webgpu_implementation.h +++ b/gpu/command_buffer/client/webgpu_implementation.h
@@ -21,6 +21,10 @@ #include "gpu/command_buffer/client/webgpu_interface.h" #include "ui/gl/buildflags.h" +namespace dawn_wire { +class WireClient; +} + namespace gpu { namespace webgpu { @@ -111,44 +115,35 @@ // WebGPUInterface implementation const DawnProcTable& GetProcs() const override; void FlushCommands() override; - void FlushCommands(DawnDeviceClientID device_client_id) override; - void EnsureAwaitingFlush(DawnDeviceClientID device_client_id, - bool* needs_flush) override; - void FlushAwaitingCommands(DawnDeviceClientID device_client_id) override; + void EnsureAwaitingFlush(bool* needs_flush) override; + void FlushAwaitingCommands() override; void DisconnectContextAndDestroyServer() override; - WGPUDevice GetDevice(DawnDeviceClientID device_client_id) override; - ReservedTexture ReserveTexture(DawnDeviceClientID device_client_id) override; - bool RequestAdapterAsync( + ReservedTexture ReserveTexture(WGPUDevice device) override; + void RequestAdapterAsync( PowerPreference power_preference, base::OnceCallback<void(int32_t, const WGPUDeviceProperties&, const char*)> request_adapter_callback) override; - bool RequestDeviceAsync( + void RequestDeviceAsync( uint32_t requested_adapter_id, const WGPUDeviceProperties& requested_device_properties, - base::OnceCallback<void(bool, DawnDeviceClientID)> - request_device_callback) override; - void RemoveDevice(DawnDeviceClientID device_client_id) override; + base::OnceCallback<void(WGPUDevice)> request_device_callback) override; + + WGPUDevice DeprecatedEnsureDefaultDeviceSync() override; private: const char* GetLogPrefix() const { return "webgpu"; } void CheckGLError() {} DawnRequestAdapterSerial NextRequestAdapterSerial(); - DawnDeviceClientID NextDeviceClientID(); + DawnRequestDeviceSerial NextRequestDeviceSerial(); WebGPUCmdHelper* helper_; #if BUILDFLAG(USE_DAWN) std::unique_ptr<DawnClientMemoryTransferService> memory_transfer_service_; - - DawnClientSerializer* GetCommandSerializerWithDeviceClientID( - DawnDeviceClientID device_client_id) const; - void FlushAllCommandSerializers(); - void ClearAllCommandSerializers(); - bool AddNewCommandSerializer(DawnDeviceClientID device_client_id); - base::flat_map<DawnDeviceClientID, std::unique_ptr<DawnClientSerializer>> - command_serializers_; + std::unique_ptr<DawnClientSerializer> wire_serializer_; + std::unique_ptr<dawn_wire::WireClient> wire_client_; #endif - DawnProcTable procs_ = {}; + WGPUDevice deprecated_default_device_ = nullptr; LogSettings log_settings_; @@ -158,10 +153,9 @@ request_adapter_callback_map_; DawnRequestAdapterSerial request_adapter_serial_ = 0; - base::flat_map<DawnDeviceClientID, - base::OnceCallback<void(bool, DawnDeviceClientID)>> + base::flat_map<DawnRequestDeviceSerial, base::OnceCallback<void(bool)>> request_device_callback_map_; - DawnDeviceClientID device_client_id_ = 0; + DawnRequestDeviceSerial request_device_serial_ = 0; std::atomic_bool lost_{false};
diff --git a/gpu/command_buffer/client/webgpu_implementation_autogen.h b/gpu/command_buffer/client/webgpu_implementation_autogen.h index 8458b85..1e299de 100644 --- a/gpu/command_buffer/client/webgpu_implementation_autogen.h +++ b/gpu/command_buffer/client/webgpu_implementation_autogen.h
@@ -13,15 +13,13 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_ -void AssociateMailbox(GLuint64 device_client_id, +void AssociateMailbox(GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, const GLbyte* mailbox) override; -void DissociateMailbox(GLuint64 device_client_id, - GLuint texture_id, - GLuint texture_generation) override; +void DissociateMailbox(GLuint texture_id, GLuint texture_generation) override; #endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/webgpu_interface.h b/gpu/command_buffer/client/webgpu_interface.h index 9a4668e..df6094f3 100644 --- a/gpu/command_buffer/client/webgpu_interface.h +++ b/gpu/command_buffer/client/webgpu_interface.h
@@ -20,6 +20,8 @@ WGPUTexture texture; uint32_t id; uint32_t generation; + uint32_t deviceId; + uint32_t deviceGeneration; }; class WebGPUInterface : public InterfaceBase { @@ -32,38 +34,35 @@ // Flush all commands. virtual void FlushCommands() = 0; - // Flush all commands on the device client. - virtual void FlushCommands(DawnDeviceClientID device_client_id) = 0; - // Ensure the awaiting flush flag is set on the device client. Returns false // if a flush has already been indicated, or a flush is not needed (there may // be no commands to flush). Returns true if the caller should schedule a // flush. - virtual void EnsureAwaitingFlush(DawnDeviceClientID device_client_id, - bool* needs_flush) = 0; + virtual void EnsureAwaitingFlush(bool* needs_flush) = 0; // If the awaiting flush flag is set, flushes commands. Otherwise, does // nothing. - virtual void FlushAwaitingCommands(DawnDeviceClientID device_client_id) = 0; + virtual void FlushAwaitingCommands() = 0; // Disconnect. All commands should become a no-op and server-side resources // can be freed. virtual void DisconnectContextAndDestroyServer() = 0; - virtual WGPUDevice GetDevice(DawnDeviceClientID device_client_id) = 0; - virtual ReservedTexture ReserveTexture( - DawnDeviceClientID device_client_id) = 0; - virtual bool RequestAdapterAsync( + virtual ReservedTexture ReserveTexture(WGPUDevice device) = 0; + virtual void RequestAdapterAsync( PowerPreference power_preference, base::OnceCallback<void(int32_t, const WGPUDeviceProperties&, const char*)> request_adapter_callback) = 0; - virtual bool RequestDeviceAsync( + virtual void RequestDeviceAsync( uint32_t adapter_service_id, const WGPUDeviceProperties& requested_device_properties, - base::OnceCallback<void(bool, DawnDeviceClientID)> - request_device_callback) = 0; - virtual void RemoveDevice(DawnDeviceClientID device_client_id) = 0; + base::OnceCallback<void(WGPUDevice)> request_device_callback) = 0; + + // Gets or creates a usable WGPUDevice synchronously. It really should not + // be used, and the async request adapter and request device APIs should be + // used instead. + virtual WGPUDevice DeprecatedEnsureDefaultDeviceSync() = 0; // Include the auto-generated part of this class. We split this because // it means we can easily edit the non-auto generated parts right here in
diff --git a/gpu/command_buffer/client/webgpu_interface_autogen.h b/gpu/command_buffer/client/webgpu_interface_autogen.h index 10af23f..9278447 100644 --- a/gpu/command_buffer/client/webgpu_interface_autogen.h +++ b/gpu/command_buffer/client/webgpu_interface_autogen.h
@@ -13,13 +13,12 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_ -virtual void AssociateMailbox(GLuint64 device_client_id, +virtual void AssociateMailbox(GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, const GLbyte* mailbox) = 0; -virtual void DissociateMailbox(GLuint64 device_client_id, - GLuint texture_id, +virtual void DissociateMailbox(GLuint texture_id, GLuint texture_generation) = 0; #endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/webgpu_interface_stub.cc b/gpu/command_buffer/client/webgpu_interface_stub.cc index 4b3e25e..f6acf6ea 100644 --- a/gpu/command_buffer/client/webgpu_interface_stub.cc +++ b/gpu/command_buffer/client/webgpu_interface_stub.cc
@@ -23,34 +23,24 @@ return null_procs_; } void WebGPUInterfaceStub::FlushCommands() {} -void WebGPUInterfaceStub::FlushCommands(DawnDeviceClientID device_client_id) {} -void WebGPUInterfaceStub::EnsureAwaitingFlush( - DawnDeviceClientID device_client_id, - bool* needs_flush) {} -void WebGPUInterfaceStub::FlushAwaitingCommands( - DawnDeviceClientID device_client_id) {} +void WebGPUInterfaceStub::EnsureAwaitingFlush(bool* needs_flush) {} +void WebGPUInterfaceStub::FlushAwaitingCommands() {} void WebGPUInterfaceStub::DisconnectContextAndDestroyServer() {} -WGPUDevice WebGPUInterfaceStub::GetDevice(DawnDeviceClientID device_client_id) { - return nullptr; +ReservedTexture WebGPUInterfaceStub::ReserveTexture(WGPUDevice) { + return {nullptr, 0, 0, 0, 0}; } -ReservedTexture WebGPUInterfaceStub::ReserveTexture( - DawnDeviceClientID device_client_id) { - return {nullptr, 0, 0}; -} -bool WebGPUInterfaceStub::RequestAdapterAsync( +void WebGPUInterfaceStub::RequestAdapterAsync( PowerPreference power_preference, base::OnceCallback<void(int32_t, const WGPUDeviceProperties&, const char*)> - request_adapter_callback) { - return false; -} -bool WebGPUInterfaceStub::RequestDeviceAsync( + request_adapter_callback) {} +void WebGPUInterfaceStub::RequestDeviceAsync( uint32_t adapter_service_id, const WGPUDeviceProperties& requested_device_properties, - base::OnceCallback<void(bool, DawnDeviceClientID)> - request_device_callback) { - return false; + base::OnceCallback<void(WGPUDevice)> request_device_callback) {} + +WGPUDevice WebGPUInterfaceStub::DeprecatedEnsureDefaultDeviceSync() { + return nullptr; } -void WebGPUInterfaceStub::RemoveDevice(DawnDeviceClientID device_client_id) {} // Include the auto-generated part of this class. We split this because // it means we can easily edit the non-auto generated parts right here in
diff --git a/gpu/command_buffer/client/webgpu_interface_stub.h b/gpu/command_buffer/client/webgpu_interface_stub.h index 42353d5..f5d6076 100644 --- a/gpu/command_buffer/client/webgpu_interface_stub.h +++ b/gpu/command_buffer/client/webgpu_interface_stub.h
@@ -25,24 +25,21 @@ // WebGPUInterface implementation const DawnProcTable& GetProcs() const override; void FlushCommands() override; - void FlushCommands(DawnDeviceClientID device_client_id) override; - void EnsureAwaitingFlush(DawnDeviceClientID device_client_id, - bool* needs_flush) override; - void FlushAwaitingCommands(DawnDeviceClientID device_client_id) override; + void EnsureAwaitingFlush(bool* needs_flush) override; + void FlushAwaitingCommands() override; void DisconnectContextAndDestroyServer() override; - WGPUDevice GetDevice(DawnDeviceClientID device_client_id) override; - ReservedTexture ReserveTexture(DawnDeviceClientID device_client_id) override; - bool RequestAdapterAsync( + ReservedTexture ReserveTexture(WGPUDevice device) override; + void RequestAdapterAsync( PowerPreference power_preference, base::OnceCallback<void(int32_t, const WGPUDeviceProperties&, const char*)> request_adapter_callback) override; - bool RequestDeviceAsync( + void RequestDeviceAsync( uint32_t adapter_service_id, const WGPUDeviceProperties& requested_device_properties, - base::OnceCallback<void(bool, DawnDeviceClientID)> - request_device_callback) override; - void RemoveDevice(DawnDeviceClientID device_client_id) override; + base::OnceCallback<void(WGPUDevice)> request_device_callback) override; + + WGPUDevice DeprecatedEnsureDefaultDeviceSync() override; // Include the auto-generated part of this class. We split this because // it means we can easily edit the non-auto generated parts right here in
diff --git a/gpu/command_buffer/client/webgpu_interface_stub_autogen.h b/gpu/command_buffer/client/webgpu_interface_stub_autogen.h index 18a083a..6d23a68 100644 --- a/gpu/command_buffer/client/webgpu_interface_stub_autogen.h +++ b/gpu/command_buffer/client/webgpu_interface_stub_autogen.h
@@ -12,13 +12,11 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_ -void AssociateMailbox(GLuint64 device_client_id, +void AssociateMailbox(GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, const GLbyte* mailbox) override; -void DissociateMailbox(GLuint64 device_client_id, - GLuint texture_id, - GLuint texture_generation) override; +void DissociateMailbox(GLuint texture_id, GLuint texture_generation) override; #endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h b/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h index cf164130..0d89b68 100644 --- a/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h
@@ -12,13 +12,12 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_ -void WebGPUInterfaceStub::AssociateMailbox(GLuint64 /* device_client_id */, +void WebGPUInterfaceStub::AssociateMailbox(GLuint /* device_id */, GLuint /* device_generation */, GLuint /* id */, GLuint /* generation */, GLuint /* usage */, const GLbyte* /* mailbox */) {} -void WebGPUInterfaceStub::DissociateMailbox(GLuint64 /* device_client_id */, - GLuint /* texture_id */, +void WebGPUInterfaceStub::DissociateMailbox(GLuint /* texture_id */, GLuint /* texture_generation */) {} #endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/webgpu_cmd_format.h b/gpu/command_buffer/common/webgpu_cmd_format.h index 7438f69..2bf5ebf 100644 --- a/gpu/command_buffer/common/webgpu_cmd_format.h +++ b/gpu/command_buffer/common/webgpu_cmd_format.h
@@ -27,7 +27,6 @@ struct DawnReturnCommandsInfoHeader { DawnReturnDataHeader return_data_header = {DawnReturnDataType::kDawnCommands}; - DawnDeviceClientID device_client_id; }; static_assert(offsetof(DawnReturnCommandsInfoHeader, return_data_header) == 0, @@ -67,7 +66,7 @@ struct DawnReturnRequestDeviceInfo { DawnReturnDataHeader return_data_header = { DawnReturnDataType::kRequestedDeviceReturnInfo}; - DawnDeviceClientID device_client_id; + DawnRequestDeviceSerial request_device_serial; bool is_request_device_success; };
diff --git a/gpu/command_buffer/common/webgpu_cmd_format_autogen.h b/gpu/command_buffer/common/webgpu_cmd_format_autogen.h index 5a7f561..a82850b 100644 --- a/gpu/command_buffer/common/webgpu_cmd_format_autogen.h +++ b/gpu/command_buffer/common/webgpu_cmd_format_autogen.h
@@ -25,45 +25,39 @@ void SetHeader() { header.SetCmd<ValueType>(); } - void Init(uint64_t _device_client_id, - uint32_t _commands_shm_id, + void Init(uint32_t _commands_shm_id, uint32_t _commands_shm_offset, uint32_t _size) { SetHeader(); - device_client_id = _device_client_id; commands_shm_id = _commands_shm_id; commands_shm_offset = _commands_shm_offset; size = _size; } void* Set(void* cmd, - uint64_t _device_client_id, uint32_t _commands_shm_id, uint32_t _commands_shm_offset, uint32_t _size) { - static_cast<ValueType*>(cmd)->Init(_device_client_id, _commands_shm_id, - _commands_shm_offset, _size); + static_cast<ValueType*>(cmd)->Init(_commands_shm_id, _commands_shm_offset, + _size); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; - uint32_t device_client_id; uint32_t commands_shm_id; uint32_t commands_shm_offset; uint32_t size; }; -static_assert(sizeof(DawnCommands) == 20, "size of DawnCommands should be 20"); +static_assert(sizeof(DawnCommands) == 16, "size of DawnCommands should be 16"); static_assert(offsetof(DawnCommands, header) == 0, "offset of DawnCommands header should be 0"); -static_assert(offsetof(DawnCommands, device_client_id) == 4, - "offset of DawnCommands device_client_id should be 4"); -static_assert(offsetof(DawnCommands, commands_shm_id) == 8, - "offset of DawnCommands commands_shm_id should be 8"); -static_assert(offsetof(DawnCommands, commands_shm_offset) == 12, - "offset of DawnCommands commands_shm_offset should be 12"); -static_assert(offsetof(DawnCommands, size) == 16, - "offset of DawnCommands size should be 16"); +static_assert(offsetof(DawnCommands, commands_shm_id) == 4, + "offset of DawnCommands commands_shm_id should be 4"); +static_assert(offsetof(DawnCommands, commands_shm_offset) == 8, + "offset of DawnCommands commands_shm_offset should be 8"); +static_assert(offsetof(DawnCommands, size) == 12, + "offset of DawnCommands size should be 12"); struct AssociateMailboxImmediate { typedef AssociateMailboxImmediate ValueType; @@ -81,16 +75,14 @@ void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); } - void Init(GLuint64 _device_client_id, + void Init(GLuint _device_id, GLuint _device_generation, GLuint _id, GLuint _generation, GLuint _usage, const GLbyte* _mailbox) { SetHeader(); - gles2::GLES2Util::MapUint64ToTwoUint32( - static_cast<uint64_t>(_device_client_id), &device_client_id_0, - &device_client_id_1); + device_id = _device_id; device_generation = _device_generation; id = _id; generation = _generation; @@ -99,51 +91,41 @@ } void* Set(void* cmd, - GLuint64 _device_client_id, + GLuint _device_id, GLuint _device_generation, GLuint _id, GLuint _generation, GLuint _usage, const GLbyte* _mailbox) { - static_cast<ValueType*>(cmd)->Init(_device_client_id, _device_generation, - _id, _generation, _usage, _mailbox); + static_cast<ValueType*>(cmd)->Init(_device_id, _device_generation, _id, + _generation, _usage, _mailbox); const uint32_t size = ComputeSize(); return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); } - GLuint64 device_client_id() const volatile { - return static_cast<GLuint64>(gles2::GLES2Util::MapTwoUint32ToUint64( - device_client_id_0, device_client_id_1)); - } - gpu::CommandHeader header; - uint32_t device_client_id_0; - uint32_t device_client_id_1; + uint32_t device_id; uint32_t device_generation; uint32_t id; uint32_t generation; uint32_t usage; }; -static_assert(sizeof(AssociateMailboxImmediate) == 28, - "size of AssociateMailboxImmediate should be 28"); +static_assert(sizeof(AssociateMailboxImmediate) == 24, + "size of AssociateMailboxImmediate should be 24"); static_assert(offsetof(AssociateMailboxImmediate, header) == 0, "offset of AssociateMailboxImmediate header should be 0"); +static_assert(offsetof(AssociateMailboxImmediate, device_id) == 4, + "offset of AssociateMailboxImmediate device_id should be 4"); static_assert( - offsetof(AssociateMailboxImmediate, device_client_id_0) == 4, - "offset of AssociateMailboxImmediate device_client_id_0 should be 4"); -static_assert( - offsetof(AssociateMailboxImmediate, device_client_id_1) == 8, - "offset of AssociateMailboxImmediate device_client_id_1 should be 8"); -static_assert( - offsetof(AssociateMailboxImmediate, device_generation) == 12, - "offset of AssociateMailboxImmediate device_generation should be 12"); -static_assert(offsetof(AssociateMailboxImmediate, id) == 16, - "offset of AssociateMailboxImmediate id should be 16"); -static_assert(offsetof(AssociateMailboxImmediate, generation) == 20, - "offset of AssociateMailboxImmediate generation should be 20"); -static_assert(offsetof(AssociateMailboxImmediate, usage) == 24, - "offset of AssociateMailboxImmediate usage should be 24"); + offsetof(AssociateMailboxImmediate, device_generation) == 8, + "offset of AssociateMailboxImmediate device_generation should be 8"); +static_assert(offsetof(AssociateMailboxImmediate, id) == 12, + "offset of AssociateMailboxImmediate id should be 12"); +static_assert(offsetof(AssociateMailboxImmediate, generation) == 16, + "offset of AssociateMailboxImmediate generation should be 16"); +static_assert(offsetof(AssociateMailboxImmediate, usage) == 20, + "offset of AssociateMailboxImmediate usage should be 20"); struct DissociateMailbox { typedef DissociateMailbox ValueType; @@ -157,50 +139,30 @@ void SetHeader() { header.SetCmd<ValueType>(); } - void Init(GLuint64 _device_client_id, - GLuint _texture_id, - GLuint _texture_generation) { + void Init(GLuint _texture_id, GLuint _texture_generation) { SetHeader(); - gles2::GLES2Util::MapUint64ToTwoUint32( - static_cast<uint64_t>(_device_client_id), &device_client_id_0, - &device_client_id_1); texture_id = _texture_id; texture_generation = _texture_generation; } - void* Set(void* cmd, - GLuint64 _device_client_id, - GLuint _texture_id, - GLuint _texture_generation) { - static_cast<ValueType*>(cmd)->Init(_device_client_id, _texture_id, - _texture_generation); + void* Set(void* cmd, GLuint _texture_id, GLuint _texture_generation) { + static_cast<ValueType*>(cmd)->Init(_texture_id, _texture_generation); return NextCmdAddress<ValueType>(cmd); } - GLuint64 device_client_id() const volatile { - return static_cast<GLuint64>(gles2::GLES2Util::MapTwoUint32ToUint64( - device_client_id_0, device_client_id_1)); - } - gpu::CommandHeader header; - uint32_t device_client_id_0; - uint32_t device_client_id_1; uint32_t texture_id; uint32_t texture_generation; }; -static_assert(sizeof(DissociateMailbox) == 20, - "size of DissociateMailbox should be 20"); +static_assert(sizeof(DissociateMailbox) == 12, + "size of DissociateMailbox should be 12"); static_assert(offsetof(DissociateMailbox, header) == 0, "offset of DissociateMailbox header should be 0"); -static_assert(offsetof(DissociateMailbox, device_client_id_0) == 4, - "offset of DissociateMailbox device_client_id_0 should be 4"); -static_assert(offsetof(DissociateMailbox, device_client_id_1) == 8, - "offset of DissociateMailbox device_client_id_1 should be 8"); -static_assert(offsetof(DissociateMailbox, texture_id) == 12, - "offset of DissociateMailbox texture_id should be 12"); -static_assert(offsetof(DissociateMailbox, texture_generation) == 16, - "offset of DissociateMailbox texture_generation should be 16"); +static_assert(offsetof(DissociateMailbox, texture_id) == 4, + "offset of DissociateMailbox texture_id should be 4"); +static_assert(offsetof(DissociateMailbox, texture_generation) == 8, + "offset of DissociateMailbox texture_generation should be 8"); struct RequestAdapter { typedef RequestAdapter ValueType; @@ -254,14 +216,18 @@ void SetHeader() { header.SetCmd<ValueType>(); } - void Init(uint64_t _device_client_id, + void Init(uint64_t _request_device_serial, uint32_t _adapter_service_id, + uint32_t _device_id, + uint32_t _device_generation, uint32_t _request_device_properties_shm_id, uint32_t _request_device_properties_shm_offset, uint32_t _request_device_properties_size) { SetHeader(); - device_client_id = _device_client_id; + request_device_serial = _request_device_serial; adapter_service_id = _adapter_service_id; + device_id = _device_id; + device_generation = _device_generation; request_device_properties_shm_id = _request_device_properties_shm_id; request_device_properties_shm_offset = _request_device_properties_shm_offset; @@ -269,75 +235,51 @@ } void* Set(void* cmd, - uint64_t _device_client_id, + uint64_t _request_device_serial, uint32_t _adapter_service_id, + uint32_t _device_id, + uint32_t _device_generation, uint32_t _request_device_properties_shm_id, uint32_t _request_device_properties_shm_offset, uint32_t _request_device_properties_size) { - static_cast<ValueType*>(cmd)->Init(_device_client_id, _adapter_service_id, - _request_device_properties_shm_id, - _request_device_properties_shm_offset, - _request_device_properties_size); + static_cast<ValueType*>(cmd)->Init( + _request_device_serial, _adapter_service_id, _device_id, + _device_generation, _request_device_properties_shm_id, + _request_device_properties_shm_offset, _request_device_properties_size); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; - uint32_t device_client_id; + uint32_t request_device_serial; uint32_t adapter_service_id; + uint32_t device_id; + uint32_t device_generation; uint32_t request_device_properties_shm_id; uint32_t request_device_properties_shm_offset; uint32_t request_device_properties_size; }; -static_assert(sizeof(RequestDevice) == 24, - "size of RequestDevice should be 24"); +static_assert(sizeof(RequestDevice) == 32, + "size of RequestDevice should be 32"); static_assert(offsetof(RequestDevice, header) == 0, "offset of RequestDevice header should be 0"); -static_assert(offsetof(RequestDevice, device_client_id) == 4, - "offset of RequestDevice device_client_id should be 4"); +static_assert(offsetof(RequestDevice, request_device_serial) == 4, + "offset of RequestDevice request_device_serial should be 4"); static_assert(offsetof(RequestDevice, adapter_service_id) == 8, "offset of RequestDevice adapter_service_id should be 8"); +static_assert(offsetof(RequestDevice, device_id) == 12, + "offset of RequestDevice device_id should be 12"); +static_assert(offsetof(RequestDevice, device_generation) == 16, + "offset of RequestDevice device_generation should be 16"); static_assert( - offsetof(RequestDevice, request_device_properties_shm_id) == 12, - "offset of RequestDevice request_device_properties_shm_id should be 12"); + offsetof(RequestDevice, request_device_properties_shm_id) == 20, + "offset of RequestDevice request_device_properties_shm_id should be 20"); static_assert(offsetof(RequestDevice, request_device_properties_shm_offset) == - 16, + 24, "offset of RequestDevice request_device_properties_shm_offset " - "should be 16"); + "should be 24"); static_assert( - offsetof(RequestDevice, request_device_properties_size) == 20, - "offset of RequestDevice request_device_properties_size should be 20"); - -struct RemoveDevice { - typedef RemoveDevice ValueType; - static const CommandId kCmdId = kRemoveDevice; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init(uint64_t _device_client_id) { - SetHeader(); - device_client_id = _device_client_id; - } - - void* Set(void* cmd, uint64_t _device_client_id) { - static_cast<ValueType*>(cmd)->Init(_device_client_id); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32_t device_client_id; -}; - -static_assert(sizeof(RemoveDevice) == 8, "size of RemoveDevice should be 8"); -static_assert(offsetof(RemoveDevice, header) == 0, - "offset of RemoveDevice header should be 0"); -static_assert(offsetof(RemoveDevice, device_client_id) == 4, - "offset of RemoveDevice device_client_id should be 4"); + offsetof(RequestDevice, request_device_properties_size) == 28, + "offset of RequestDevice request_device_properties_size should be 28"); #endif // GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_FORMAT_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/webgpu_cmd_format_test_autogen.h b/gpu/command_buffer/common/webgpu_cmd_format_test_autogen.h index 589388b..3234f419 100644 --- a/gpu/command_buffer/common/webgpu_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/webgpu_cmd_format_test_autogen.h
@@ -17,15 +17,14 @@ TEST_F(WebGPUFormatTest, DawnCommands) { cmds::DawnCommands& cmd = *GetBufferAs<cmds::DawnCommands>(); void* next_cmd = - cmd.Set(&cmd, static_cast<uint64_t>(11), static_cast<uint32_t>(12), - static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + cmd.Set(&cmd, static_cast<uint32_t>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); EXPECT_EQ(static_cast<uint32_t>(cmds::DawnCommands::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<uint64_t>(11), cmd.device_client_id); - EXPECT_EQ(static_cast<uint32_t>(12), cmd.commands_shm_id); - EXPECT_EQ(static_cast<uint32_t>(13), cmd.commands_shm_offset); - EXPECT_EQ(static_cast<uint32_t>(14), cmd.size); + EXPECT_EQ(static_cast<uint32_t>(11), cmd.commands_shm_id); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.commands_shm_offset); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.size); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } @@ -52,14 +51,14 @@ cmds::AssociateMailboxImmediate& cmd = *GetBufferAs<cmds::AssociateMailboxImmediate>(); void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint64>(11), static_cast<GLuint>(12), + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), static_cast<GLuint>(13), static_cast<GLuint>(14), static_cast<GLuint>(15), data); EXPECT_EQ(static_cast<uint32_t>(cmds::AssociateMailboxImmediate::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint64>(11), cmd.device_client_id()); + EXPECT_EQ(static_cast<GLuint>(11), cmd.device_id); EXPECT_EQ(static_cast<GLuint>(12), cmd.device_generation); EXPECT_EQ(static_cast<GLuint>(13), cmd.id); EXPECT_EQ(static_cast<GLuint>(14), cmd.generation); @@ -70,14 +69,13 @@ TEST_F(WebGPUFormatTest, DissociateMailbox) { cmds::DissociateMailbox& cmd = *GetBufferAs<cmds::DissociateMailbox>(); - void* next_cmd = cmd.Set(&cmd, static_cast<GLuint64>(11), - static_cast<GLuint>(12), static_cast<GLuint>(13)); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12)); EXPECT_EQ(static_cast<uint32_t>(cmds::DissociateMailbox::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint64>(11), cmd.device_client_id()); - EXPECT_EQ(static_cast<GLuint>(12), cmd.texture_id); - EXPECT_EQ(static_cast<GLuint>(13), cmd.texture_generation); + EXPECT_EQ(static_cast<GLuint>(11), cmd.texture_id); + EXPECT_EQ(static_cast<GLuint>(12), cmd.texture_generation); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } @@ -98,26 +96,19 @@ void* next_cmd = cmd.Set(&cmd, static_cast<uint64_t>(11), static_cast<uint32_t>(12), static_cast<uint32_t>(13), static_cast<uint32_t>(14), - static_cast<uint32_t>(15)); + static_cast<uint32_t>(15), static_cast<uint32_t>(16), + static_cast<uint32_t>(17)); EXPECT_EQ(static_cast<uint32_t>(cmds::RequestDevice::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<uint64_t>(11), cmd.device_client_id); + EXPECT_EQ(static_cast<uint64_t>(11), cmd.request_device_serial); EXPECT_EQ(static_cast<uint32_t>(12), cmd.adapter_service_id); - EXPECT_EQ(static_cast<uint32_t>(13), cmd.request_device_properties_shm_id); - EXPECT_EQ(static_cast<uint32_t>(14), + EXPECT_EQ(static_cast<uint32_t>(13), cmd.device_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.device_generation); + EXPECT_EQ(static_cast<uint32_t>(15), cmd.request_device_properties_shm_id); + EXPECT_EQ(static_cast<uint32_t>(16), cmd.request_device_properties_shm_offset); - EXPECT_EQ(static_cast<uint32_t>(15), cmd.request_device_properties_size); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - -TEST_F(WebGPUFormatTest, RemoveDevice) { - cmds::RemoveDevice& cmd = *GetBufferAs<cmds::RemoveDevice>(); - void* next_cmd = cmd.Set(&cmd, static_cast<uint64_t>(11)); - EXPECT_EQ(static_cast<uint32_t>(cmds::RemoveDevice::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<uint64_t>(11), cmd.device_client_id); + EXPECT_EQ(static_cast<uint32_t>(17), cmd.request_device_properties_size); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); }
diff --git a/gpu/command_buffer/common/webgpu_cmd_ids.h b/gpu/command_buffer/common/webgpu_cmd_ids.h index 6a5a107..6b26128 100644 --- a/gpu/command_buffer/common/webgpu_cmd_ids.h +++ b/gpu/command_buffer/common/webgpu_cmd_ids.h
@@ -17,7 +17,7 @@ const char* GetCommandName(CommandId command_id); using DawnRequestAdapterSerial = uint64_t; -using DawnDeviceClientID = uint64_t; +using DawnRequestDeviceSerial = uint64_t; } // namespace webgpu } // namespace gpu
diff --git a/gpu/command_buffer/common/webgpu_cmd_ids_autogen.h b/gpu/command_buffer/common/webgpu_cmd_ids_autogen.h index 6ebfffd..3e70690 100644 --- a/gpu/command_buffer/common/webgpu_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/webgpu_cmd_ids_autogen.h
@@ -16,8 +16,7 @@ OP(AssociateMailboxImmediate) /* 257 */ \ OP(DissociateMailbox) /* 258 */ \ OP(RequestAdapter) /* 259 */ \ - OP(RequestDevice) /* 260 */ \ - OP(RemoveDevice) /* 261 */ + OP(RequestDevice) /* 260 */ enum CommandId { kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index 233a6ff..4b033949 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -51,8 +51,7 @@ class WireServerCommandSerializer : public dawn_wire::CommandSerializer { public: - WireServerCommandSerializer(DecoderClient* client, - DawnDeviceClientID device_client_id); + explicit WireServerCommandSerializer(DecoderClient* client); ~WireServerCommandSerializer() override = default; size_t GetMaximumAllocationSize() const final; void* GetCmdSpace(size_t size) final; @@ -64,9 +63,7 @@ size_t put_offset_; }; -WireServerCommandSerializer::WireServerCommandSerializer( - DecoderClient* client, - DawnDeviceClientID device_client_id) +WireServerCommandSerializer::WireServerCommandSerializer(DecoderClient* client) : client_(client), buffer_(kMaxWireBufferSize), put_offset_(offsetof(cmds::DawnReturnCommandsInfo, deserialized_buffer)) { @@ -76,7 +73,6 @@ reinterpret_cast<cmds::DawnReturnCommandsInfoHeader*>(&buffer_[0]); header->return_data_header.return_data_type = DawnReturnDataType::kDawnCommands; - header->device_client_id = device_client_id; } size_t WireServerCommandSerializer::GetMaximumAllocationSize() const { @@ -141,184 +137,6 @@ } } -class DawnDeviceAndWireServer { - public: - DawnDeviceAndWireServer( - DecoderClient* client, - WGPUDevice wgpu_device, - DawnDeviceClientID device_client_id, - DawnServiceMemoryTransferService* memory_transfer_service); - ~DawnDeviceAndWireServer(); - - WGPUDevice GetWGPUDevice() const; - bool HasPollingWork() const; - void PerformPollingWork(); - error::Error HandleDawnCommands(const volatile char* dawn_commands, - size_t size); - - error::Error AssociateMailbox( - SharedImageRepresentationFactory* shared_image_representation_factory, - const Mailbox& mailbox, - uint32_t texture_id, - uint32_t texture_generation, - uint32_t usage); - error::Error DissociateMailbox(uint32_t texture_id, - uint32_t texture_generation); - - private: - WGPUDevice wgpu_device_ = nullptr; - std::unique_ptr<dawn_wire::WireServer> wire_server_; - std::unique_ptr<WireServerCommandSerializer> wire_serializer_; - const DawnProcTable dawn_procs_; - - // Helper struct which holds a representation and its ScopedAccess, ensuring - // safe destruction order. - struct SharedImageRepresentationAndAccess { - std::unique_ptr<SharedImageRepresentationDawn> representation; - std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> access; - }; - - // Map from the <ID, generation> pair for a wire texture to the shared image - // representation and access for it. - base::flat_map<std::tuple<uint32_t, uint32_t>, - std::unique_ptr<SharedImageRepresentationAndAccess>> - associated_shared_image_map_; - - bool has_polling_work_ = false; -}; - -DawnDeviceAndWireServer::DawnDeviceAndWireServer( - DecoderClient* client, - WGPUDevice wgpu_device, - DawnDeviceClientID device_client_id, - DawnServiceMemoryTransferService* memory_transfer_service) - : wgpu_device_(wgpu_device), - wire_serializer_( - std::make_unique<WireServerCommandSerializer>(client, - device_client_id)), - dawn_procs_(dawn_native::GetProcs()) { - DCHECK(client); - DCHECK(wgpu_device); - DCHECK(memory_transfer_service); - - dawn_wire::WireServerDescriptor descriptor = {}; - descriptor.device = wgpu_device_; - descriptor.procs = &dawn_procs_; - descriptor.serializer = wire_serializer_.get(); - descriptor.memoryTransferService = memory_transfer_service; - wire_server_ = std::make_unique<dawn_wire::WireServer>(descriptor); -} - -DawnDeviceAndWireServer::~DawnDeviceAndWireServer() { - associated_shared_image_map_.clear(); - - // Reset the wire server first so all objects are destroyed before the - // device. - // TODO(enga): Handle Device/Context lost. - wire_server_ = nullptr; - dawn_procs_.deviceRelease(wgpu_device_); -} - -WGPUDevice DawnDeviceAndWireServer::GetWGPUDevice() const { - return wgpu_device_; -} - -void DawnDeviceAndWireServer::PerformPollingWork() { - has_polling_work_ = dawn_native::DeviceTick(wgpu_device_); - wire_serializer_->Flush(); -} - -error::Error DawnDeviceAndWireServer::HandleDawnCommands( - const volatile char* dawn_commands, - size_t size) { - if (!wire_server_->HandleCommands(dawn_commands, size)) { - NOTREACHED(); - return error::kLostContext; - } - has_polling_work_ = dawn_native::DeviceTick(wgpu_device_); - wire_serializer_->Flush(); - return error::kNoError; -} - -error::Error DawnDeviceAndWireServer::AssociateMailbox( - SharedImageRepresentationFactory* shared_image_representation_factory, - const Mailbox& mailbox, - uint32_t texture_id, - uint32_t texture_generation, - uint32_t usage) { - static constexpr uint32_t kAllowedTextureUsages = static_cast<uint32_t>( - WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst | - WGPUTextureUsage_Sampled | WGPUTextureUsage_OutputAttachment); - if (usage & ~kAllowedTextureUsages) { - DLOG(ERROR) << "AssociateMailbox: Invalid usage"; - return error::kInvalidArguments; - } - WGPUTextureUsage wgpu_usage = static_cast<WGPUTextureUsage>(usage); - - // Create a WGPUTexture from the mailbox. - std::unique_ptr<SharedImageRepresentationDawn> shared_image = - shared_image_representation_factory->ProduceDawn(mailbox, wgpu_device_); - if (!shared_image) { - DLOG(ERROR) << "AssociateMailbox: Couldn't produce shared image"; - return error::kInvalidArguments; - } - - // TODO(cwallez@chromium.org): Handle texture clearing. We should either - // pre-clear textures, or implement a way to detect whether DAWN has cleared - // a texture. crbug.com/1036080 - std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> - shared_image_access = shared_image->BeginScopedAccess( - wgpu_usage, SharedImageRepresentation::AllowUnclearedAccess::kYes); - if (!shared_image_access) { - DLOG(ERROR) << "AssociateMailbox: Couldn't begin shared image access"; - return error::kInvalidArguments; - } - - // Inject the texture in the dawn_wire::Server and remember which shared image - // it is associated with. - if (!wire_server_->InjectTexture(shared_image_access->texture(), texture_id, - texture_generation)) { - DLOG(ERROR) << "AssociateMailbox: Invalid texture ID"; - return error::kInvalidArguments; - } - - std::unique_ptr<SharedImageRepresentationAndAccess> - representation_and_access = - std::make_unique<SharedImageRepresentationAndAccess>(); - representation_and_access->representation = std::move(shared_image); - representation_and_access->access = std::move(shared_image_access); - - std::tuple<uint32_t, uint32_t> id_and_generation{texture_id, - texture_generation}; - auto insertion = associated_shared_image_map_.emplace( - id_and_generation, std::move(representation_and_access)); - - // InjectTexture already validated that the (ID, generation) can't have been - // registered before. - DCHECK(insertion.second); - - return error::kNoError; -} - -error::Error DawnDeviceAndWireServer::DissociateMailbox( - uint32_t texture_id, - uint32_t texture_generation) { - std::tuple<uint32_t, uint32_t> id_and_generation{texture_id, - texture_generation}; - auto it = associated_shared_image_map_.find(id_and_generation); - if (it == associated_shared_image_map_.end()) { - DLOG(ERROR) << "DissociateMailbox: Invalid texture ID"; - return error::kInvalidArguments; - } - - associated_shared_image_map_.erase(it); - return error::kNoError; -} - -bool DawnDeviceAndWireServer::HasPollingWork() const { - return has_polling_work_; -} - } // namespace class WebGPUDecoderImpl final : public WebGPUDecoder { @@ -397,21 +215,33 @@ bool HasMoreIdleWork() const override { return false; } void PerformIdleWork() override {} - bool HasPollingWork() const override { - for (auto& iter : dawn_device_and_wire_servers_) { - if (iter.second->HasPollingWork()) { - return true; - } - } - return false; - } + bool HasPollingWork() const override { return has_polling_work_; } void PerformPollingWork() override { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "WebGPUDecoderImpl::PerformPollingWork"); - for (auto& iter : dawn_device_and_wire_servers_) { - iter.second->PerformPollingWork(); + has_polling_work_ = false; + if (known_devices_.empty()) { + return; } + + // Prune the list of known devices to remove ones that are no longer valid. + // And call DeviceTick() on all valid devices. + auto it = + std::remove_if(known_devices_.begin(), known_devices_.end(), + [this](std::pair<uint32_t, uint32_t> id_generation) { + WGPUDevice device = wire_server_->GetDevice( + id_generation.first, id_generation.second); + if (device != nullptr) { + if (dawn_native::DeviceTick(device)) { + has_polling_work_ = true; + } + return false; + } + return true; + }); + known_devices_.erase(it, known_devices_.end()); + wire_serializer_->Flush(); } TextureBase* GetTextureBase(uint32_t client_id) override { @@ -564,16 +394,17 @@ int32_t GetPreferredAdapterIndex(PowerPreference power_preference) const; - error::Error InitDawnDeviceAndSetWireServer( + error::Error InitDawnDevice( int32_t requested_adapter_index, - DawnDeviceClientID device_client_id, + uint32_t device_id, + uint32_t device_generation, const WGPUDeviceProperties& requested_device_properties); void SendAdapterProperties(DawnRequestAdapterSerial request_adapter_serial, int32_t adapter_service_id, const dawn_native::Adapter& adapter, const char* error_message = nullptr); - void SendRequestedDeviceInfo(DawnDeviceClientID device_client_id, + void SendRequestedDeviceInfo(DawnRequestDeviceSerial request_device_serial, bool is_request_device_success); const GrContextType gr_context_type_; @@ -581,9 +412,6 @@ std::unique_ptr<SharedImageRepresentationFactory> shared_image_representation_factory_; - base::flat_map<DawnDeviceClientID, std::unique_ptr<DawnDeviceAndWireServer>> - dawn_device_and_wire_servers_; - std::unique_ptr<dawn_platform::Platform> dawn_platform_; std::unique_ptr<DawnServiceMemoryTransferService> memory_transfer_service_; std::unique_ptr<dawn_native::Instance> dawn_instance_; @@ -592,6 +420,30 @@ std::vector<std::string> force_enabled_toggles_; std::vector<std::string> force_disabled_toggles_; + std::unique_ptr<dawn_wire::WireServer> wire_server_; + std::unique_ptr<WireServerCommandSerializer> wire_serializer_; + + // Helper struct which holds a representation and its ScopedAccess, ensuring + // safe destruction order. + struct SharedImageRepresentationAndAccess { + std::unique_ptr<SharedImageRepresentationDawn> representation; + std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> access; + }; + + // Map from the <ID, generation> pair for a wire texture to the shared image + // representation and access for it. + base::flat_map<std::tuple<uint32_t, uint32_t>, + std::unique_ptr<SharedImageRepresentationAndAccess>> + associated_shared_image_map_; + + // A list of (id, generation) device pairs that we've seen on the wire. + // Not all of them may be valid, so it gets pruned when iterating through it + // in PerformPollingWork. Dawn will never reuse a previously allocated + // <ID, generation> pair. + std::vector<std::pair<uint32_t, uint32_t>> known_devices_; + + bool has_polling_work_ = false; + DISALLOW_COPY_AND_ASSIGN(WebGPUDecoderImpl); }; @@ -634,13 +486,20 @@ memory_tracker)), dawn_platform_(new DawnPlatform()), memory_transfer_service_(new DawnServiceMemoryTransferService(this)), - dawn_instance_(new dawn_native::Instance()) { + dawn_instance_(new dawn_native::Instance()), + wire_serializer_(new WireServerCommandSerializer(client)) { dawn_instance_->SetPlatform(dawn_platform_.get()); dawn_instance_->EnableBackendValidation( gpu_preferences.enable_dawn_backend_validation); force_enabled_toggles_ = gpu_preferences.enabled_dawn_features_list; force_disabled_toggles_ = gpu_preferences.disabled_dawn_features_list; + + dawn_wire::WireServerDescriptor descriptor = {}; + descriptor.procs = &dawn_native::GetProcs(); + descriptor.serializer = wire_serializer_.get(); + descriptor.memoryTransferService = memory_transfer_service_.get(); + wire_server_ = std::make_unique<dawn_wire::WireServer>(descriptor); } WebGPUDecoderImpl::~WebGPUDecoderImpl() { @@ -648,7 +507,8 @@ } void WebGPUDecoderImpl::Destroy(bool have_context) { - dawn_device_and_wire_servers_.clear(); + associated_shared_image_map_.clear(); + wire_server_ = nullptr; } ContextResult WebGPUDecoderImpl::Initialize() { @@ -656,20 +516,16 @@ return ContextResult::kSuccess; } -error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer( +error::Error WebGPUDecoderImpl::InitDawnDevice( int32_t requested_adapter_index, - DawnDeviceClientID device_client_id, + uint32_t device_id, + uint32_t device_generation, const WGPUDeviceProperties& request_device_properties) { DCHECK_LE(0, requested_adapter_index); DCHECK_LT(static_cast<size_t>(requested_adapter_index), dawn_adapters_.size()); - if (dawn_device_and_wire_servers_.find(device_client_id) != - dawn_device_and_wire_servers_.end()) { - return error::kLostContext; - } - dawn_native::DeviceDescriptor device_descriptor; if (request_device_properties.textureCompressionBC) { device_descriptor.requiredExtensions.push_back("texture_compression_bc"); @@ -697,10 +553,18 @@ return error::kInvalidArguments; } - dawn_device_and_wire_servers_[device_client_id] = - std::make_unique<DawnDeviceAndWireServer>(client(), wgpu_device, - device_client_id, - memory_transfer_service_.get()); + if (!wire_server_->InjectDevice(wgpu_device, device_id, device_generation)) { + return error::kInvalidArguments; + } + + // Device injection takes a ref. The wire now owns the device so release it. + dawn_native::GetProcs().deviceRelease(wgpu_device); + + // Save the id and generation of the device. Now, we can query the server for + // this pair to discover if this device has been destroyed. The list will be + // checked in PerformPollingWork to tick all the live devices and remove all + // the dead ones. + known_devices_.emplace_back(device_id, device_generation); return error::kNoError; } @@ -921,12 +785,12 @@ } void WebGPUDecoderImpl::SendRequestedDeviceInfo( - DawnDeviceClientID device_client_id, + DawnRequestDeviceSerial request_device_serial, bool is_request_device_success) { cmds::DawnReturnRequestDeviceInfo return_request_device_info; DCHECK_EQ(DawnReturnDataType::kRequestedDeviceReturnInfo, return_request_device_info.return_data_header.return_data_type); - return_request_device_info.device_client_id = device_client_id; + return_request_device_info.request_device_serial = request_device_serial; return_request_device_info.is_request_device_success = is_request_device_success; @@ -978,9 +842,11 @@ const volatile void* cmd_data) { const volatile webgpu::cmds::RequestDevice& c = *static_cast<const volatile webgpu::cmds::RequestDevice*>(cmd_data); - DawnDeviceClientID device_client_id = - static_cast<DawnDeviceClientID>(c.device_client_id); + DawnRequestDeviceSerial request_device_serial = + static_cast<DawnRequestDeviceSerial>(c.request_device_serial); uint32_t adapter_service_id = static_cast<uint32_t>(c.adapter_service_id); + uint32_t device_id = static_cast<uint32_t>(c.device_id); + uint32_t device_generation = static_cast<uint32_t>(c.device_generation); uint32_t request_device_properties_shm_id = static_cast<uint32_t>(c.request_device_properties_shm_id); uint32_t request_device_properties_shm_offset = @@ -999,15 +865,18 @@ return error::kOutOfBounds; } - dawn_wire::DeserializeWGPUDeviceProperties(&device_properties, - shm_device_properties); + if (!dawn_wire::DeserializeWGPUDeviceProperties( + &device_properties, shm_device_properties, + request_device_properties_size)) { + return error::kOutOfBounds; + } } - error::Error init_dawn_device_error = InitDawnDeviceAndSetWireServer( - adapter_service_id, device_client_id, device_properties); - SendRequestedDeviceInfo(device_client_id, - !error::IsError(init_dawn_device_error)); - return init_dawn_device_error; + error::Error init_device_error = InitDawnDevice( + adapter_service_id, device_id, device_generation, device_properties); + SendRequestedDeviceInfo(request_device_serial, + !error::IsError(init_device_error)); + return init_device_error; } error::Error WebGPUDecoderImpl::HandleDawnCommands( @@ -1018,8 +887,6 @@ uint32_t size = static_cast<uint32_t>(c.size); uint32_t commands_shm_id = static_cast<uint32_t>(c.commands_shm_id); uint32_t commands_shm_offset = static_cast<uint32_t>(c.commands_shm_offset); - DawnDeviceClientID device_client_id = - static_cast<DawnDeviceClientID>(c.device_client_id); const volatile char* shm_commands = GetSharedMemoryAs<const volatile char*>( commands_shm_id, commands_shm_offset, size); @@ -1035,12 +902,17 @@ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), "WebGPUDecoderImpl::HandleDawnCommands", "bytes", size); - auto iter = dawn_device_and_wire_servers_.find(device_client_id); - if (iter == dawn_device_and_wire_servers_.end()) { - return error::kInvalidArguments; + if (!wire_server_->HandleCommands(shm_commands, size)) { + NOTREACHED(); + return error::kLostContext; } - return iter->second->HandleDawnCommands(shm_commands, size); + // TODO(crbug.com/1174145): This is O(N) where N is the number of devices. + // Multiple submits would be O(N*M). We should find a way to more + // intelligently poll for work on only the devices that need it. + PerformPollingWork(); + + return error::kNoError; } error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate( @@ -1049,12 +921,11 @@ const volatile webgpu::cmds::AssociateMailboxImmediate& c = *static_cast<const volatile webgpu::cmds::AssociateMailboxImmediate*>( cmd_data); - DawnDeviceClientID device_client_id = - static_cast<DawnDeviceClientID>(c.device_client_id()); + uint32_t device_id = static_cast<uint32_t>(c.device_id); uint32_t device_generation = static_cast<uint32_t>(c.device_generation); uint32_t id = static_cast<uint32_t>(c.id); uint32_t generation = static_cast<uint32_t>(c.generation); - uint32_t usage = static_cast<WGPUTextureUsage>(c.usage); + WGPUTextureUsage usage = static_cast<WGPUTextureUsage>(c.usage); // Unpack the mailbox if (sizeof(Mailbox) > immediate_data_size) { @@ -1071,17 +942,60 @@ DLOG_IF(ERROR, !mailbox.Verify()) << "AssociateMailbox was passed an invalid mailbox"; - // Get the correct DawnDeviceAndWireServer - auto iter = dawn_device_and_wire_servers_.find(device_client_id); - if (iter == dawn_device_and_wire_servers_.end() || device_generation != 0) { - DLOG(ERROR) << "AssociateMailbox: Invalid device client ID"; + static constexpr uint32_t kAllowedTextureUsages = static_cast<uint32_t>( + WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst | + WGPUTextureUsage_Sampled | WGPUTextureUsage_OutputAttachment); + if (usage & ~kAllowedTextureUsages) { + DLOG(ERROR) << "AssociateMailbox: Invalid usage"; return error::kInvalidArguments; } - DawnDeviceAndWireServer* dawn_device_and_wire_server = iter->second.get(); - return dawn_device_and_wire_server->AssociateMailbox( - shared_image_representation_factory_.get(), mailbox, id, generation, - usage); + WGPUDevice device = wire_server_->GetDevice(device_id, device_generation); + if (device == nullptr) { + return error::kInvalidArguments; + } + + // Create a WGPUTexture from the mailbox. + std::unique_ptr<SharedImageRepresentationDawn> shared_image = + shared_image_representation_factory_->ProduceDawn(mailbox, device); + if (!shared_image) { + DLOG(ERROR) << "AssociateMailbox: Couldn't produce shared image"; + return error::kInvalidArguments; + } + + // TODO(cwallez@chromium.org): Handle texture clearing. We should either + // pre-clear textures, or implement a way to detect whether DAWN has cleared + // a texture. crbug.com/1036080 + std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> + shared_image_access = shared_image->BeginScopedAccess( + usage, SharedImageRepresentation::AllowUnclearedAccess::kYes); + if (!shared_image_access) { + DLOG(ERROR) << "AssociateMailbox: Couldn't begin shared image access"; + return error::kInvalidArguments; + } + + // Inject the texture in the dawn_wire::Server and remember which shared image + // it is associated with. + if (!wire_server_->InjectTexture(shared_image_access->texture(), id, + generation, device_id, device_generation)) { + DLOG(ERROR) << "AssociateMailbox: Invalid texture ID"; + return error::kInvalidArguments; + } + + std::unique_ptr<SharedImageRepresentationAndAccess> + representation_and_access = + std::make_unique<SharedImageRepresentationAndAccess>(); + representation_and_access->representation = std::move(shared_image); + representation_and_access->access = std::move(shared_image_access); + + std::tuple<uint32_t, uint32_t> id_and_generation{id, generation}; + auto insertion = associated_shared_image_map_.emplace( + id_and_generation, std::move(representation_and_access)); + + // InjectTexture already validated that the (ID, generation) can't have been + // registered before. + DCHECK(insertion.second); + return error::kNoError; } error::Error WebGPUDecoderImpl::HandleDissociateMailbox( @@ -1089,37 +1003,18 @@ const volatile void* cmd_data) { const volatile webgpu::cmds::DissociateMailbox& c = *static_cast<const volatile webgpu::cmds::DissociateMailbox*>(cmd_data); - DawnDeviceClientID device_client_id = - static_cast<DawnDeviceClientID>(c.device_client_id()); uint32_t texture_id = static_cast<uint32_t>(c.texture_id); uint32_t texture_generation = static_cast<uint32_t>(c.texture_generation); - // Get the correct DawnDeviceAndWireServer - auto iter = dawn_device_and_wire_servers_.find(device_client_id); - if (iter == dawn_device_and_wire_servers_.end()) { - DLOG(ERROR) << "AssociateMailbox: Invalid device client ID"; - return error::kInvalidArguments; - } - DawnDeviceAndWireServer* dawn_device_and_wire_server = iter->second.get(); - - return dawn_device_and_wire_server->DissociateMailbox(texture_id, - texture_generation); -} - -error::Error WebGPUDecoderImpl::HandleRemoveDevice( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile webgpu::cmds::RemoveDevice& c = - *static_cast<const volatile webgpu::cmds::RemoveDevice*>(cmd_data); - DawnDeviceClientID device_client_id = - static_cast<DawnDeviceClientID>(c.device_client_id); - - auto it = dawn_device_and_wire_servers_.find(device_client_id); - if (it == dawn_device_and_wire_servers_.end()) { + std::tuple<uint32_t, uint32_t> id_and_generation{texture_id, + texture_generation}; + auto it = associated_shared_image_map_.find(id_and_generation); + if (it == associated_shared_image_map_.end()) { + DLOG(ERROR) << "DissociateMailbox: Invalid texture ID"; return error::kInvalidArguments; } - dawn_device_and_wire_servers_.erase(it); + associated_shared_image_map_.erase(it); return error::kNoError; }
diff --git a/gpu/command_buffer/service/webgpu_decoder_unittest.cc b/gpu/command_buffer/service/webgpu_decoder_unittest.cc index 9072d38f..aebc03b 100644 --- a/gpu/command_buffer/service/webgpu_decoder_unittest.cc +++ b/gpu/command_buffer/service/webgpu_decoder_unittest.cc
@@ -45,7 +45,7 @@ constexpr uint32_t kAdapterServiceID = 0; cmds::RequestDevice requestDeviceCmd; - requestDeviceCmd.Init(kDeviceClientID, kAdapterServiceID, 0, 0, 0); + requestDeviceCmd.Init(0, kAdapterServiceID, 1, 0, 0, 0, 0); ASSERT_EQ(error::kNoError, ExecuteCmd(requestDeviceCmd)); } @@ -69,7 +69,6 @@ std::unique_ptr<WebGPUDecoder> decoder_; std::unique_ptr<FakeDecoderClient> decoder_client_; gles2::TraceOutputter outputter_; - static const DawnDeviceClientID kDeviceClientID = 0u; }; TEST_F(WebGPUDecoderTest, DawnCommands) { @@ -79,7 +78,7 @@ } cmds::DawnCommands cmd; - cmd.Init(kDeviceClientID, 0, 0, 0); + cmd.Init(0, 0, 0); EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); }
diff --git a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc index ed657da..49f31b8 100644 --- a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc +++ b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc
@@ -135,16 +135,15 @@ gl()->GenUnverifiedSyncTokenCHROMIUM(gl_op_token.GetData()); webgpu()->WaitSyncTokenCHROMIUM(gl_op_token.GetConstData()); - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; - webgpu::DawnDeviceClientID device_client_id = device_and_id.client_id; + wgpu::Device device = GetNewDevice(); { // Register the shared image as a Dawn texture in the wire. gpu::webgpu::ReservedTexture reservation = - webgpu()->ReserveTexture(device_client_id); + webgpu()->ReserveTexture(device.Get()); - webgpu()->AssociateMailbox(device_client_id, 0, reservation.id, + webgpu()->AssociateMailbox(reservation.deviceId, + reservation.deviceGeneration, reservation.id, reservation.generation, WGPUTextureUsage_CopySrc, reinterpret_cast<GLbyte*>(&gl_mailbox)); wgpu::Texture texture = wgpu::Texture::Acquire(reservation.texture); @@ -175,8 +174,7 @@ wgpu::Queue queue = device.GetDefaultQueue(); queue.Submit(1, &commands); - webgpu()->DissociateMailbox(device_client_id, reservation.id, - reservation.generation); + webgpu()->DissociateMailbox(reservation.id, reservation.generation); // Map the buffer and assert the pixel is the correct value. readback_buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapCallback,
diff --git a/gpu/command_buffer/tests/webgpu_fence_unittest.cc b/gpu/command_buffer/tests/webgpu_fence_unittest.cc index ccc5bdb..16b0f20 100644 --- a/gpu/command_buffer/tests/webgpu_fence_unittest.cc +++ b/gpu/command_buffer/tests/webgpu_fence_unittest.cc
@@ -54,8 +54,7 @@ return; } - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; + wgpu::Device device = GetNewDevice(); wgpu::Queue queue = device.GetDefaultQueue(); { @@ -77,8 +76,7 @@ return; } - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; + wgpu::Device device = GetNewDevice(); wgpu::Queue queue = device.GetDefaultQueue(); wgpu::FenceDescriptor fence_desc{nullptr, nullptr, 0}; @@ -96,8 +94,7 @@ return; } - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; + wgpu::Device device = GetNewDevice(); wgpu::Queue queue = device.GetDefaultQueue(); wgpu::FenceDescriptor fence_desc{nullptr, nullptr, 0}; @@ -118,8 +115,7 @@ return; } - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; + wgpu::Device device = GetNewDevice(); wgpu::Queue queue = device.GetDefaultQueue(); wgpu::FenceDescriptor fence_desc{nullptr, nullptr, 0};
diff --git a/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc b/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc index 0077b08..28332f9 100644 --- a/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc +++ b/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc
@@ -105,17 +105,19 @@ kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, SHARED_IMAGE_USAGE_WEBGPU, kNullSurfaceHandle); - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); + wgpu::Device device = GetNewDevice(); + webgpu::ReservedTexture reservation = webgpu()->ReserveTexture(device.Get()); GetGpuServiceHolder()->ScheduleGpuTask(base::BindOnce( - [](webgpu::WebGPUDecoder* decoder, webgpu::DawnDeviceClientID client_id, + [](webgpu::WebGPUDecoder* decoder, webgpu::ReservedTexture reservation, gpu::Mailbox mailbox) { // Error case: invalid mailbox { gpu::Mailbox bad_mailbox; AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 1, 0, WGPUTextureUsage_Sampled, - bad_mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_Sampled, bad_mailbox.name); EXPECT_EQ( error::kInvalidArguments, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(bad_mailbox.name))); @@ -124,8 +126,9 @@ // Error case: device client id doesn't exist. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id + 1, 0, 1, 0, WGPUTextureUsage_Sampled, - mailbox.name); + cmd.cmd.Init(reservation.deviceId + 1, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_Sampled, mailbox.name); EXPECT_EQ( error::kInvalidArguments, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); @@ -134,8 +137,9 @@ // Error case: device generation is invalid. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 42, 1, 0, WGPUTextureUsage_Sampled, - mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration + 1, + reservation.id, reservation.generation, + WGPUTextureUsage_Sampled, mailbox.name); EXPECT_EQ( error::kInvalidArguments, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); @@ -144,18 +148,9 @@ // Error case: texture ID invalid for the wire server. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 42, 42, WGPUTextureUsage_Sampled, - mailbox.name); - EXPECT_EQ( - error::kInvalidArguments, - ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); - } - - // Error case: invalid usage. - { - AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 42, 42, WGPUTextureUsage_Sampled, - mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration, + reservation.id + 1, reservation.generation, + WGPUTextureUsage_Sampled, mailbox.name); EXPECT_EQ( error::kInvalidArguments, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); @@ -164,22 +159,23 @@ // Error case: invalid texture usage. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 1, 0, WGPUTextureUsage_Force32, - mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_Force32, mailbox.name); EXPECT_EQ( error::kInvalidArguments, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); } - // Control case: test a successful call to AssociateMailbox - // (1, 0) is a valid texture ID on dawn_wire server start. + // Control case: test a successful call to AssociateMailbox. // The control case is not put first because it modifies the internal // state of the Dawn wire server and would make calls with the same // texture ID and generation invalid. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 1, 0, WGPUTextureUsage_Sampled, - mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_Sampled, mailbox.name); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); } @@ -187,8 +183,9 @@ // Error case: associated to an already associated texture. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 1, 0, WGPUTextureUsage_Sampled, - mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_Sampled, mailbox.name); EXPECT_EQ( error::kInvalidArguments, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); @@ -197,11 +194,11 @@ // Dissociate the image from the control case to remove its reference. { webgpu::cmds::DissociateMailbox cmd; - cmd.Init(client_id, 1, 0); + cmd.Init(reservation.id, reservation.generation); EXPECT_EQ(error::kNoError, ExecuteCmd(decoder, cmd)); } }, - GetDecoder(), device_and_id.client_id, mailbox)); + GetDecoder(), reservation, mailbox)); GetGpuServiceHolder()->gpu_thread_task_runner()->RunsTasksInCurrentSequence(); } @@ -223,16 +220,18 @@ kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, SHARED_IMAGE_USAGE_WEBGPU, kNullSurfaceHandle); - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); + wgpu::Device device = GetNewDevice(); + webgpu::ReservedTexture reservation = webgpu()->ReserveTexture(device.Get()); GetGpuServiceHolder()->ScheduleGpuTask(base::BindOnce( - [](webgpu::WebGPUDecoder* decoder, webgpu::DawnDeviceClientID client_id, + [](webgpu::WebGPUDecoder* decoder, webgpu::ReservedTexture reservation, gpu::Mailbox mailbox) { // Associate a mailbox so we can later dissociate it. { AssociateMailboxCmdStorage cmd; - cmd.cmd.Init(client_id, 0, 1, 0, WGPUTextureUsage_Sampled, - mailbox.name); + cmd.cmd.Init(reservation.deviceId, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_Sampled, mailbox.name); EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(decoder, cmd.cmd, sizeof(mailbox.name))); } @@ -240,32 +239,32 @@ // Error case: wrong texture ID { webgpu::cmds::DissociateMailbox cmd; - cmd.Init(client_id, 42, 0); + cmd.Init(reservation.id + 1, reservation.generation); EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(decoder, cmd)); } // Error case: wrong texture generation { webgpu::cmds::DissociateMailbox cmd; - cmd.Init(client_id, 1, 42); - EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(decoder, cmd)); - } - - // Error case: invalid client device ID - { - webgpu::cmds::DissociateMailbox cmd; - cmd.Init(client_id + 1, 1, 0); + cmd.Init(reservation.id, reservation.generation + 1); EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(decoder, cmd)); } // Success case { webgpu::cmds::DissociateMailbox cmd; - cmd.Init(client_id, 1, 0); + cmd.Init(reservation.id, reservation.generation); EXPECT_EQ(error::kNoError, ExecuteCmd(decoder, cmd)); } + + // Error case: dissociate an already dissociated mailbox + { + webgpu::cmds::DissociateMailbox cmd; + cmd.Init(reservation.id, reservation.generation); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(decoder, cmd)); + } }, - GetDecoder(), device_and_id.client_id, mailbox)); + GetDecoder(), reservation, mailbox)); GetGpuServiceHolder()->gpu_thread_task_runner()->RunsTasksInCurrentSequence(); } @@ -293,19 +292,18 @@ SyncToken mailbox_produced_token = sii->GenVerifiedSyncToken(); webgpu()->WaitSyncTokenCHROMIUM(mailbox_produced_token.GetConstData()); - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; - webgpu::DawnDeviceClientID device_client_id = device_and_id.client_id; + wgpu::Device device = GetNewDevice(); // Part 1: Write to the texture using Dawn { // Register the shared image as a Dawn texture in the wire. gpu::webgpu::ReservedTexture reservation = - webgpu()->ReserveTexture(device_client_id); + webgpu()->ReserveTexture(device.Get()); webgpu()->AssociateMailbox( - device_client_id, 0, reservation.id, reservation.generation, - WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&mailbox)); + reservation.deviceId, reservation.deviceGeneration, reservation.id, + reservation.generation, WGPUTextureUsage_OutputAttachment, + reinterpret_cast<GLbyte*>(&mailbox)); wgpu::Texture texture = wgpu::Texture::Acquire(reservation.texture); // Clear the texture using a render pass. @@ -327,17 +325,17 @@ wgpu::Queue queue = device.GetDefaultQueue(); queue.Submit(1, &commands); - webgpu()->DissociateMailbox(device_client_id, reservation.id, - reservation.generation); + webgpu()->DissociateMailbox(reservation.id, reservation.generation); } // Part 2: Read back the texture using Dawn { // Register the shared image as a Dawn texture in the wire. gpu::webgpu::ReservedTexture reservation = - webgpu()->ReserveTexture(device_client_id); + webgpu()->ReserveTexture(device.Get()); - webgpu()->AssociateMailbox(device_client_id, 0, reservation.id, + webgpu()->AssociateMailbox(reservation.deviceId, + reservation.deviceGeneration, reservation.id, reservation.generation, WGPUTextureUsage_CopySrc, reinterpret_cast<GLbyte*>(&mailbox)); wgpu::Texture texture = wgpu::Texture::Acquire(reservation.texture); @@ -368,8 +366,7 @@ wgpu::Queue queue = device.GetDefaultQueue(); queue.Submit(1, &commands); - webgpu()->DissociateMailbox(device_client_id, reservation.id, - reservation.generation); + webgpu()->DissociateMailbox(reservation.id, reservation.generation); // Map the buffer and assert the pixel is the correct value. readback_buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapCallback, @@ -406,22 +403,20 @@ webgpu()->WaitSyncTokenCHROMIUM(mailbox_produced_token.GetConstData()); // Create the device, and expect a validation error. - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; - webgpu::DawnDeviceClientID device_client_id = device_and_id.client_id; + wgpu::Device device = GetNewDevice(); device.SetUncapturedErrorCallback(ToMockUncapturedErrorCallback, 0); // Associate and immediately dissociate the image. gpu::webgpu::ReservedTexture reservation = - webgpu()->ReserveTexture(device_client_id); + webgpu()->ReserveTexture(device.Get()); wgpu::Texture texture = wgpu::Texture::Acquire(reservation.texture); - webgpu()->AssociateMailbox( - device_client_id, 0, reservation.id, reservation.generation, - WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&mailbox)); - webgpu()->DissociateMailbox(device_client_id, reservation.id, - reservation.generation); + webgpu()->AssociateMailbox(reservation.deviceId, reservation.deviceGeneration, + reservation.id, reservation.generation, + WGPUTextureUsage_OutputAttachment, + reinterpret_cast<GLbyte*>(&mailbox)); + webgpu()->DissociateMailbox(reservation.id, reservation.generation); // Try using the texture, it should produce a validation error. wgpu::TextureView view = texture.CreateView(); @@ -470,28 +465,26 @@ kNullSurfaceHandle); // Get a WebGPU device to associate the shared images to. - DeviceAndClientID device_and_id = GetNewDeviceAndClientID(); - wgpu::Device device = device_and_id.device; - webgpu::DawnDeviceClientID device_client_id = device_and_id.client_id; + wgpu::Device device = GetNewDevice(); // Associate both mailboxes gpu::webgpu::ReservedTexture reservation_a = - webgpu()->ReserveTexture(device_client_id); + webgpu()->ReserveTexture(device.Get()); webgpu()->AssociateMailbox( - device_client_id, 0, reservation_a.id, reservation_a.generation, - WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&mailbox_a)); + reservation_a.deviceId, reservation_a.deviceGeneration, reservation_a.id, + reservation_a.generation, WGPUTextureUsage_OutputAttachment, + reinterpret_cast<GLbyte*>(&mailbox_a)); gpu::webgpu::ReservedTexture reservation_b = - webgpu()->ReserveTexture(device_client_id); + webgpu()->ReserveTexture(device.Get()); webgpu()->AssociateMailbox( - device_client_id, 0, reservation_b.id, reservation_b.generation, - WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&mailbox_b)); + reservation_b.deviceId, reservation_b.deviceGeneration, reservation_b.id, + reservation_b.generation, WGPUTextureUsage_OutputAttachment, + reinterpret_cast<GLbyte*>(&mailbox_b)); // Dissociate both mailboxes in the same order. - webgpu()->DissociateMailbox(device_client_id, reservation_a.id, - reservation_a.generation); - webgpu()->DissociateMailbox(device_client_id, reservation_b.id, - reservation_b.generation); + webgpu()->DissociateMailbox(reservation_a.id, reservation_a.generation); + webgpu()->DissociateMailbox(reservation_b.id, reservation_b.generation); // Send all the previous commands to the WebGPU decoder. webgpu()->FlushCommands(); @@ -524,30 +517,27 @@ kNullSurfaceHandle); // Two WebGPU devices to associate the shared images to. - DeviceAndClientID device_and_id_a = GetNewDeviceAndClientID(); - webgpu::DawnDeviceClientID client_id_a = device_and_id_a.client_id; - - DeviceAndClientID device_and_id_b = GetNewDeviceAndClientID(); - webgpu::DawnDeviceClientID client_id_b = device_and_id_b.client_id; + wgpu::Device device_a = GetNewDevice(); + wgpu::Device device_b = GetNewDevice(); // Associate both mailboxes gpu::webgpu::ReservedTexture reservation_a = - webgpu()->ReserveTexture(client_id_a); + webgpu()->ReserveTexture(device_a.Get()); webgpu()->AssociateMailbox( - client_id_a, 0, reservation_a.id, reservation_a.generation, - WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&mailbox_a)); + reservation_a.deviceId, reservation_a.deviceGeneration, reservation_a.id, + reservation_a.generation, WGPUTextureUsage_OutputAttachment, + reinterpret_cast<GLbyte*>(&mailbox_a)); gpu::webgpu::ReservedTexture reservation_b = - webgpu()->ReserveTexture(client_id_b); + webgpu()->ReserveTexture(device_b.Get()); webgpu()->AssociateMailbox( - client_id_b, 0, reservation_b.id, reservation_b.generation, - WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&mailbox_b)); + reservation_b.deviceId, reservation_b.deviceGeneration, reservation_b.id, + reservation_b.generation, WGPUTextureUsage_OutputAttachment, + reinterpret_cast<GLbyte*>(&mailbox_b)); // Dissociate both mailboxes in the same order. - webgpu()->DissociateMailbox(client_id_a, reservation_a.id, - reservation_a.generation); - webgpu()->DissociateMailbox(client_id_b, reservation_b.id, - reservation_b.generation); + webgpu()->DissociateMailbox(reservation_a.id, reservation_a.generation); + webgpu()->DissociateMailbox(reservation_b.id, reservation_b.generation); // Send all the previous commands to the WebGPU decoder. webgpu()->FlushCommands();
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc index 0c85d44e..9630782 100644 --- a/gpu/command_buffer/tests/webgpu_test.cc +++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -23,10 +23,6 @@ namespace { -void OnRequestAdapterCallback(int32_t adapter_service_id, - const WGPUDeviceProperties& properties, - const char* error_message) {} - void CountCallback(int* count) { (*count)++; } @@ -109,9 +105,23 @@ cmd_helper_ = std::make_unique<webgpu::WebGPUCmdHelper>( context_->GetCommandBufferForTest()); - ASSERT_TRUE( - webgpu()->RequestAdapterAsync(webgpu::PowerPreference::kDefault, - base::BindOnce(&OnRequestAdapterCallback))); + + bool done = false; + webgpu()->RequestAdapterAsync( + webgpu::PowerPreference::kDefault, + base::BindOnce( + [](WebGPUTest* test, bool* done, int32_t adapter_id, + const WGPUDeviceProperties& properties, const char*) { + EXPECT_GE(adapter_id, 0); + test->adapter_id_ = static_cast<uint32_t>(adapter_id); + test->device_properties_ = properties; + *done = true; + }, + this, &done)); + + while (!done) { + RunPendingTasks(); + } DawnProcTable procs = webgpu()->GetProcs(); dawnProcSetProcs(&procs); @@ -135,6 +145,13 @@ void WebGPUTest::RunPendingTasks() { context_->GetTaskRunner()->RunPendingTasks(); + gpu_service_holder_->ScheduleGpuTask(base::BindOnce( + [](webgpu::WebGPUDecoder* decoder) { + if (decoder->HasPollingWork()) { + decoder->PerformPollingWork(); + } + }, + GetDecoder())); } void WebGPUTest::WaitForCompletion(wgpu::Device device) { @@ -155,24 +172,24 @@ } } -WebGPUTest::DeviceAndClientID WebGPUTest::GetNewDeviceAndClientID() { - DeviceAndClientID result; - result.client_id = next_device_client_id_; +wgpu::Device WebGPUTest::GetNewDevice() { + WGPUDevice device = nullptr; + bool done = false; webgpu()->RequestDeviceAsync( - kAdapterServiceID, {}, + adapter_id_, device_properties_, base::BindOnce( - [](webgpu::DawnDeviceClientID expected_client_id, bool success, - webgpu::DawnDeviceClientID assigned_client_id) { - ASSERT_TRUE(success); - ASSERT_EQ(expected_client_id, assigned_client_id); + [](WGPUDevice* result, bool* done, WGPUDevice device) { + *result = device; + *done = true; }, - result.client_id)); + &device, &done)); + while (!done) { + RunPendingTasks(); + } - result.device = wgpu::Device::Acquire(webgpu()->GetDevice(result.client_id)); - - next_device_client_id_++; - return result; + EXPECT_NE(device, nullptr); + return wgpu::Device::Acquire(device); } TEST_F(WebGPUTest, FlushNoCommands) { @@ -235,9 +252,19 @@ Initialize(WebGPUTest::Options()); webgpu()->OnGpuControlLostContext(); - ASSERT_FALSE( - webgpu()->RequestAdapterAsync(webgpu::PowerPreference::kDefault, - base::BindOnce(&OnRequestAdapterCallback))); + + bool called = false; + webgpu()->RequestAdapterAsync( + webgpu::PowerPreference::kDefault, + base::BindOnce( + [](bool* called, int32_t adapter_id, const WGPUDeviceProperties&, + const char*) { + EXPECT_EQ(adapter_id, -1); + *called = true; + }, + &called)); + RunPendingTasks(); + EXPECT_TRUE(called); } TEST_F(WebGPUTest, RequestDeviceAfterContextLost) { @@ -249,10 +276,17 @@ Initialize(WebGPUTest::Options()); webgpu()->OnGpuControlLostContext(); - ASSERT_FALSE(webgpu()->RequestDeviceAsync( - kAdapterServiceID, {}, - base::BindOnce( - [](bool success, webgpu::DawnDeviceClientID assigned_client_id) {}))); + + bool called = false; + webgpu()->RequestDeviceAsync(GetAdapterId(), GetDeviceProperties(), + base::BindOnce( + [](bool* called, WGPUDevice device) { + EXPECT_EQ(device, nullptr); + *called = true; + }, + &called)); + RunPendingTasks(); + EXPECT_TRUE(called); } } // namespace gpu
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h index cacc34f..d513f5d 100644 --- a/gpu/command_buffer/tests/webgpu_test.h +++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -27,9 +27,6 @@ class SharedImageInterface; class WebGPUInProcessContext; -void OnRequestDeviceCallback(bool is_request_device_success, - webgpu::DawnDeviceClientID device_client_id); - namespace webgpu { class WebGPUCmdHelper; @@ -66,17 +63,17 @@ void RunPendingTasks(); void WaitForCompletion(wgpu::Device device); - struct DeviceAndClientID { - wgpu::Device device; - webgpu::DawnDeviceClientID client_id; - }; - DeviceAndClientID GetNewDeviceAndClientID(); + wgpu::Device GetNewDevice(); viz::TestGpuServiceHolder* GetGpuServiceHolder() { return gpu_service_holder_.get(); } - const uint32_t kAdapterServiceID = 0u; + uint32_t GetAdapterId() const { return adapter_id_; } + + const WGPUDeviceProperties& GetDeviceProperties() const { + return device_properties_; + } private: std::unique_ptr<viz::TestGpuServiceHolder> gpu_service_holder_; @@ -86,8 +83,8 @@ // SharedImages on macOS require a valid image factory. GpuMemoryBufferFactoryIOSurface image_factory_; #endif - - webgpu::DawnDeviceClientID next_device_client_id_ = 1; + uint32_t adapter_id_; + WGPUDeviceProperties device_properties_; }; } // namespace gpu
diff --git a/gpu/command_buffer/webgpu_cmd_buffer_functions.txt b/gpu/command_buffer/webgpu_cmd_buffer_functions.txt index 4f34880..8ac5f0da 100644 --- a/gpu/command_buffer/webgpu_cmd_buffer_functions.txt +++ b/gpu/command_buffer/webgpu_cmd_buffer_functions.txt
@@ -6,9 +6,8 @@ // WebGPU commands. Note the first 2 characters (usually 'wg') are // completely ignored. -GL_APICALL void GL_APIENTRY wgDawnCommands (GLuint64 device_client_id, const char* commands, size_t size); -GL_APICALL void GL_APIENTRY wgAssociateMailbox (GLuint64 device_client_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, const GLbyte* mailbox); -GL_APICALL void GL_APIENTRY wgDissociateMailbox (GLuint64 device_client_id, GLuint texture_id, GLuint texture_generation); +GL_APICALL void GL_APIENTRY wgDawnCommands (const char* commands, size_t size); +GL_APICALL void GL_APIENTRY wgAssociateMailbox (GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, const GLbyte* mailbox); +GL_APICALL void GL_APIENTRY wgDissociateMailbox (GLuint texture_id, GLuint texture_generation); GL_APICALL void GL_APIENTRY wgRequestAdapter (GLuint64 request_adapter_serial, EnumClassPowerPreference power_preference = PowerPreference::kDefault); -GL_APICALL void GL_APIENTRY wgRequestDevice (GLuint64 device_client_id, GLuint adapter_service_id, const char* dawn_request_device_properties, size_t request_device_properties_size); -GL_APICALL void GL_APIENTRY wgRemoveDevice (GLuint64 device_client_id); +GL_APICALL void GL_APIENTRY wgRequestDevice (GLuint64 request_device_serial, GLuint adapter_service_id, GLuint device_id, GLuint device_generation, const char* dawn_request_device_properties, size_t request_device_properties_size);
diff --git a/gpu/skia_bindings/grcontext_for_webgpu_interface.cc b/gpu/skia_bindings/grcontext_for_webgpu_interface.cc index 8094a64..6db7f0d4 100644 --- a/gpu/skia_bindings/grcontext_for_webgpu_interface.cc +++ b/gpu/skia_bindings/grcontext_for_webgpu_interface.cc
@@ -34,9 +34,9 @@ options.fSharpenMipmappedTextures = true; options.fShaderErrorHandler = this; options.fInternalMultisampleCount = 0; - // TODO(senorblanco): use an actual passed-in Device, rather than assuming - // device ID 1. http://crbug.com/1078775 - WGPUDevice device = webgpu->GetDevice(1); + // TODO(senorblanco): create an actual passed-in Device, rather than this + // default hacky one. http://crbug.com/1078775 + WGPUDevice device = webgpu->DeprecatedEnsureDefaultDeviceSync(); wgpuDeviceSetUncapturedErrorCallback(device, PrintDeviceError, 0); gr_context_ = GrDirectContext::MakeDawn(device, options); if (gr_context_) {
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index 998ab72..d74e3df 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -6a7f902139eefab707c554567564fc1979f7608a \ No newline at end of file +3726dc7e3f64153178f73325b064d56082772eb5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index d46a995..495a7f83 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -7b1cdaefb39ef7bf0255f4d8cf211c64f86e9832 \ No newline at end of file +87d7f28eef0826ebd5c7ae32557cbf1b4dc87cfa \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index a4077b31..0686deb52 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -e9266f2bf3e7a99ab52cbcef3a42c5fa75c396fc \ No newline at end of file +e4af75b9571545b8b6c085f897a6020ad534527e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 33f74a0..37b3740 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -686e014f0dc501b9d2a9ee460c1c2bd562455e9d \ No newline at end of file +60965286a0b8b64b272c60d42200925591cc36e6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index af8869b..9dbf32b 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -b4bfc89e22b13e557c07e884d42257b3a5d90722 \ No newline at end of file +a29f608862defbc52c29de689d7c74bf60eb9771 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 036591f..2868be8 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -5d34969f1ee1502b87e6dec4218117c7a043e5cf \ No newline at end of file +7ab0cffa045fe4a78256dd6741aeed5c45e06c92 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index 1854acd9..7ba3164 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -28aae8925cb5ebb9d29e60feb4544f606f1ffa93 \ No newline at end of file +e711ec1ef66afe2a7d4af80961957abc916830de \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index 9efd02e9..77059b4 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@ -1a859a0890970d9845462755fdeb7f9d944c0df5 \ No newline at end of file +53ef0154233d1ca4472e861372ac565301d942fb \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index 9303d560..d0ed91c 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@ -5310fb36cf166ed7586fc74266287938416b0eb0 \ No newline at end of file +2d70eea7565dd734377392fdfcc34b77ccd1afb1 \ No newline at end of file
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 00f80e6..39bc6be5 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -534,6 +534,7 @@ # TODO(crbug.com/1006266): consider using |use_chromeos_video_acceleration|. if (use_v4l2_codec || use_vaapi) { test("video_decode_accelerator_tests") { + assert(enable_dav1d_decoder) testonly = true sources = [ "video_decode_accelerator_tests.cc" ] data = [ "//media/test/data/" ] @@ -542,6 +543,7 @@ "test:frame_file_writer", "test:frame_validator", "test:helpers", + "test:test_helpers", "test:video_player", "test:video_player_test_environment", "test:video_player_thumbnail_renderer",
diff --git a/media/gpu/test/video_player/video_player_test_environment.cc b/media/gpu/test/video_player/video_player_test_environment.cc index 4019441..2b4112a 100644 --- a/media/gpu/test/video_player/video_player_test_environment.cc +++ b/media/gpu/test/video_player/video_player_test_environment.cc
@@ -25,7 +25,7 @@ VideoPlayerTestEnvironment* VideoPlayerTestEnvironment::Create( const base::FilePath& video_path, const base::FilePath& video_metadata_path, - bool enable_validator, + ValidatorType validator_type, const DecoderImplementation implementation, const base::FilePath& output_folder, const FrameOutputConfig& frame_output_config) { @@ -37,14 +37,14 @@ return nullptr; } - return new VideoPlayerTestEnvironment(std::move(video), enable_validator, + return new VideoPlayerTestEnvironment(std::move(video), validator_type, implementation, output_folder, frame_output_config); } VideoPlayerTestEnvironment::VideoPlayerTestEnvironment( std::unique_ptr<media::test::Video> video, - bool enable_validator, + ValidatorType validator_type, const DecoderImplementation implementation, const base::FilePath& output_folder, const FrameOutputConfig& frame_output_config) @@ -66,7 +66,7 @@ #endif }), video_(std::move(video)), - enable_validator_(enable_validator), + validator_type_(validator_type), implementation_(implementation), frame_output_config_(frame_output_config), output_folder_(output_folder), @@ -109,7 +109,12 @@ } bool VideoPlayerTestEnvironment::IsValidatorEnabled() const { - return enable_validator_; + return validator_type_ != ValidatorType::kNone; +} + +VideoPlayerTestEnvironment::ValidatorType +VideoPlayerTestEnvironment::GetValidatorType() const { + return validator_type_; } DecoderImplementation VideoPlayerTestEnvironment::GetDecoderImplementation()
diff --git a/media/gpu/test/video_player/video_player_test_environment.h b/media/gpu/test/video_player/video_player_test_environment.h index 17e5e54..a66f596 100644 --- a/media/gpu/test/video_player/video_player_test_environment.h +++ b/media/gpu/test/video_player/video_player_test_environment.h
@@ -23,10 +23,16 @@ // the entire test run. class VideoPlayerTestEnvironment : public VideoTestEnvironment { public: + enum class ValidatorType { + kNone, + kMD5, + kSSIM, + }; + static VideoPlayerTestEnvironment* Create( const base::FilePath& video_path, const base::FilePath& video_metadata_path, - bool enable_validator, + ValidatorType validator_type, const DecoderImplementation implementation, const base::FilePath& output_folder = base::FilePath(), const FrameOutputConfig& frame_output_config = FrameOutputConfig()); @@ -39,6 +45,8 @@ const media::test::Video* Video() const; // Check whether frame validation is enabled. bool IsValidatorEnabled() const; + // Get the validator type. + ValidatorType GetValidatorType() const; // Return which implementation is used. DecoderImplementation GetDecoderImplementation() const; @@ -62,13 +70,13 @@ private: VideoPlayerTestEnvironment(std::unique_ptr<media::test::Video> video, - bool enable_validator, + ValidatorType validator_type, const DecoderImplementation implementation, const base::FilePath& output_folder, const FrameOutputConfig& frame_output_config); const std::unique_ptr<media::test::Video> video_; - const bool enable_validator_; + const ValidatorType validator_type_; const DecoderImplementation implementation_; const FrameOutputConfig frame_output_config_;
diff --git a/media/gpu/video_decode_accelerator_perf_tests.cc b/media/gpu/video_decode_accelerator_perf_tests.cc index 1282d2c..7bede6c6 100644 --- a/media/gpu/video_decode_accelerator_perf_tests.cc +++ b/media/gpu/video_decode_accelerator_perf_tests.cc
@@ -440,7 +440,9 @@ // Set up our test environment. media::test::VideoPlayerTestEnvironment* test_environment = media::test::VideoPlayerTestEnvironment::Create( - video_path, video_metadata_path, false, implementation, + video_path, video_metadata_path, /*validator_type=*/ + media::test::VideoPlayerTestEnvironment::ValidatorType::kNone, + implementation, base::FilePath(output_folder)); if (!test_environment) return EXIT_FAILURE;
diff --git a/media/gpu/video_decode_accelerator_tests.cc b/media/gpu/video_decode_accelerator_tests.cc index a74d151a..f3ff18c 100644 --- a/media/gpu/video_decode_accelerator_tests.cc +++ b/media/gpu/video_decode_accelerator_tests.cc
@@ -8,7 +8,13 @@ #include "base/files/file_util.h" #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" +#include "media/base/decoder_buffer.h" +#include "media/base/encryption_scheme.h" +#include "media/base/media_util.h" #include "media/base/test_data_util.h" +#include "media/base/video_decoder_config.h" +#include "media/base/video_transformation.h" +#include "media/filters/dav1d_video_decoder.h" #include "media/gpu/test/video.h" #include "media/gpu/test/video_frame_file_writer.h" #include "media/gpu/test/video_frame_validator.h" @@ -17,6 +23,7 @@ #include "media/gpu/test/video_player/video_decoder_client.h" #include "media/gpu/test/video_player/video_player.h" #include "media/gpu/test/video_player/video_player_test_environment.h" +#include "media/gpu/test/video_test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { @@ -28,7 +35,8 @@ // under docs/media/gpu/video_decoder_test_usage.md when making changes here. constexpr const char* usage_msg = "usage: video_decode_accelerator_tests\n" - " [-v=<level>] [--vmodule=<config>] [--disable_validator]\n" + " [-v=<level>] [--vmodule=<config>]\n" + " [--validator_type=(none|md5|ssim)]\n" " [--output_frames=(all|corrupt)] [--output_format=(png|yuv)]\n" " [--output_limit=<number>] [--output_folder=<folder>]\n" " ([--use_vd]|[--use_vd_vda]) [--gtest_help] [--help]\n" @@ -46,7 +54,11 @@ " -v enable verbose mode, e.g. -v=2.\n" " --vmodule enable verbose mode for the specified module,\n" " e.g. --vmodule=*media/gpu*=2.\n\n" - " --disable_validator disable frame validation.\n" + " --validator_type validate decoded frames, possible values are \n" + " md5 (default, compare against md5hash of expected\n" + " frames), ssim (compute SSIM against expected\n" + " frames, currently allowed for AV1 streams only)\n" + " and none (disable frame validation).\n" " --use_vd use the new VD-based video decoders, instead of\n" " the default VDA-based video decoders.\n" " --use_vd_vda use the new VD-based video decoders with a\n" @@ -108,13 +120,30 @@ g_env->Video()->BitDepth() != 10u) { LOG(ERROR) << "Unsupported bit depth: " << base::strict_cast<int>(g_env->Video()->BitDepth()); - return nullptr; + ADD_FAILURE(); } const VideoPixelFormat validation_format = g_env->Video()->BitDepth() == 10 ? PIXEL_FORMAT_YUV420P10 : PIXEL_FORMAT_I420; - frame_processors.push_back(media::test::MD5VideoFrameValidator::Create( - video->FrameChecksums(), validation_format, std::move(frame_writer))); + if (g_env->GetValidatorType() == + VideoPlayerTestEnvironment::ValidatorType::kMD5) { + frame_processors.push_back(media::test::MD5VideoFrameValidator::Create( + video->FrameChecksums(), validation_format, + std::move(frame_writer))); + } else { + DCHECK_EQ(g_env->GetValidatorType(), + VideoPlayerTestEnvironment::ValidatorType::kSSIM); + if (!CreateModelFrames(g_env->Video())) { + LOG(ERROR) << "Failed creating model frames"; + ADD_FAILURE(); + } + constexpr double kSSIMTolerance = 0.915; + frame_processors.push_back(media::test::SSIMVideoFrameValidator::Create( + base::BindRepeating(&VideoDecoderTest::GetModelFrame, + base::Unretained(this)), + std::move(frame_writer), + VideoFrameValidator::ValidationMode::kThreshold, kSSIMTolerance)); + } } config.implementation = g_env->GetDecoderImplementation(); @@ -132,6 +161,78 @@ } return video_player; } + + private: + // TODO(hiroh): Move this to Video class or video_frame_helpers.h. + // TODO(hiroh): Create model frames once during the test. + bool CreateModelFrames(const Video* video) { + if (video->Codec() != VideoCodec::kCodecAV1) { + LOG(ERROR) << "Frame validation by SSIM is allowed for AV1 streams only"; + return false; + } + Dav1dVideoDecoder decoder( + /*media_log=*/nullptr, + OffloadableVideoDecoder::OffloadState::kOffloaded); + VideoDecoderConfig decoder_config( + video->Codec(), video->Profile(), + VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), + kNoTransformation, video->Resolution(), video->VisibleRect(), + video->VisibleRect().size(), EmptyExtraData(), + EncryptionScheme::kUnencrypted); + + bool init_success = false; + VideoDecoder::InitCB init_cb = base::BindOnce( + [](bool* init_success, media::Status result) { + *init_success = result.is_ok(); + }, + &init_success); + decoder.Initialize(decoder_config, /*low_delay=*/false, + /*cdm_context=*/nullptr, std::move(init_cb), + base::BindRepeating(&VideoDecoderTest::AddModelFrame, + base::Unretained(this)), + /*waiting_cb=*/base::NullCallback()); + if (!init_success) + return false; + auto encoded_data_helper = + std::make_unique<EncodedDataHelper>(video->Data(), video->Profile()); + DCHECK(encoded_data_helper); + while (!encoded_data_helper->ReachEndOfStream()) { + bool decode_success = false; + media::VideoDecoder::DecodeCB decode_cb = base::BindOnce( + [](bool* decode_success, media::Status status) { + *decode_success = status.is_ok(); + }, + &decode_success); + scoped_refptr<DecoderBuffer> bitstream_buffer = + encoded_data_helper->GetNextBuffer(); + if (!bitstream_buffer) { + LOG(ERROR) << "Failed to get next video stream data"; + return false; + } + decoder.Decode(std::move(bitstream_buffer), std::move(decode_cb)); + if (!decode_success) + return false; + } + bool flush_success = false; + media::VideoDecoder::DecodeCB flush_cb = base::BindOnce( + [](bool* flush_success, media::Status status) { + *flush_success = status.is_ok(); + }, + &flush_success); + decoder.Decode(DecoderBuffer::CreateEOSBuffer(), std::move(flush_cb)); + + return flush_success && model_frames_.size() == video->NumFrames(); + } + + void AddModelFrame(scoped_refptr<VideoFrame> frame) { + model_frames_.push_back(std::move(frame)); + } + + scoped_refptr<const VideoFrame> GetModelFrame(size_t frame_index) { + CHECK_LT(frame_index, model_frames_.size()); + return model_frames_[frame_index]; + } + std::vector<scoped_refptr<VideoFrame>> model_frames_; }; } // namespace @@ -430,7 +531,8 @@ (args.size() >= 2) ? base::FilePath(args[1]) : base::FilePath(); // Parse command line arguments. - bool enable_validator = true; + auto validator_type = + media::test::VideoPlayerTestEnvironment::ValidatorType::kMD5; media::test::FrameOutputConfig frame_output_config; base::FilePath::StringType output_folder = base::FilePath::kCurrentDirectory; bool use_vd = false; @@ -445,8 +547,21 @@ continue; } - if (it->first == "disable_validator") { - enable_validator = false; + if (it->first == "validator_type") { + if (it->second == "none") { + validator_type = + media::test::VideoPlayerTestEnvironment::ValidatorType::kNone; + } else if (it->second == "md5") { + validator_type = + media::test::VideoPlayerTestEnvironment::ValidatorType::kMD5; + } else if (it->second == "ssim") { + validator_type = + media::test::VideoPlayerTestEnvironment::ValidatorType::kSSIM; + } else { + std::cout << "unknown validator type \"" << it->second + << "\", possible values are \"none|md5|ssim\"\n"; + return EXIT_FAILURE; + } } else if (it->first == "output_frames") { if (it->second == "all") { frame_output_config.output_mode = media::test::FrameOutputMode::kAll; @@ -502,7 +617,7 @@ // Set up our test environment. media::test::VideoPlayerTestEnvironment* test_environment = media::test::VideoPlayerTestEnvironment::Create( - video_path, video_metadata_path, enable_validator, implementation, + video_path, video_metadata_path, validator_type, implementation, base::FilePath(output_folder), frame_output_config); if (!test_environment) return EXIT_FAILURE;
diff --git a/mojo/core/node_channel.cc b/mojo/core/node_channel.cc index e108f8e..7b52f70d 100644 --- a/mojo/core/node_channel.cc +++ b/mojo/core/node_channel.cc
@@ -692,7 +692,8 @@ case MessageType::REQUEST_INTRODUCTION: { IntroductionData data; - if (GetMessagePayload(payload, payload_size, &data)) { + if (GetMessagePayloadMinimumSized<IntroductionData, IntroductionDataV0>( + payload, payload_size, &data)) { delegate_->OnRequestIntroduction(remote_node_name_, data.name); return; } @@ -816,7 +817,8 @@ return; } - DLOG(ERROR) << "Received invalid message. Closing channel."; + DLOG(ERROR) << "Received invalid message type: " + << static_cast<int>(header->type) << " closing channel."; if (process_error_callback_) process_error_callback_.Run("NodeChannel received a malformed message"); delegate_->OnChannelError(remote_node_name_, this);
diff --git a/mojo/public/js/interface_support.js b/mojo/public/js/interface_support.js index 6e7f2ec..b93203a 100644 --- a/mojo/public/js/interface_support.js +++ b/mojo/public/js/interface_support.js
@@ -1032,6 +1032,16 @@ return this.connectionErrorEventRouter_; } + /** + * @return {!Promise} + * @export + */ + async flush() { + for (let endpoint of this.endpoints_) { + await endpoint.flushForTesting(); + } + } + /** @override */ onMessageReceived(endpoint, header, buffer, handles) { if (header.flags & mojo.internal.kMessageFlagIsResponse) @@ -1141,6 +1151,14 @@ close() { this.helper_internal_.closeBindings(); } + + /** + * @return {!Promise} + * @export + */ + flush() { + return this.helper_internal_.flush(); + } } /**
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index 4edefc9..07792a9 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -261,6 +261,7 @@ "//net", "//ppapi/cpp:objects", "//ppapi/cpp/private:internal_module", + "//skia", "//ui/base", ] } @@ -286,6 +287,7 @@ "//content/public/renderer", "//gin", "//ppapi/cpp:objects", # TODO(crbug.com/1114263): PDFEngine::Client only. + "//skia", "//third_party/blink/public:blink_headers", "//ui/base/cursor:cursor_base", "//v8",
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 956a847..c2b2eb2 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -643,11 +643,6 @@ if (!base::StringToUint(argv[i], &background_color)) return false; SetBackgroundColor(background_color); - } else if (strcmp(argn[i], "top-toolbar-height") == 0) { - int toolbar_height; - if (!base::StringToInt(argv[i], &toolbar_height)) - return false; - set_top_toolbar_height_in_viewport_coords(toolbar_height); } else if (strcmp(argn[i], "javascript") == 0) { if (strcmp(argv[i], "allow") != 0) script_option = PDFiumFormFiller::ScriptOption::kNoJavaScript; @@ -837,14 +832,7 @@ void OutOfProcessInstance::UpdateScroll() { DCHECK(!stop_scrolling_); - - // Because view messages come from the DOM, the coordinates of the viewport - // are 0-based (i.e. they do not correspond to the viewport's coordinates in - // JS), so we need to subtract the toolbar height to convert them into - // viewport coordinates. - gfx::PointF scroll_position_float( - scroll_position_.x(), - scroll_position_.y() - top_toolbar_height_in_viewport_coords()); + gfx::PointF scroll_position_float(scroll_position_.x(), scroll_position_.y()); scroll_position_float = BoundScrollPositionToDocument(scroll_position_float); engine()->ScrolledToXPosition(scroll_position_float.x() * device_scale()); engine()->ScrolledToYPosition(scroll_position_float.y() * device_scale()); @@ -944,8 +932,7 @@ void OutOfProcessInstance::SendAccessibilityViewportInfo() { PP_PrivateAccessibilityViewportInfo viewport_info; viewport_info.scroll.x = -plugin_offset().x(); - viewport_info.scroll.y = - -top_toolbar_height_in_viewport_coords() - plugin_offset().y(); + viewport_info.scroll.y = -plugin_offset().y(); viewport_info.offset.x = available_area().x() / (device_scale() * zoom()); viewport_info.offset.y = available_area().y() / (device_scale() * zoom()); @@ -1200,14 +1187,10 @@ PostMessage(position); } -void OutOfProcessInstance::ScrollToY(int y_in_screen_coords, - bool compensate_for_toolbar) { +void OutOfProcessInstance::ScrollToY(int y_in_screen_coords) { pp::VarDictionary position; position.Set(kType, kJSSetScrollPositionType); float new_y_viewport_coords = y_in_screen_coords / device_scale(); - if (compensate_for_toolbar) { - new_y_viewport_coords -= top_toolbar_height_in_viewport_coords(); - } position.Set(kJSPositionY, pp::Var(new_y_viewport_coords)); PostMessage(position); } @@ -2083,10 +2066,6 @@ PostMessage(message); } -float OutOfProcessInstance::GetToolbarHeightInScreenCoords() { - return top_toolbar_height_in_viewport_coords() * device_scale(); -} - void OutOfProcessInstance::DocumentFocusChanged(bool document_has_focus) { pp::VarDictionary message; message.Set(pp::Var(kType), pp::Var(kJSDocumentFocusChangedType)); @@ -2306,11 +2285,10 @@ document_size().width() * float{zoom()} - plugin_dip_size().width(), 0.0f); float x = base::ClampToRange(scroll_position.x(), 0.0f, max_x); - float min_y = -top_toolbar_height_in_viewport_coords(); float max_y = std::max( document_size().height() * float{zoom()} - plugin_dip_size().height(), - min_y); - float y = base::ClampToRange(scroll_position.y(), min_y, max_y); + 0.0f); + float y = base::ClampToRange(scroll_position.y(), 0.0f, max_y); return gfx::PointF(x, y); }
diff --git a/pdf/out_of_process_instance.h b/pdf/out_of_process_instance.h index cdc8430..908592a 100644 --- a/pdf/out_of_process_instance.h +++ b/pdf/out_of_process_instance.h
@@ -106,7 +106,7 @@ void ProposeDocumentLayout(const DocumentLayout& layout) override; void DidScroll(const gfx::Vector2d& offset) override; void ScrollToX(int x_in_screen_coords) override; - void ScrollToY(int y_in_screen_coords, bool compensate_for_toolbar) override; + void ScrollToY(int y_in_screen_coords) override; void ScrollBy(const gfx::Vector2d& scroll_delta) override; void ScrollToPage(int page) override; void NavigateTo(const std::string& url, @@ -152,7 +152,6 @@ void IsSelectingChanged(bool is_selecting) override; void SelectionChanged(const gfx::Rect& left, const gfx::Rect& right) override; void EnteredEditMode() override; - float GetToolbarHeightInScreenCoords() override; void DocumentFocusChanged(bool document_has_focus) override; void SetSelectedText(const std::string& selected_text) override; void SetLinkUnderCursor(const std::string& link_under_cursor) override;
diff --git a/pdf/pdf_engine.h b/pdf/pdf_engine.h index ae0d6c5..275a1efb 100644 --- a/pdf/pdf_engine.h +++ b/pdf/pdf_engine.h
@@ -155,11 +155,8 @@ // Scroll the horizontal/vertical scrollbars to a given position. // Values are in screen coordinates, where 0 is the top/left of the document // and a positive value is the distance in pixels from that line. - // For ScrollToY, setting |compensate_for_toolbar| will align the position - // with the bottom of the toolbar so the given position is always visible. virtual void ScrollToX(int x_in_screen_coords) {} - virtual void ScrollToY(int y_in_screen_coords, - bool compensate_for_toolbar) {} + virtual void ScrollToY(int y_in_screen_coords) {} // Scroll by a given delta relative to the current position. virtual void ScrollBy(const gfx::Vector2d& scroll_delta) {} @@ -281,10 +278,6 @@ // Notifies the client that the PDF has been edited. virtual void EnteredEditMode() {} - // Gets the height of the top toolbar in screen coordinates. This is - // independent of whether it is hidden or not at the moment. - virtual float GetToolbarHeightInScreenCoords() = 0; - // Notifies the client about focus changes for the document. virtual void DocumentFocusChanged(bool document_has_focus) {}
diff --git a/pdf/pdf_view_plugin_base.cc b/pdf/pdf_view_plugin_base.cc index e5b90f3..cb7a18ae 100644 --- a/pdf/pdf_view_plugin_base.cc +++ b/pdf/pdf_view_plugin_base.cc
@@ -146,9 +146,7 @@ // The distance between top of the plugin and the bottom of the document in // pixels. - int bottom_of_document = - GetDocumentPixelHeight() + - (top_toolbar_height_in_viewport_coords() * device_scale()); + int bottom_of_document = GetDocumentPixelHeight(); if (bottom_of_document < plugin_size_.height()) available_area_.set_height(bottom_of_document);
diff --git a/pdf/pdf_view_plugin_base.h b/pdf/pdf_view_plugin_base.h index ffaf6d6..4553c82 100644 --- a/pdf/pdf_view_plugin_base.h +++ b/pdf/pdf_view_plugin_base.h
@@ -136,14 +136,6 @@ background_color_ = background_color; } - int top_toolbar_height_in_viewport_coords() const { - return top_toolbar_height_in_viewport_coords_; - } - - void set_top_toolbar_height_in_viewport_coords(int height) { - top_toolbar_height_in_viewport_coords_ = height; - } - // Sets the new zoom scale. void SetZoom(double scale); @@ -216,10 +208,6 @@ // The background color of the PDF viewer. SkColor background_color_ = SK_ColorTRANSPARENT; - // The blank space above the first page of the document reserved for the - // toolbar. - int top_toolbar_height_in_viewport_coords_ = 0; - // Current zoom factor. double zoom_ = 1.0;
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index ca00729..298a68f 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -43,6 +43,7 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_plugin_container.h" #include "third_party/blink/public/web/web_plugin_params.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/cursor/cursor.h" #include "v8/include/v8.h" @@ -112,19 +113,12 @@ if (initial_params_.attribute_names[i] == "stream-url") { stream_url = initial_params_.attribute_values[i].Utf8(); } else if (initial_params_.attribute_names[i] == "background-color") { - uint32_t background_color; - if (!base::HexStringToUInt(initial_params_.attribute_values[i].Utf8(), - &background_color)) { + SkColor background_color; + if (!base::StringToUint(initial_params_.attribute_values[i].Utf8(), + &background_color)) { return false; } SetBackgroundColor(background_color); - } else if (initial_params_.attribute_names[i] == "top-toolbar-height") { - int toolbar_height; - if (!base::StringToInt(initial_params_.attribute_values[i].Utf8(), - &toolbar_height)) { - return false; - } - set_top_toolbar_height_in_viewport_coords(toolbar_height); } } @@ -203,8 +197,7 @@ void PdfViewWebPlugin::ScrollToX(int x_in_screen_coords) {} -void PdfViewWebPlugin::ScrollToY(int y_in_screen_coords, - bool compensate_for_toolbar) {} +void PdfViewWebPlugin::ScrollToY(int y_in_screen_coords) {} void PdfViewWebPlugin::ScrollBy(const gfx::Vector2d& scroll_delta) {} @@ -306,10 +299,6 @@ void PdfViewWebPlugin::EnteredEditMode() {} -float PdfViewWebPlugin::GetToolbarHeightInScreenCoords() { - return 0; -} - void PdfViewWebPlugin::DocumentFocusChanged(bool document_has_focus) {} void PdfViewWebPlugin::SetSelectedText(const std::string& selected_text) {
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h index a8bdef5..3cfba36 100644 --- a/pdf/pdf_view_web_plugin.h +++ b/pdf/pdf_view_web_plugin.h
@@ -59,7 +59,7 @@ void ProposeDocumentLayout(const DocumentLayout& layout) override; void DidScroll(const gfx::Vector2d& offset) override; void ScrollToX(int x_in_screen_coords) override; - void ScrollToY(int y_in_screen_coords, bool compensate_for_toolbar) override; + void ScrollToY(int y_in_screen_coords) override; void ScrollBy(const gfx::Vector2d& scroll_delta) override; void ScrollToPage(int page) override; void NavigateTo(const std::string& url, @@ -105,7 +105,6 @@ void IsSelectingChanged(bool is_selecting) override; void SelectionChanged(const gfx::Rect& left, const gfx::Rect& right) override; void EnteredEditMode() override; - float GetToolbarHeightInScreenCoords() override; void DocumentFocusChanged(bool document_has_focus) override; void SetSelectedText(const std::string& selected_text) override; void SetLinkUnderCursor(const std::string& link_under_cursor) override;
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 93532a2..1d92e69 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -2082,7 +2082,7 @@ // Make the page centered. int new_y = CalculateCenterForZoom(center.y(), visible_rect.height(), current_zoom_); - client_->ScrollToY(new_y, /*compensate_for_toolbar=*/false); + client_->ScrollToY(new_y); // Only move horizontally if it's not visible. if (center.x() < visible_rect.x() || center.x() > visible_rect.right()) { @@ -3855,10 +3855,6 @@ pages_[index.page_index]->IsCharIndexInBounds(index.char_index); } -float PDFiumEngine::GetToolbarHeightInScreenCoords() { - return client_->GetToolbarHeightInScreenCoords(); -} - FPDF_BOOL PDFiumEngine::Pause_NeedToPauseNow(IFSDK_PAUSE* param) { PDFiumEngine* engine = static_cast<PDFiumEngine*>(param); return base::Time::Now() - engine->last_progressive_start_time_ > @@ -3931,8 +3927,7 @@ if (rect.y() < visible_rect.y() || rect.bottom() > visible_rect.bottom()) { // Scroll the viewport vertically to align the top of focus rect to // centre. - client_->ScrollToY(rect.y() * current_zoom_ - plugin_size_.height() / 2, - /*compensate_for_toolbar=*/false); + client_->ScrollToY(rect.y() * current_zoom_ - plugin_size_.height() / 2); } if (rect.x() < visible_rect.x() || rect.right() > visible_rect.right()) { // Scroll the viewport horizontally to align the left of focus rect to
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index 448b012f..c5da034 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -554,10 +554,6 @@ bool IsPageCharacterIndexInBounds( const PP_PdfPageCharacterIndex& index) const; - // Gets the height of the top toolbar in screen coordinates. This is - // independent of whether it is hidden or not at the moment. - float GetToolbarHeightInScreenCoords(); - void ScheduleTouchTimer(const TouchInputEvent& event); void KillTouchTimer(); void HandleLongPress(const TouchInputEvent& event);
diff --git a/pdf/pdfium/pdfium_engine_unittest.cc b/pdf/pdfium/pdfium_engine_unittest.cc index 9489a3c..931c245 100644 --- a/pdf/pdfium/pdfium_engine_unittest.cc +++ b/pdf/pdfium/pdfium_engine_unittest.cc
@@ -1048,7 +1048,7 @@ // Mock PDFEngine::Client methods. MOCK_METHOD(void, ScrollToX, (int), (override)); - MOCK_METHOD(void, ScrollToY, (int, bool), (override)); + MOCK_METHOD(void, ScrollToY, (int), (override)); }; TEST_F(PDFiumEngineTabbingTest, MaintainViewportWhenFocusIsUpdated) { @@ -1062,7 +1062,7 @@ { InSequence sequence; static constexpr gfx::Point kScrollValue = {510, 478}; - EXPECT_CALL(client, ScrollToY(kScrollValue.y(), false)) + EXPECT_CALL(client, ScrollToY(kScrollValue.y())) .WillOnce(Invoke( [&engine]() { engine->ScrolledToYPosition(kScrollValue.y()); })); EXPECT_CALL(client, ScrollToX(kScrollValue.x())) @@ -1117,7 +1117,7 @@ static constexpr gfx::Point kScrollValues[] = {{510, 478}, {510, 478}}; for (const auto& scroll_value : kScrollValues) { - EXPECT_CALL(client, ScrollToY(scroll_value.y(), false)) + EXPECT_CALL(client, ScrollToY(scroll_value.y())) .WillOnce(Invoke([&engine, &scroll_value]() { engine->ScrolledToYPosition(scroll_value.y()); }));
diff --git a/pdf/pdfium/pdfium_form_filler.cc b/pdf/pdfium/pdfium_form_filler.cc index 2e55748..b0c57366af 100644 --- a/pdf/pdfium/pdfium_form_filler.cc +++ b/pdf/pdfium/pdfium_form_filler.cc
@@ -405,9 +405,6 @@ gfx::Rect page_view_rect = engine->GetPageContentsRect(page_index); - float toolbar_height_in_screen_coords = - engine->GetToolbarHeightInScreenCoords(); - float page_width = FPDF_GetPageWidth(page); float page_height = FPDF_GetPageHeight(page); @@ -420,11 +417,10 @@ // coords, we use (page_width * (x - base_x) / page_view_rect.width()). // For y positions, (page_height * (y - base_y) / page_view_rect.height()). - // The top-most y position that can be relied to be visible on the screen is - // the bottom of the toolbar, which is y = toolbar_height_in_screen_coords. + // The top-most x position that is visible on the screen is the top of the + // plugin area, which is y = 0. float screen_top_in_page_coords = - page_height * (toolbar_height_in_screen_coords - page_view_rect.y()) / - page_view_rect.height(); + page_height * (0 - page_view_rect.y()) / page_view_rect.height(); // The bottom-most y position that is visible on the screen is the bottom of // the plugin area, which is y = engine->plugin_size_.height(). float screen_bottom_in_page_coords =
diff --git a/pdf/pdfium/pdfium_form_filler_unittest.cc b/pdf/pdfium/pdfium_form_filler_unittest.cc index ab5c48d..031bff0 100644 --- a/pdf/pdfium/pdfium_form_filler_unittest.cc +++ b/pdf/pdfium/pdfium_form_filler_unittest.cc
@@ -27,7 +27,7 @@ // Mock PDFEngine::Client methods. MOCK_METHOD(void, ScrollToX, (int), (override)); - MOCK_METHOD(void, ScrollToY, (int, bool), (override)); + MOCK_METHOD(void, ScrollToY, (int), (override)); MOCK_METHOD(void, NavigateTo, (const std::string&, WindowOpenDisposition), @@ -140,8 +140,7 @@ for (const auto& test_case : test_cases) { if (test_case.final_scroll_position.y() != 0) { - EXPECT_CALL(client, - ScrollToY(test_case.final_scroll_position.y(), false)); + EXPECT_CALL(client, ScrollToY(test_case.final_scroll_position.y())); } if (test_case.final_scroll_position.x() != 0) EXPECT_CALL(client, ScrollToX(test_case.final_scroll_position.x()));
diff --git a/pdf/preview_mode_client.cc b/pdf/preview_mode_client.cc index ec128f2..78ce8721 100644 --- a/pdf/preview_mode_client.cc +++ b/pdf/preview_mode_client.cc
@@ -39,8 +39,7 @@ NOTREACHED(); } -void PreviewModeClient::ScrollToY(int y_in_screen_coords, - bool compensate_for_toolbar) { +void PreviewModeClient::ScrollToY(int y_in_screen_coords) { NOTREACHED(); } @@ -158,10 +157,6 @@ return true; } -float PreviewModeClient::GetToolbarHeightInScreenCoords() { - return 0.0f; -} - SkColor PreviewModeClient::GetBackgroundColor() { NOTREACHED(); return SK_ColorTRANSPARENT;
diff --git a/pdf/preview_mode_client.h b/pdf/preview_mode_client.h index 4aab79e..24bdc61 100644 --- a/pdf/preview_mode_client.h +++ b/pdf/preview_mode_client.h
@@ -38,7 +38,7 @@ void Invalidate(const gfx::Rect& rect) override; void DidScroll(const gfx::Vector2d& offset) override; void ScrollToX(int x_in_screen_coords) override; - void ScrollToY(int y_in_screen_coords, bool compensate_for_toolbar) override; + void ScrollToY(int y_in_screen_coords) override; void ScrollBy(const gfx::Vector2d& scroll_delta) override; void ScrollToPage(int page) override; void NavigateTo(const std::string& url, @@ -74,7 +74,6 @@ void DocumentHasUnsupportedFeature(const std::string& feature) override; void FormTextFieldFocusChange(bool in_focus) override; bool IsPrintPreview() override; - float GetToolbarHeightInScreenCoords() override; SkColor GetBackgroundColor() override; void SetSelectedText(const std::string& selected_text) override; void SetLinkUnderCursor(const std::string& link_under_cursor) override;
diff --git a/pdf/test/test_client.cc b/pdf/test/test_client.cc index 654e557..1c7b87a7 100644 --- a/pdf/test/test_client.cc +++ b/pdf/test/test_client.cc
@@ -62,10 +62,6 @@ return SK_ColorTRANSPARENT; } -float TestClient::GetToolbarHeightInScreenCoords() { - return 0; -} - void TestClient::SetSelectedText(const std::string& selected_text) {} void TestClient::SetLinkUnderCursor(const std::string& link_under_cursor) {}
diff --git a/pdf/test/test_client.h b/pdf/test/test_client.h index 296b970..65b4265 100644 --- a/pdf/test/test_client.h +++ b/pdf/test/test_client.h
@@ -38,7 +38,6 @@ pp::Instance* GetPluginInstance() override; bool IsPrintPreview() override; SkColor GetBackgroundColor() override; - float GetToolbarHeightInScreenCoords() override; void SetSelectedText(const std::string& selected_text) override; void SetLinkUnderCursor(const std::string& link_under_cursor) override; bool IsValidLink(const std::string& url) override;
diff --git a/services/device/public/cpp/test/fake_usb_device_info.cc b/services/device/public/cpp/test/fake_usb_device_info.cc index 950e30b3..82a7fa4 100644 --- a/services/device/public/cpp/test/fake_usb_device_info.cc +++ b/services/device/public/cpp/test/fake_usb_device_info.cc
@@ -44,6 +44,7 @@ device_info_.manufacturer_name = base::UTF8ToUTF16(manufacturer_string); device_info_.product_name = base::UTF8ToUTF16(product_string); device_info_.serial_number = base::UTF8ToUTF16(serial_number); + AddConfig(CreateConfiguration(0xFF, 0x00, 0x00)); } FakeUsbDeviceInfo::FakeUsbDeviceInfo(uint16_t vendor_id, @@ -135,4 +136,25 @@ observer.OnDeviceRemoved(this); } +mojom::UsbConfigurationInfoPtr FakeUsbDeviceInfo::CreateConfiguration( + uint8_t device_class, + uint8_t subclass_code, + uint8_t protocol_code, + uint8_t configuration_value) { + auto alternate = device::mojom::UsbAlternateInterfaceInfo::New(); + alternate->alternate_setting = 0; + alternate->class_code = device_class; + alternate->subclass_code = subclass_code; + alternate->protocol_code = protocol_code; + + auto interface = device::mojom::UsbInterfaceInfo::New(); + interface->interface_number = 0; + interface->alternates.push_back(std::move(alternate)); + + auto config = device::mojom::UsbConfigurationInfo::New(); + config->configuration_value = configuration_value; + config->interfaces.push_back(std::move(interface)); + return config; +} + } // namespace device
diff --git a/services/device/public/cpp/test/fake_usb_device_info.h b/services/device/public/cpp/test/fake_usb_device_info.h index 9dcc973..e737268 100644 --- a/services/device/public/cpp/test/fake_usb_device_info.h +++ b/services/device/public/cpp/test/fake_usb_device_info.h
@@ -22,6 +22,8 @@ // This class acts like device::UsbDevice and provides mojom::UsbDeviceInfo. // It should be used together with FakeUsbDeviceManager just for testing. +// For convenience, a default configuration will be set if the chosen +// constructor does not explicitly set these. class FakeUsbDeviceInfo : public base::RefCounted<FakeUsbDeviceInfo> { public: class Observer : public base::CheckedObserver { @@ -77,6 +79,12 @@ void SetMockDevice(MockUsbMojoDevice* device) { mock_device_ = device; } MockUsbMojoDevice* mock_device() const { return mock_device_; } + static mojom::UsbConfigurationInfoPtr CreateConfiguration( + uint8_t device_class, + uint8_t subclass_code, + uint8_t protocol_code, + uint8_t configuration_value = 1); + protected: friend class RefCounted<FakeUsbDeviceInfo>; virtual ~FakeUsbDeviceInfo();
diff --git a/services/network/public/cpp/content_security_policy/content_security_policy.cc b/services/network/public/cpp/content_security_policy/content_security_policy.cc index 939ec5ee..fcfa2ec 100644 --- a/services/network/public/cpp/content_security_policy/content_security_policy.cc +++ b/services/network/public/cpp/content_security_policy/content_security_policy.cc
@@ -40,8 +40,9 @@ } bool IsDirectiveValueCharacter(char c) { + // Whitespace + VCHAR, but not ',' and ';' return base::IsAsciiWhitespace(c) || - base::IsAsciiPrintable(c); // Whitespace + VCHAR + (base::IsAsciiPrintable(c) && c != ',' && c != ';'); } std::string ElideURLForReportViolation(const GURL& url) { @@ -1248,14 +1249,6 @@ if (!policy[0]) return false; - if (!policy[0]->parsing_errors.empty()) { - error_message = - "Parsing the csp attribute into a Content-Security-Policy returned one " - "or more parsing errors: " + - base::JoinString(policy[0]->parsing_errors, " "); - return false; - } - if (!policy[0]->report_endpoints.empty() || // We really don't want any report directives, even with invalid/missing // endpoints.
diff --git a/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc b/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc index 92004af9..6be02036 100644 --- a/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc +++ b/services/network/public/cpp/content_security_policy/content_security_policy_unittest.cc
@@ -1481,14 +1481,14 @@ const char* csp; bool expected; std::string expected_error; - } cases[] = {{"script-src 'none'", true, ""}, - {"script-src 'none'; invalid-directive", false, - "Parsing the csp attribute into a Content-Security-Policy " - "returned one or more parsing errors: Unrecognized " - "Content-Security-Policy directive 'invalid-directive'."}, - {"script-src 'none'; report-uri https://www.example.com", false, - "The csp attribute cannot contain the directives 'report-to' " - "or 'report-uri'."}}; + } cases[] = { + {" script-src 'none' https://www.google.com ;; ; invalid-directive " + "invalid-value ;", + true, ""}, + {"script-src 'none'; report-uri https://www.example.com", false, + "The csp attribute cannot contain the directives 'report-to' " + "or 'report-uri'."}, + }; for (auto& test : cases) { SCOPED_TRACE(test.csp); @@ -1498,6 +1498,12 @@ required_csp_headers->SetHeader("Content-Security-Policy", test.csp); AddContentSecurityPolicyFromHeaders(*required_csp_headers, GURL("https://example.com/"), &csp); + + // Overwrite the header_value artificially. At the moment, our header parser + // takes already care of some parts (like removing commas). But we want to + // be sure that header values with commas or other invalid header values are + // blocked by our validation mechanism anyway. + csp[0]->header->header_value = test.csp; std::string out; EXPECT_EQ(test.expected, IsValidRequiredCSPAttr(csp, nullptr, out)); EXPECT_EQ(test.expected_error, out);
diff --git a/services/preferences/tracked/registry_hash_store_contents_win.cc b/services/preferences/tracked/registry_hash_store_contents_win.cc index 8b28d35..27bd33e0 100644 --- a/services/preferences/tracked/registry_hash_store_contents_win.cc +++ b/services/preferences/tracked/registry_hash_store_contents_win.cc
@@ -24,19 +24,19 @@ constexpr size_t kMacSize = 64; -base::string16 GetSplitPrefKeyName(const base::string16& reg_key_name, - const std::string& split_key_name) { - return reg_key_name + L"\\" + base::UTF8ToUTF16(split_key_name); +std::wstring GetSplitPrefKeyName(const std::wstring& reg_key_name, + const std::string& split_key_name) { + return reg_key_name + L"\\" + base::UTF8ToWide(split_key_name); } bool ReadMacFromRegistry(const base::win::RegKey& key, const std::string& value_name, std::string* out_mac) { - base::string16 string_value; - if (key.ReadValue(base::UTF8ToUTF16(value_name).c_str(), &string_value) == + std::wstring string_value; + if (key.ReadValue(base::UTF8ToWide(value_name).c_str(), &string_value) == ERROR_SUCCESS && string_value.size() == kMacSize) { - out_mac->assign(base::UTF16ToUTF8(string_value)); + out_mac->assign(base::WideToUTF8(string_value)); return true; } return false; @@ -44,12 +44,12 @@ // Removes |value_name| under |reg_key_name|. Returns true if found and // successfully removed. -bool ClearAtomicMac(const base::string16& reg_key_name, +bool ClearAtomicMac(const std::wstring& reg_key_name, const std::string& value_name) { base::win::RegKey key; if (key.Open(HKEY_CURRENT_USER, reg_key_name.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { - return key.DeleteValue(base::UTF8ToUTF16(value_name).c_str()) == + return key.DeleteValue(base::UTF8ToWide(value_name).c_str()) == ERROR_SUCCESS; } return false; @@ -57,7 +57,7 @@ // Deletes |split_key_name| under |reg_key_name|. Returns true if found and // successfully removed. -bool ClearSplitMac(const base::string16& reg_key_name, +bool ClearSplitMac(const std::wstring& reg_key_name, const std::string& split_key_name) { base::win::RegKey key; if (key.Open(HKEY_CURRENT_USER, @@ -69,7 +69,7 @@ } // Deletes |reg_key_name| if it exists. -void DeleteRegistryKey(const base::string16& reg_key_name) { +void DeleteRegistryKey(const std::wstring& reg_key_name) { base::win::RegKey key; if (key.Open(HKEY_CURRENT_USER, reg_key_name.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { @@ -81,7 +81,7 @@ } // namespace void TempScopedDirRegistryCleaner::SetRegistryPath( - const base::string16& registry_path) { + const std::wstring& registry_path) { if (registry_path_.empty()) registry_path_ = registry_path; else @@ -94,8 +94,8 @@ } RegistryHashStoreContentsWin::RegistryHashStoreContentsWin( - const base::string16& registry_path, - const base::string16& store_key, + const std::wstring& registry_path, + const std::wstring& store_key, scoped_refptr<TempScopedDirCleaner> temp_dir_cleaner) : preference_key_name_(registry_path + L"\\PreferenceMACs\\" + store_key), temp_dir_cleaner_(std::move(temp_dir_cleaner)) { @@ -148,8 +148,8 @@ GetSplitPrefKeyName(preference_key_name_, path).c_str()); for (; iter_key.Valid(); ++iter_key) { - split_macs->insert(make_pair(base::UTF16ToUTF8(iter_key.Name()), - base::UTF16ToUTF8(iter_key.Value()))); + split_macs->insert(make_pair(base::WideToUTF8(iter_key.Name()), + base::WideToUTF8(iter_key.Value()))); } return !split_macs->empty(); @@ -162,8 +162,8 @@ if (key.Create(HKEY_CURRENT_USER, preference_key_name_.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { - key.WriteValue(base::UTF8ToUTF16(path).c_str(), - base::UTF8ToUTF16(value).c_str()); + key.WriteValue(base::UTF8ToWide(path).c_str(), + base::UTF8ToWide(value).c_str()); } } @@ -176,8 +176,8 @@ if (key.Create(HKEY_CURRENT_USER, GetSplitPrefKeyName(preference_key_name_, path).c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { - key.WriteValue(base::UTF8ToUTF16(split_path).c_str(), - base::UTF8ToUTF16(value).c_str()); + key.WriteValue(base::UTF8ToWide(split_path).c_str(), + base::UTF8ToWide(value).c_str()); } }
diff --git a/services/preferences/tracked/registry_hash_store_contents_win.h b/services/preferences/tracked/registry_hash_store_contents_win.h index dd55669..234b805 100644 --- a/services/preferences/tracked/registry_hash_store_contents_win.h +++ b/services/preferences/tracked/registry_hash_store_contents_win.h
@@ -5,21 +5,22 @@ #ifndef SERVICES_PREFERENCES_TRACKED_REGISTRY_HASH_STORE_CONTENTS_WIN_H_ #define SERVICES_PREFERENCES_TRACKED_REGISTRY_HASH_STORE_CONTENTS_WIN_H_ +#include <string> + #include "base/macros.h" -#include "base/strings/string16.h" #include "services/preferences/tracked/hash_store_contents.h" #include "services/preferences/tracked/temp_scoped_dir_cleaner.h" // Helper object to clear registry entries for scoped temporary pref stores. class TempScopedDirRegistryCleaner : public TempScopedDirCleaner { public: - void SetRegistryPath(const base::string16& registry_path); + void SetRegistryPath(const std::wstring& registry_path); private: friend class base::RefCountedThreadSafe<TempScopedDirRegistryCleaner>; ~TempScopedDirRegistryCleaner() override; - base::string16 registry_path_; + std::wstring registry_path_; }; // Implements HashStoreContents by storing MACs in the Windows registry. @@ -28,8 +29,8 @@ // Constructs a RegistryHashStoreContents which acts on a registry entry // defined by |registry_path| and |store_key|. explicit RegistryHashStoreContentsWin( - const base::string16& registry_path, - const base::string16& store_key, + const std::wstring& registry_path, + const std::wstring& store_key, scoped_refptr<TempScopedDirCleaner> temp_dir_cleaner); ~RegistryHashStoreContentsWin() override; @@ -59,7 +60,7 @@ explicit RegistryHashStoreContentsWin( const RegistryHashStoreContentsWin& other); - const base::string16 preference_key_name_; + const std::wstring preference_key_name_; scoped_refptr<TempScopedDirCleaner> temp_dir_cleaner_; };
diff --git a/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc b/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc index aa807d58..ad810a7 100644 --- a/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc +++ b/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc
@@ -16,8 +16,8 @@ namespace { -constexpr base::char16 kRegistryPath[] = L"Foo\\TestStore"; -constexpr base::char16 kStoreKey[] = L"test_store_key"; +constexpr wchar_t kRegistryPath[] = L"Foo\\TestStore"; +constexpr wchar_t kStoreKey[] = L"test_store_key"; // Hex-encoded MACs are 64 characters long. constexpr char kTestStringA[] = @@ -128,8 +128,8 @@ base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - const base::string16 registry_path = - temp_dir.GetPath().DirName().BaseName().LossyDisplayName(); + const std::wstring registry_path = + temp_dir.GetPath().DirName().BaseName().value(); RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey, nullptr); @@ -159,7 +159,7 @@ } void OffThreadTempScopedDirDestructor( - base::string16 registry_path, + std::wstring registry_path, std::unique_ptr<HashStoreContents> contents) { std::string stored_mac; @@ -179,8 +179,8 @@ base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - const base::string16 registry_path = - temp_dir.GetPath().DirName().BaseName().LossyDisplayName(); + const std::wstring registry_path = + temp_dir.GetPath().DirName().BaseName().value(); RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey, nullptr);
diff --git a/services/preferences/tracked/tracked_persistent_pref_store_factory.cc b/services/preferences/tracked/tracked_persistent_pref_store_factory.cc index 65052cc1..4d135729 100644 --- a/services/preferences/tracked/tracked_persistent_pref_store_factory.cc +++ b/services/preferences/tracked/tracked_persistent_pref_store_factory.cc
@@ -49,15 +49,14 @@ const prefs::mojom::TrackedPersistentPrefStoreConfiguration& config, scoped_refptr<TempScopedDirCleaner> temp_dir_cleaner) { #if defined(OS_WIN) - return std::make_pair(std::make_unique<PrefHashStoreImpl>( - config.registry_seed, config.legacy_device_id, - false /* use_super_mac */), - std::make_unique<RegistryHashStoreContentsWin>( - config.registry_path, - config.unprotected_pref_filename.DirName() - .BaseName() - .LossyDisplayName(), - std::move(temp_dir_cleaner))); + return std::make_pair( + std::make_unique<PrefHashStoreImpl>(config.registry_seed, + config.legacy_device_id, + false /* use_super_mac */), + std::make_unique<RegistryHashStoreContentsWin>( + base::AsWString(config.registry_path), + config.unprotected_pref_filename.DirName().BaseName().value(), + std::move(temp_dir_cleaner))); #else return std::make_pair(nullptr, nullptr); #endif @@ -92,11 +91,10 @@ // object between the unprotected and protected hash filter's // RegistryHashStoreContentsWin which will clear the registry keys when // destroyed. (https://crbug.com/721245) - if (base::StartsWith(config->unprotected_pref_filename.DirName() - .BaseName() - .LossyDisplayName(), - base::ScopedTempDir::GetTempDirPrefix(), - base::CompareCase::INSENSITIVE_ASCII)) { + if (base::StartsWith( + config->unprotected_pref_filename.DirName().BaseName().value(), + base::ScopedTempDir::GetTempDirPrefix(), + base::CompareCase::INSENSITIVE_ASCII)) { temp_scoped_dir_cleaner = base::MakeRefCounted<TempScopedDirRegistryCleaner>(); }
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn index 35b9713..bb9f5ff 100644 --- a/storage/browser/BUILD.gn +++ b/storage/browser/BUILD.gn
@@ -211,6 +211,8 @@ "quota/quota_temporary_storage_evictor.h", "quota/special_storage_policy.cc", "quota/special_storage_policy.h", + "quota/storage_policy_observer.cc", + "quota/storage_policy_observer.h", "quota/usage_tracker.cc", "quota/usage_tracker.h", ]
diff --git a/storage/browser/file_system/file_system_context.cc b/storage/browser/file_system/file_system_context.cc index 51aacf1..e249cc7e 100644 --- a/storage/browser/file_system/file_system_context.cc +++ b/storage/browser/file_system/file_system_context.cc
@@ -641,12 +641,8 @@ DCHECK(result); } - // TODO(mtomasz): Not all fields should be required for ResolveURL. operation_runner()->GetMetadata( - url, - FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY | - FileSystemOperation::GET_METADATA_FIELD_SIZE | - FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED, + url, FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY, base::BindOnce(&DidGetMetadataForResolveURL, path, std::move(callback), info)); }
diff --git a/storage/browser/quota/storage_policy_observer.cc b/storage/browser/quota/storage_policy_observer.cc new file mode 100644 index 0000000..7b3e774 --- /dev/null +++ b/storage/browser/quota/storage_policy_observer.cc
@@ -0,0 +1,123 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "storage/browser/quota/storage_policy_observer.h" + +#include <utility> + +#include "base/task/post_task.h" +#include "url/origin.h" + +namespace storage { + +// A helper class that lives on the IO thread and registers with +// SpecialStoragePolicy. It bounces back any OnPolicyChanged messages +// to the StoragePolicyObserver on the provided `reply_task_runner`. +class StoragePolicyObserverIOThread + : public storage::SpecialStoragePolicy::Observer { + public: + StoragePolicyObserverIOThread( + scoped_refptr<base::SequencedTaskRunner> reply_task_runner, + scoped_refptr<storage::SpecialStoragePolicy> storage_policy, + base::WeakPtr<StoragePolicyObserver> observer) + : reply_task_runner_(std::move(reply_task_runner)), + storage_policy_(std::move(storage_policy)), + observer_(std::move(observer)) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + storage_policy_->AddObserver(this); + } + + ~StoragePolicyObserverIOThread() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + storage_policy_->RemoveObserver(this); + } + + // storage::SpecialStoragePolicy::Observer implementation: + void OnPolicyChanged() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + reply_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&StoragePolicyObserver::OnPolicyChanged, observer_)); + } + + private: + scoped_refptr<base::SequencedTaskRunner> reply_task_runner_; + scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; + + SEQUENCE_CHECKER(sequence_checker_); + base::WeakPtr<StoragePolicyObserver> observer_; +}; + +StoragePolicyObserver::StoragePolicyObserver( + ApplyPolicyUpdatesCallback callback, + scoped_refptr<base::SequencedTaskRunner> io_task_runner, + scoped_refptr<storage::SpecialStoragePolicy> storage_policy) + : callback_(callback), storage_policy_(std::move(storage_policy)) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!storage_policy_) + return; + + storage_policy_observer_ = base::SequenceBound<StoragePolicyObserverIOThread>( + std::move(io_task_runner), base::SequencedTaskRunnerHandle::Get(), + storage_policy_, weak_factory_.GetWeakPtr()); +} + +StoragePolicyObserver::~StoragePolicyObserver() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +void StoragePolicyObserver::StartTrackingOrigin(const url::Origin& origin) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // If the origin exists, emplace fails, and its state is unchanged. + const GURL origin_url = GURL(origin.Serialize()); + origin_state_.emplace(origin_url, OriginState()); + + OnPolicyChanged(); +} + +void StoragePolicyObserver::StopTrackingOrigin(const url::Origin& origin) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + const GURL origin_url = GURL(origin.Serialize()); + origin_state_.erase(origin_url); +} + +void StoragePolicyObserver::OnPolicyChanged() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + std::vector<storage::mojom::StoragePolicyUpdatePtr> policy_updates; + for (auto& entry : origin_state_) { + const GURL& origin = entry.first; + OriginState& state = entry.second; + state.should_purge_on_shutdown = ShouldPurgeOnShutdown(origin); + + if (state.should_purge_on_shutdown != state.will_purge_on_shutdown) { + state.will_purge_on_shutdown = state.should_purge_on_shutdown; + policy_updates.emplace_back(storage::mojom::StoragePolicyUpdate::New( + url::Origin::Create(origin), state.should_purge_on_shutdown)); + } + } + if (policy_updates.empty()) + return; + callback_.Run(std::move(policy_updates)); +} + +bool StoragePolicyObserver::ShouldPurgeOnShutdownForTesting( + const url::Origin& origin) { + const GURL origin_url = GURL(origin.Serialize()); + return ShouldPurgeOnShutdown(origin_url); +} + +bool StoragePolicyObserver::ShouldPurgeOnShutdown(const GURL& origin) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!storage_policy_) + return false; + if (!storage_policy_->IsStorageSessionOnly(origin)) + return false; + if (storage_policy_->IsStorageProtected(origin)) + return false; + return true; +} + +} // namespace storage
diff --git a/storage/browser/quota/storage_policy_observer.h b/storage/browser/quota/storage_policy_observer.h new file mode 100644 index 0000000..bb04ed8 --- /dev/null +++ b/storage/browser/quota/storage_policy_observer.h
@@ -0,0 +1,84 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef STORAGE_BROWSER_QUOTA_STORAGE_POLICY_OBSERVER_H_ +#define STORAGE_BROWSER_QUOTA_STORAGE_POLICY_OBSERVER_H_ + +#include <map> +#include <vector> + +#include "base/callback.h" +#include "base/component_export.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/threading/sequence_bound.h" +#include "components/services/storage/public/mojom/storage_policy_update.mojom.h" +#include "storage/browser/quota/special_storage_policy.h" +#include "url/gurl.h" + +namespace url { +class Origin; +} + +namespace storage { + +class StoragePolicyObserverIOThread; + +// A helper class that aggregates storage::mojom::StoragePolicyUpdate +// changes for tracked origins. `StartTrackingOrigin()` adds an origin +// to start tracking. When these origins have policy updates, +// the provided `callback` will be called with the policy update deltas. +class COMPONENT_EXPORT(STORAGE_BROWSER) StoragePolicyObserver { + public: + using ApplyPolicyUpdatesCallback = base::RepeatingCallback<void( + std::vector<storage::mojom::StoragePolicyUpdatePtr>)>; + + StoragePolicyObserver( + ApplyPolicyUpdatesCallback callback, + scoped_refptr<base::SequencedTaskRunner> io_task_runner, + scoped_refptr<storage::SpecialStoragePolicy> storage_policy); + ~StoragePolicyObserver(); + + StoragePolicyObserver(const StoragePolicyObserver&) = delete; + StoragePolicyObserver& operator=(const StoragePolicyObserver&) = delete; + + // These methods are idempotent. Tracking an origin that is already + // tracked and stopping tracking an origin that is not being tracked + // are noops. + void StartTrackingOrigin(const url::Origin& origin); + void StopTrackingOrigin(const url::Origin& origin); + + // Called by StoragePolicyObserverIOThread. + void OnPolicyChanged(); + + bool ShouldPurgeOnShutdownForTesting(const url::Origin& origin); + + private: + bool ShouldPurgeOnShutdown(const GURL& origin); + + SEQUENCE_CHECKER(sequence_checker_); + + struct OriginState { + // Indicates that storage for this origin should be purged on shutdown. + bool should_purge_on_shutdown = false; + // Indicates the last value for `purge_on_shutdown` that was communicated. + bool will_purge_on_shutdown = false; + }; + // NOTE: The GURL key is specifically an origin GURL. + // Special storage policy uses GURLs and not Origins, so it's simpler + // to store everything in GURL form. + std::map<GURL, OriginState> origin_state_; + + const ApplyPolicyUpdatesCallback callback_; + const scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; + + base::SequenceBound<StoragePolicyObserverIOThread> storage_policy_observer_; + + base::WeakPtrFactory<StoragePolicyObserver> weak_factory_{this}; +}; + +} // namespace storage + +#endif // STORAGE_BROWSER_QUOTA_STORAGE_POLICY_OBSERVER_H_
diff --git a/third_party/abseil-cpp/BUILD.gn b/third_party/abseil-cpp/BUILD.gn index 725a92d..d3497e509 100644 --- a/third_party/abseil-cpp/BUILD.gn +++ b/third_party/abseil-cpp/BUILD.gn
@@ -184,6 +184,7 @@ "absl/algorithm:algorithm_test", "absl/algorithm:container_test", "absl/base:config_test", + "absl/cleanup:cleanup_test", "absl/container:inlined_vector_test", "absl/memory:memory_test", "absl/meta:type_traits_test",
diff --git a/third_party/abseil-cpp/CMake/AbseilDll.cmake b/third_party/abseil-cpp/CMake/AbseilDll.cmake index b8c38d68..47707df 100644 --- a/third_party/abseil-cpp/CMake/AbseilDll.cmake +++ b/third_party/abseil-cpp/CMake/AbseilDll.cmake
@@ -60,6 +60,8 @@ "base/policy_checks.h" "base/port.h" "base/thread_annotations.h" + "cleanup/cleanup.h" + "cleanup/internal/cleanup.h" "container/btree_map.h" "container/btree_set.h" "container/fixed_array.h"
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index 2744cd8c..dbba8cf 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ License: Apache 2.0 License File: LICENSE Version: 0 -Revision: e4e2e57e1a4308cf4ba008d9c1f2d478b3349201 +Revision: 58a9c6d53f93078101c2c0bd98d2951e74328a55 Security Critical: yes Description:
diff --git a/third_party/abseil-cpp/README.md b/third_party/abseil-cpp/README.md index 76f1d1e1..264c4b3 100644 --- a/third_party/abseil-cpp/README.md +++ b/third_party/abseil-cpp/README.md
@@ -72,6 +72,9 @@ * [`algorithm`](absl/algorithm/) <br /> The `algorithm` library contains additions to the C++ `<algorithm>` library and container-based versions of such algorithms. +* [`cleanup`](absl/cleanup/) + <br /> The `cleanup` library contains the control-flow-construct-like type + `absl::Cleanup` which is used for executing a callback on scope exit. * [`container`](absl/container/) <br /> The `container` library contains additional STL-style containers, including Abseil's unordered "Swiss table" containers.
diff --git a/third_party/abseil-cpp/absl/base/attributes.h b/third_party/abseil-cpp/absl/base/attributes.h index 0ba1e7da..f14f7bb 100644 --- a/third_party/abseil-cpp/absl/base/attributes.h +++ b/third_party/abseil-cpp/absl/base/attributes.h
@@ -121,7 +121,7 @@ #if ABSL_HAVE_ATTRIBUTE(disable_tail_calls) #define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 #define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) -#elif defined(__GNUC__) && !defined(__clang__) +#elif defined(__GNUC__) && !defined(__clang__) && !defined(__e2k__) #define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 #define ABSL_ATTRIBUTE_NO_TAIL_CALL \ __attribute__((optimize("no-optimize-sibling-calls")))
diff --git a/third_party/abseil-cpp/absl/base/config.h b/third_party/abseil-cpp/absl/base/config.h index f6ddf0c..3d6aa17 100644 --- a/third_party/abseil-cpp/absl/base/config.h +++ b/third_party/abseil-cpp/absl/base/config.h
@@ -722,4 +722,13 @@ #define ABSL_HAVE_ADDRESS_SANITIZER 1 #endif +// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION +// +// Class template argument deduction is a language feature added in C++17. +#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION +#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set." +#elif defined(__cpp_deduction_guides) +#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 +#endif + #endif // ABSL_BASE_CONFIG_H_
diff --git a/third_party/abseil-cpp/absl/base/spinlock_test_common.cc b/third_party/abseil-cpp/absl/base/spinlock_test_common.cc index dee266e..2b572c5 100644 --- a/third_party/abseil-cpp/absl/base/spinlock_test_common.cc +++ b/third_party/abseil-cpp/absl/base/spinlock_test_common.cc
@@ -92,6 +92,7 @@ static void ThreadedTest(SpinLock* spinlock) { std::vector<std::thread> threads; + threads.reserve(kNumThreads); for (int i = 0; i < kNumThreads; ++i) { threads.push_back(std::thread(TestFunction, i, spinlock)); }
diff --git a/third_party/abseil-cpp/absl/cleanup/BUILD.bazel b/third_party/abseil-cpp/absl/cleanup/BUILD.bazel new file mode 100644 index 0000000..5cca898 --- /dev/null +++ b/third_party/abseil-cpp/absl/cleanup/BUILD.bazel
@@ -0,0 +1,66 @@ +# Copyright 2021 The Abseil Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load( + "//absl:copts/configure_copts.bzl", + "ABSL_DEFAULT_COPTS", + "ABSL_DEFAULT_LINKOPTS", + "ABSL_TEST_COPTS", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +cc_library( + name = "cleanup_internal", + hdrs = ["internal/cleanup.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/base:base_internal", + "//absl/base:core_headers", + "//absl/utility", + ], +) + +cc_library( + name = "cleanup", + hdrs = [ + "cleanup.h", + ], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":cleanup_internal", + "//absl/base:config", + "//absl/base:core_headers", + ], +) + +cc_test( + name = "cleanup_test", + size = "small", + srcs = [ + "cleanup_test.cc", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":cleanup", + "//absl/base:config", + "//absl/utility", + "@com_google_googletest//:gtest_main", + ], +)
diff --git a/third_party/abseil-cpp/absl/cleanup/BUILD.gn b/third_party/abseil-cpp/absl/cleanup/BUILD.gn new file mode 100644 index 0000000..3b7b6c0 --- /dev/null +++ b/third_party/abseil-cpp/absl/cleanup/BUILD.gn
@@ -0,0 +1,35 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/abseil-cpp/absl.gni") + +absl_source_set("cleanup_internal") { + public = [ "internal/cleanup.h" ] + deps = [ + "//third_party/abseil-cpp/absl/base:base_internal", + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/utility", + ] + visibility = [ "//third_party/abseil-cpp/absl/*" ] +} + +absl_source_set("cleanup") { + public = [ "cleanup.h" ] + deps = [ + ":cleanup_internal", + "//third_party/abseil-cpp/absl/base:config", + "//third_party/abseil-cpp/absl/base:core_headers", + ] +} + +absl_source_set("cleanup_test") { + testonly = true + sources = [ "cleanup_test.cc" ] + deps = [ + ":cleanup", + "//third_party/abseil-cpp/absl/base:config", + "//third_party/abseil-cpp/absl/utility", + "//third_party/googletest:gtest", + ] +}
diff --git a/third_party/abseil-cpp/absl/cleanup/CMakeLists.txt b/third_party/abseil-cpp/absl/cleanup/CMakeLists.txt new file mode 100644 index 0000000..a2dd78a --- /dev/null +++ b/third_party/abseil-cpp/absl/cleanup/CMakeLists.txt
@@ -0,0 +1,55 @@ +# Copyright 2021 The Abseil Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +absl_cc_library( + NAME + cleanup_internal + HDRS + "internal/cleanup.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base_internal + absl::core_headers + absl::utility + PUBLIC +) + +absl_cc_library( + NAME + cleanup + HDRS + "cleanup.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::cleanup_internal + absl::config + absl::core_headers + PUBLIC +) + +absl_cc_test( + NAME + cleanup_test + SRCS + "cleanup_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::cleanup + absl::config + absl::utility + gmock_main +)
diff --git a/third_party/abseil-cpp/absl/cleanup/cleanup.h b/third_party/abseil-cpp/absl/cleanup/cleanup.h new file mode 100644 index 0000000..5a4bc54 --- /dev/null +++ b/third_party/abseil-cpp/absl/cleanup/cleanup.h
@@ -0,0 +1,140 @@ +// Copyright 2021 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: cleanup.h +// ----------------------------------------------------------------------------- +// +// `absl::Cleanup` implements the scope guard idiom, invoking the contained +// callback's `operator()() &&` on scope exit. +// +// Example: +// +// ``` +// absl::Status CopyGoodData(const char* source_path, const char* sink_path) { +// FILE* source_file = fopen(source_path, "r"); +// if (source_file == nullptr) { +// return absl::NotFoundError("No source file"); // No cleanups execute +// } +// +// // C++17 style cleanup using class template argument deduction +// absl::Cleanup source_closer = [source_file] { fclose(source_file); }; +// +// FILE* sink_file = fopen(sink_path, "w"); +// if (sink_file == nullptr) { +// return absl::NotFoundError("No sink file"); // First cleanup executes +// } +// +// // C++11 style cleanup using the factory function +// auto sink_closer = absl::MakeCleanup([sink_file] { fclose(sink_file); }); +// +// Data data; +// while (ReadData(source_file, &data)) { +// if (data.IsBad()) { +// absl::Status result = absl::FailedPreconditionError("Read bad data"); +// return result; // Both cleanups execute +// } +// SaveData(sink_file, &data); +// } +// +// return absl::OkStatus(); // Both cleanups execute +// } +// ``` +// +// Methods: +// +// `std::move(cleanup).Cancel()` will prevent the callback from executing. +// +// `std::move(cleanup).Invoke()` will execute the callback early, before +// destruction, and prevent the callback from executing in the destructor. +// +// Usage: +// +// `absl::Cleanup` is not an interface type. It is only intended to be used +// within the body of a function. It is not a value type and instead models a +// control flow construct. Check out `defer` in Golang for something similar. + +#ifndef ABSL_CLEANUP_CLEANUP_H_ +#define ABSL_CLEANUP_CLEANUP_H_ + +#include <utility> + +#include "absl/base/config.h" +#include "absl/base/macros.h" +#include "absl/cleanup/internal/cleanup.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +template <typename Arg, typename Callback = void()> +class ABSL_MUST_USE_RESULT Cleanup { + static_assert(cleanup_internal::WasDeduced<Arg>(), + "Explicit template parameters are not supported."); + + static_assert(cleanup_internal::ReturnsVoid<Callback>(), + "Callbacks that return values are not supported."); + + public: + Cleanup(Callback callback) // NOLINT + : storage_(std::move(callback), /*engaged=*/true) {} + + Cleanup(Cleanup&& other) = default; + + void Cancel() && { + ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); + storage_.DisengageCallback(); + } + + void Invoke() && { + ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); + storage_.DisengageCallback(); + storage_.InvokeCallback(); + } + + ~Cleanup() { + if (storage_.IsCallbackEngaged()) { + storage_.InvokeCallback(); + } + } + + private: + cleanup_internal::Storage<Callback> storage_; +}; + +// `absl::Cleanup c = /* callback */;` +// +// C++17 type deduction API for creating an instance of `absl::Cleanup` +#if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) +template <typename Callback> +Cleanup(Callback callback) -> Cleanup<cleanup_internal::Tag, Callback>; +#endif // defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) + +// `auto c = absl::MakeCleanup(/* callback */);` +// +// C++11 type deduction API for creating an instance of `absl::Cleanup` +template <typename... Args, typename Callback> +absl::Cleanup<cleanup_internal::Tag, Callback> MakeCleanup(Callback callback) { + static_assert(cleanup_internal::WasDeduced<cleanup_internal::Tag, Args...>(), + "Explicit template parameters are not supported."); + + static_assert(cleanup_internal::ReturnsVoid<Callback>(), + "Callbacks that return values are not supported."); + + return {std::move(callback)}; +} + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_CLEANUP_CLEANUP_H_
diff --git a/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc b/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc new file mode 100644 index 0000000..792595d6 --- /dev/null +++ b/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc
@@ -0,0 +1,267 @@ +// Copyright 2021 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/cleanup/cleanup.h" + +#include <functional> +#include <type_traits> +#include <utility> + +#include "gtest/gtest.h" +#include "absl/base/config.h" +#include "absl/utility/utility.h" + +namespace { + +using Tag = absl::cleanup_internal::Tag; + +template <typename Type1, typename Type2> +constexpr bool IsSame() { + return (std::is_same<Type1, Type2>::value); +} + +struct IdentityFactory { + template <typename Callback> + static Callback AsCallback(Callback callback) { + return Callback(std::move(callback)); + } +}; + +// `FunctorClass` is a type used for testing `absl::Cleanup`. It is intended to +// represent users that make their own move-only callback types outside of +// `std::function` and lambda literals. +class FunctorClass { + using Callback = std::function<void()>; + + public: + explicit FunctorClass(Callback callback) : callback_(std::move(callback)) {} + + FunctorClass(FunctorClass&& other) + : callback_(absl::exchange(other.callback_, Callback())) {} + + FunctorClass(const FunctorClass&) = delete; + + FunctorClass& operator=(const FunctorClass&) = delete; + + FunctorClass& operator=(FunctorClass&&) = delete; + + void operator()() const& = delete; + + void operator()() && { + ASSERT_TRUE(callback_); + callback_(); + callback_ = nullptr; + } + + private: + Callback callback_; +}; + +struct FunctorClassFactory { + template <typename Callback> + static FunctorClass AsCallback(Callback callback) { + return FunctorClass(std::move(callback)); + } +}; + +struct StdFunctionFactory { + template <typename Callback> + static std::function<void()> AsCallback(Callback callback) { + return std::function<void()>(std::move(callback)); + } +}; + +using CleanupTestParams = + ::testing::Types<IdentityFactory, FunctorClassFactory, StdFunctionFactory>; +template <typename> +struct CleanupTest : public ::testing::Test {}; +TYPED_TEST_SUITE(CleanupTest, CleanupTestParams); + +bool fn_ptr_called = false; +void FnPtrFunction() { fn_ptr_called = true; } + +TYPED_TEST(CleanupTest, FactoryProducesCorrectType) { + { + auto callback = TypeParam::AsCallback([] {}); + auto cleanup = absl::MakeCleanup(std::move(callback)); + + static_assert( + IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(), + ""); + } + + { + auto cleanup = absl::MakeCleanup(&FnPtrFunction); + + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), + ""); + } + + { + auto cleanup = absl::MakeCleanup(FnPtrFunction); + + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), + ""); + } +} + +#if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) +TYPED_TEST(CleanupTest, CTADProducesCorrectType) { + { + auto callback = TypeParam::AsCallback([] {}); + absl::Cleanup cleanup = std::move(callback); + + static_assert( + IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(), + ""); + } + + { + absl::Cleanup cleanup = &FnPtrFunction; + + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), + ""); + } + + { + absl::Cleanup cleanup = FnPtrFunction; + + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), + ""); + } +} + +TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) { + { + auto callback = IdentityFactory::AsCallback([] {}); + auto factory_cleanup = absl::MakeCleanup(callback); + absl::Cleanup deduction_cleanup = callback; + + static_assert( + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + } + + { + auto factory_cleanup = + absl::MakeCleanup(FunctorClassFactory::AsCallback([] {})); + absl::Cleanup deduction_cleanup = FunctorClassFactory::AsCallback([] {}); + + static_assert( + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + } + + { + auto factory_cleanup = + absl::MakeCleanup(StdFunctionFactory::AsCallback([] {})); + absl::Cleanup deduction_cleanup = StdFunctionFactory::AsCallback([] {}); + + static_assert( + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + } + + { + auto factory_cleanup = absl::MakeCleanup(&FnPtrFunction); + absl::Cleanup deduction_cleanup = &FnPtrFunction; + + static_assert( + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + } + + { + auto factory_cleanup = absl::MakeCleanup(FnPtrFunction); + absl::Cleanup deduction_cleanup = FnPtrFunction; + + static_assert( + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + } +} +#endif // defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) + +TYPED_TEST(CleanupTest, BasicUsage) { + bool called = false; + + { + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + EXPECT_FALSE(called); // Constructor shouldn't invoke the callback + } + + EXPECT_TRUE(called); // Destructor should invoke the callback +} + +TYPED_TEST(CleanupTest, BasicUsageWithFunctionPointer) { + fn_ptr_called = false; + + { + auto cleanup = absl::MakeCleanup(TypeParam::AsCallback(&FnPtrFunction)); + EXPECT_FALSE(fn_ptr_called); // Constructor shouldn't invoke the callback + } + + EXPECT_TRUE(fn_ptr_called); // Destructor should invoke the callback +} + +TYPED_TEST(CleanupTest, Cancel) { + bool called = false; + + { + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + EXPECT_FALSE(called); // Constructor shouldn't invoke the callback + + std::move(cleanup).Cancel(); + EXPECT_FALSE(called); // Cancel shouldn't invoke the callback + } + + EXPECT_FALSE(called); // Destructor shouldn't invoke the callback +} + +TYPED_TEST(CleanupTest, Invoke) { + bool called = false; + + { + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + EXPECT_FALSE(called); // Constructor shouldn't invoke the callback + + std::move(cleanup).Invoke(); + EXPECT_TRUE(called); // Invoke should invoke the callback + + called = false; // Reset tracker before destructor runs + } + + EXPECT_FALSE(called); // Destructor shouldn't invoke the callback +} + +TYPED_TEST(CleanupTest, Move) { + bool called = false; + + { + auto moved_from_cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + EXPECT_FALSE(called); // Constructor shouldn't invoke the callback + + { + auto moved_to_cleanup = std::move(moved_from_cleanup); + EXPECT_FALSE(called); // Move shouldn't invoke the callback + } + + EXPECT_TRUE(called); // Destructor should invoke the callback + + called = false; // Reset tracker before destructor runs + } + + EXPECT_FALSE(called); // Destructor shouldn't invoke the callback +} + +} // namespace
diff --git a/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h b/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h new file mode 100644 index 0000000..b68e3dd --- /dev/null +++ b/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h
@@ -0,0 +1,79 @@ +// Copyright 2021 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_CLEANUP_INTERNAL_CLEANUP_H_ +#define ABSL_CLEANUP_INTERNAL_CLEANUP_H_ + +#include <type_traits> +#include <utility> + +#include "absl/base/internal/invoke.h" +#include "absl/base/thread_annotations.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +namespace cleanup_internal { + +struct Tag {}; + +template <typename Arg, typename... Args> +constexpr bool WasDeduced() { + return (std::is_same<cleanup_internal::Tag, Arg>::value) && + (sizeof...(Args) == 0); +} + +template <typename Callback> +constexpr bool ReturnsVoid() { + return (std::is_same<base_internal::invoke_result_t<Callback>, void>::value); +} + +template <typename Callback> +class Storage { + public: + Storage() = delete; + + Storage(Callback callback, bool engaged) + : callback_(std::move(callback)), engaged_(engaged) {} + + Storage(Storage&& other) + : callback_(std::move(other.callback_)), + engaged_(absl::exchange(other.engaged_, false)) {} + + Storage(const Storage& other) = delete; + + Storage& operator=(Storage&& other) = delete; + + Storage& operator=(const Storage& other) = delete; + + bool IsCallbackEngaged() const { return engaged_; } + + void DisengageCallback() { engaged_ = false; } + + void InvokeCallback() ABSL_NO_THREAD_SAFETY_ANALYSIS { + std::move(callback_)(); + } + + private: + Callback callback_; + bool engaged_; +}; + +} // namespace cleanup_internal + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_CLEANUP_INTERNAL_CLEANUP_H_
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector.h b/third_party/abseil-cpp/absl/container/inlined_vector.h index 90bb96e8..7c18234 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector.h +++ b/third_party/abseil-cpp/absl/container/inlined_vector.h
@@ -167,11 +167,13 @@ // Creates an inlined vector by copying the contents of `other` using `alloc`. InlinedVector(const InlinedVector& other, const allocator_type& alloc) : storage_(alloc) { - if (IsMemcpyOk::value && !other.storage_.GetIsAllocated()) { + if (other.empty()) { + // Empty; nothing to do. + } else if (IsMemcpyOk::value && !other.storage_.GetIsAllocated()) { + // Memcpy-able and do not need allocation. storage_.MemcpyFrom(other.storage_); } else { - storage_.Initialize(IteratorValueAdapter<const_pointer>(other.data()), - other.size()); + storage_.InitFrom(other.storage_); } }
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc index b8dafe9..e256fad6 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc +++ b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc
@@ -534,6 +534,28 @@ ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromMove, TrivialType); ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromMove, NontrivialType); +// Measure cost of copy-constructor+destructor. +void BM_CopyTrivial(benchmark::State& state) { + const int n = state.range(0); + InlVec<int64_t> src(n); + for (auto s : state) { + InlVec<int64_t> copy(src); + benchmark::DoNotOptimize(copy); + } +} +BENCHMARK(BM_CopyTrivial)->Arg(0)->Arg(1)->Arg(kLargeSize); + +// Measure cost of copy-constructor+destructor. +void BM_CopyNonTrivial(benchmark::State& state) { + const int n = state.range(0); + InlVec<InlVec<int64_t>> src(n); + for (auto s : state) { + InlVec<InlVec<int64_t>> copy(src); + benchmark::DoNotOptimize(copy); + } +} +BENCHMARK(BM_CopyNonTrivial)->Arg(0)->Arg(1)->Arg(kLargeSize); + template <typename T, size_t FromSize, size_t ToSize> void BM_AssignSizeRef(benchmark::State& state) { auto size = ToSize;
diff --git a/third_party/abseil-cpp/absl/container/internal/inlined_vector.h b/third_party/abseil-cpp/absl/container/internal/inlined_vector.h index 120849cd..b8aec45 100644 --- a/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +++ b/third_party/abseil-cpp/absl/container/internal/inlined_vector.h
@@ -81,6 +81,23 @@ } } +// If kUseMemcpy is true, memcpy(dst, src, n); else do nothing. +// Useful to avoid compiler warnings when memcpy() is used for T values +// that are not trivially copyable in non-reachable code. +template <bool kUseMemcpy> +inline void MemcpyIfAllowed(void* dst, const void* src, size_t n); + +// memcpy when allowed. +template <> +inline void MemcpyIfAllowed<true>(void* dst, const void* src, size_t n) { + memcpy(dst, src, n); +} + +// Do nothing for types that are not memcpy-able. This function is only +// called from non-reachable branches. +template <> +inline void MemcpyIfAllowed<false>(void*, const void*, size_t) {} + template <typename AllocatorType, typename Pointer, typename ValueAdapter, typename SizeType> void ConstructElements(AllocatorType* alloc_ptr, Pointer construct_first, @@ -310,9 +327,14 @@ : metadata_(alloc, /* size and is_allocated */ 0) {} ~Storage() { - pointer data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); - inlined_vector_internal::DestroyElements(GetAllocPtr(), data, GetSize()); - DeallocateIfAllocated(); + if (GetSizeAndIsAllocated() == 0) { + // Empty and not allocated; nothing to do. + } else if (IsMemcpyOk::value) { + // No destructors need to be run; just deallocate if necessary. + DeallocateIfAllocated(); + } else { + DestroyContents(); + } } // --------------------------------------------------------------------------- @@ -370,6 +392,8 @@ // Storage Member Mutators // --------------------------------------------------------------------------- + ABSL_ATTRIBUTE_NOINLINE void InitFrom(const Storage& other); + template <typename ValueAdapter> void Initialize(ValueAdapter values, size_type new_size); @@ -452,6 +476,8 @@ } private: + ABSL_ATTRIBUTE_NOINLINE void DestroyContents(); + using Metadata = container_internal::CompressedTuple<allocator_type, size_type>; @@ -477,6 +503,40 @@ }; template <typename T, size_t N, typename A> +void Storage<T, N, A>::DestroyContents() { + pointer data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); + inlined_vector_internal::DestroyElements(GetAllocPtr(), data, GetSize()); + DeallocateIfAllocated(); +} + +template <typename T, size_t N, typename A> +void Storage<T, N, A>::InitFrom(const Storage& other) { + const auto n = other.GetSize(); + assert(n > 0); // Empty sources handled handled in caller. + const_pointer src; + pointer dst; + if (!other.GetIsAllocated()) { + dst = GetInlinedData(); + src = other.GetInlinedData(); + } else { + // Because this is only called from the `InlinedVector` constructors, it's + // safe to take on the allocation with size `0`. If `ConstructElements(...)` + // throws, deallocation will be automatically handled by `~Storage()`. + size_type new_capacity = ComputeCapacity(GetInlinedCapacity(), n); + dst = AllocatorTraits::allocate(*GetAllocPtr(), new_capacity); + SetAllocatedData(dst, new_capacity); + src = other.GetAllocatedData(); + } + if (IsMemcpyOk::value) { + MemcpyIfAllowed<IsMemcpyOk::value>(dst, src, sizeof(dst[0]) * n); + } else { + auto values = IteratorValueAdapter<const_pointer>(src); + inlined_vector_internal::ConstructElements(GetAllocPtr(), dst, &values, n); + } + GetSizeAndIsAllocated() = other.GetSizeAndIsAllocated(); +} + +template <typename T, size_t N, typename A> template <typename ValueAdapter> auto Storage<T, N, A>::Initialize(ValueAdapter values, size_type new_size) -> void {
diff --git a/third_party/abseil-cpp/absl/copts/AbseilConfigureCopts.cmake b/third_party/abseil-cpp/absl/copts/AbseilConfigureCopts.cmake index 90a1449d..9cd6fd1 100644 --- a/third_party/abseil-cpp/absl/copts/AbseilConfigureCopts.cmake +++ b/third_party/abseil-cpp/absl/copts/AbseilConfigureCopts.cmake
@@ -41,7 +41,6 @@ # clang-cl is half MSVC, half LLVM set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}") - set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") else() set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}")
diff --git a/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc b/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc index 6e5ff1f..57913025d 100644 --- a/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc +++ b/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc
@@ -66,6 +66,8 @@ #elif defined(__x86_64__) if (16 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs)) return reinterpret_cast<void*>(context->uc_mcontext.gregs[16]); +#elif defined(__e2k__) + return reinterpret_cast<void*>(context->uc_mcontext.cr0_hi); #else #error "Undefined Architecture." #endif
diff --git a/third_party/abseil-cpp/absl/hash/internal/wyhash_test.cc b/third_party/abseil-cpp/absl/hash/internal/wyhash_test.cc index 30dc9e3..9fb06d2 100644 --- a/third_party/abseil-cpp/absl/hash/internal/wyhash_test.cc +++ b/third_party/abseil-cpp/absl/hash/internal/wyhash_test.cc
@@ -1,14 +1,14 @@ // Copyright 2020 The Abseil Authors // // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in cokSaltliance with the License. +// you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or ikSaltlied. +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.
diff --git a/third_party/abseil-cpp/absl/status/status.cc b/third_party/abseil-cpp/absl/status/status.cc index c71de84..7962bb9 100644 --- a/third_party/abseil-cpp/absl/status/status.cc +++ b/third_party/abseil-cpp/absl/status/status.cc
@@ -207,10 +207,12 @@ } } -uintptr_t Status::NewRep(absl::StatusCode code, absl::string_view msg, - std::unique_ptr<status_internal::Payloads> payloads) { +uintptr_t Status::NewRep( + absl::StatusCode code, absl::string_view msg, + std::unique_ptr<status_internal::Payloads> payloads) { status_internal::StatusRep* rep = new status_internal::StatusRep( - code, std::string(msg.data(), msg.size()), std::move(payloads)); + code, std::string(msg.data(), msg.size()), + std::move(payloads)); return PointerToRep(rep); } @@ -236,8 +238,9 @@ void Status::PrepareToModify() { ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); if (IsInlined(rep_)) { - rep_ = NewRep(static_cast<absl::StatusCode>(raw_code()), - absl::string_view(), nullptr); + rep_ = + NewRep(static_cast<absl::StatusCode>(raw_code()), absl::string_view(), + nullptr); return; } @@ -248,7 +251,8 @@ if (rep->payloads) { payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads); } - rep_ = NewRep(rep->code, message(), std::move(payloads)); + rep_ = NewRep(rep->code, message(), + std::move(payloads)); UnrefNonInlined(rep_i); } }
diff --git a/third_party/abseil-cpp/absl/status/status.h b/third_party/abseil-cpp/absl/status/status.h index 08d3e80..118f64f 100644 --- a/third_party/abseil-cpp/absl/status/status.h +++ b/third_party/abseil-cpp/absl/status/status.h
@@ -371,10 +371,10 @@ Status(); // Creates a status in the canonical error space with the specified - // `absl::StatusCode` and error message. If `code == absl::StatusCode::kOk`, + // `absl::StatusCode` and error message. If `code == absl::StatusCode::kOk`, // NOLINT // `msg` is ignored and an object identical to an OK status is constructed. // - // The `msg` string must be in UTF-8. The implementation may complain (e.g., + // The `msg` string must be in UTF-8. The implementation may complain (e.g., // NOLINT // by printing a warning) if it is not. Status(absl::StatusCode code, absl::string_view msg); @@ -551,8 +551,9 @@ status_internal::Payloads* GetPayloads(); // Takes ownership of payload. - static uintptr_t NewRep(absl::StatusCode code, absl::string_view msg, - std::unique_ptr<status_internal::Payloads> payload); + static uintptr_t NewRep( + absl::StatusCode code, absl::string_view msg, + std::unique_ptr<status_internal::Payloads> payload); static bool EqualsSlow(const absl::Status& a, const absl::Status& b); // MSVC 14.0 limitation requires the const.
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.bazel b/third_party/abseil-cpp/absl/strings/BUILD.bazel index 794cf43..5efaf89 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.bazel +++ b/third_party/abseil-cpp/absl/strings/BUILD.bazel
@@ -286,6 +286,7 @@ "//absl/base:base_internal", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:endian", "//absl/base:raw_logging_internal", "//absl/base:throw_delegate", "//absl/container:compressed_tuple",
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.gn b/third_party/abseil-cpp/absl/strings/BUILD.gn index 10b393c..d9d2769b 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.gn +++ b/third_party/abseil-cpp/absl/strings/BUILD.gn
@@ -133,6 +133,7 @@ "//third_party/abseil-cpp/absl/base:base_internal", "//third_party/abseil-cpp/absl/base:config", "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/base:endian", "//third_party/abseil-cpp/absl/base:raw_logging_internal", "//third_party/abseil-cpp/absl/base:throw_delegate", "//third_party/abseil-cpp/absl/container:compressed_tuple",
diff --git a/third_party/abseil-cpp/absl/strings/cord.cc b/third_party/abseil-cpp/absl/strings/cord.cc index df8c26d..39191ef5 100644 --- a/third_party/abseil-cpp/absl/strings/cord.cc +++ b/third_party/abseil-cpp/absl/strings/cord.cc
@@ -37,6 +37,7 @@ #include "absl/strings/escaping.h" #include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_rep_flat.h" +#include "absl/strings/internal/cord_rep_ring.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -50,8 +51,8 @@ using ::absl::cord_internal::CordRepConcat; using ::absl::cord_internal::CordRepExternal; using ::absl::cord_internal::CordRepFlat; +using ::absl::cord_internal::CordRepRing; using ::absl::cord_internal::CordRepSubstring; - using ::absl::cord_internal::kMinFlatLength; using ::absl::cord_internal::kMaxFlatLength; @@ -94,6 +95,11 @@ static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); +static inline bool cord_ring_enabled() { + return cord_internal::cord_ring_buffer_enabled.load( + std::memory_order_relaxed); +} + static inline bool IsRootBalanced(CordRep* node) { if (node->tag != CONCAT) { return true; @@ -109,7 +115,8 @@ } static CordRep* Rebalance(CordRep* node); -static void DumpNode(CordRep* rep, bool include_data, std::ostream* os); +static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, + int indent = 0); static bool VerifyNode(CordRep* root, CordRep* start_node, bool full_validation); @@ -198,12 +205,38 @@ return reps[0]; } +static CordRepFlat* CreateFlat(const char* data, size_t length, + size_t alloc_hint) { + CordRepFlat* flat = CordRepFlat::New(length + alloc_hint); + flat->length = length; + memcpy(flat->Data(), data, length); + return flat; +} + +// Creates a new flat or ringbuffer out of the specified array. +// The returned node has a refcount of 1. +static CordRep* RingNewTree(const char* data, size_t length, + size_t alloc_hint) { + if (length <= kMaxFlatLength) { + return CreateFlat(data, length, alloc_hint); + } + CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0); + data += kMaxFlatLength; + length -= kMaxFlatLength; + size_t extra = (length - 1) / kMaxFlatLength + 1; + auto* root = CordRepRing::Create(flat, extra); + return CordRepRing::Append(root, {data, length}, alloc_hint); +} + // Create a new tree out of the specified array. // The returned node has a refcount of 1. static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { if (length == 0) return nullptr; + if (cord_ring_enabled()) { + return RingNewTree(data, length, alloc_hint); + } absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); size_t n = 0; do { @@ -295,10 +328,18 @@ reduce_size(n); } +// Returns `rep` converted into a CordRepRing. +// Directly returns `rep` if `rep` is already a CordRepRing. +static CordRepRing* ForceRing(CordRep* rep, size_t extra) { + return (rep->tag == RING) ? rep->ring() : CordRepRing::Create(rep, extra); +} + void Cord::InlineRep::AppendTree(CordRep* tree) { if (tree == nullptr) return; if (data_.is_empty()) { set_tree(tree); + } else if (cord_ring_enabled()) { + set_tree(CordRepRing::Append(ForceRing(force_tree(0), 1), tree)); } else { set_tree(Concat(force_tree(0), tree)); } @@ -308,6 +349,8 @@ assert(tree != nullptr); if (data_.is_empty()) { set_tree(tree); + } else if (cord_ring_enabled()) { + set_tree(CordRepRing::Prepend(ForceRing(force_tree(0), 1), tree)); } else { set_tree(Concat(tree, force_tree(0))); } @@ -319,6 +362,15 @@ // written to region and the actual size increase will be written to size. static inline bool PrepareAppendRegion(CordRep* root, char** region, size_t* size, size_t max_length) { + if (root->tag == RING && root->refcount.IsOne()) { + Span<char> span = root->ring()->GetAppendBuffer(max_length); + if (!span.empty()) { + *region = span.data(); + *size = span.size(); + return true; + } + } + // Search down the right-hand path for a non-full FLAT node. CordRep* dst = root; while (dst->tag == CONCAT && dst->refcount.IsOne()) { @@ -383,6 +435,11 @@ new_node->length = std::min(new_node->Capacity(), max_length); *region = new_node->Data(); *size = new_node->length; + + if (cord_ring_enabled()) { + replace_tree(CordRepRing::Append(ForceRing(root, 1), new_node)); + return; + } replace_tree(Concat(root, new_node)); } @@ -411,6 +468,11 @@ new_node->length = new_node->Capacity(); *region = new_node->Data(); *size = new_node->length; + + if (cord_ring_enabled()) { + replace_tree(CordRepRing::Append(ForceRing(root, 1), new_node)); + return; + } replace_tree(Concat(root, new_node)); } @@ -593,6 +655,13 @@ return; } + if (cord_ring_enabled()) { + absl::string_view data(src_data, src_size); + root = ForceRing(root, (data.size() - 1) / kMaxFlatLength + 1); + replace_tree(CordRepRing::Append(root->ring(), data)); + return; + } + // Use new block(s) for any remaining bytes that were not handled above. // Alloc extra memory only if the right child of the root of the new tree is // going to be a FLAT node, which will permit further inplace appends. @@ -805,6 +874,8 @@ CordRep* tree = contents_.tree(); if (tree == nullptr) { contents_.remove_prefix(n); + } else if (tree->tag == RING) { + contents_.replace_tree(CordRepRing::RemovePrefix(tree->ring(), n)); } else { CordRep* newrep = RemovePrefixFrom(tree, n); CordRep::Unref(tree); @@ -819,6 +890,8 @@ CordRep* tree = contents_.tree(); if (tree == nullptr) { contents_.reduce_size(n); + } else if (tree->tag == RING) { + contents_.replace_tree(CordRepRing::RemoveSuffix(tree->ring(), n)); } else { CordRep* newrep = RemoveSuffixFrom(tree, n); CordRep::Unref(tree); @@ -902,6 +975,9 @@ } cord_internal::SmallMemmove(dest, it->data(), remaining_size); sub_cord.contents_.set_inline_size(new_size); + } else if (tree->tag == RING) { + tree = CordRepRing::SubRing(CordRep::Ref(tree)->ring(), pos, new_size); + sub_cord.contents_.set_tree(tree); } else { sub_cord.contents_.set_tree(NewSubRange(tree, pos, new_size)); } @@ -1103,6 +1179,10 @@ return absl::string_view(node->external()->base, node->length); } + if (node->tag == RING) { + return node->ring()->entry_data(node->ring()->head()); + } + // Walk down the left branches until we hit a non-CONCAT node. while (node->tag == CONCAT) { node = node->concat()->left; @@ -1360,6 +1440,25 @@ } return subcord; } + + if (ring_reader_) { + size_t chunk_size = current_chunk_.size(); + if (n <= chunk_size && n <= kMaxBytesToCopy) { + subcord = Cord(current_chunk_.substr(0, n)); + } else { + auto* ring = CordRep::Ref(ring_reader_.ring())->ring(); + size_t offset = ring_reader_.length() - bytes_remaining_; + subcord.contents_.set_tree(CordRepRing::SubRing(ring, offset, n)); + } + if (n < chunk_size) { + bytes_remaining_ -= n; + current_chunk_.remove_prefix(n); + } else { + AdvanceBytesRing(n); + } + return subcord; + } + auto& stack_of_right_children = stack_of_right_children_; if (n < current_chunk_.size()) { // Range to read is a proper subrange of the current chunk. @@ -1533,6 +1632,8 @@ if (rep->tag >= FLAT) { // Get the "i"th character directly from the flat array. return rep->flat()->Data()[offset]; + } else if (rep->tag == RING) { + return rep->ring()->GetCharacter(offset); } else if (rep->tag == EXTERNAL) { // Get the "i"th character from the external array. return rep->external()->base[offset]; @@ -1609,6 +1710,15 @@ /* static */ void Cord::ForEachChunkAux( absl::cord_internal::CordRep* rep, absl::FunctionRef<void(absl::string_view)> callback) { + if (rep->tag == RING) { + ChunkIterator it(rep), end; + while (it != end) { + callback(*it); + ++it; + } + return; + } + assert(rep != nullptr); int stack_pos = 0; constexpr int stack_max = 128; @@ -1650,9 +1760,9 @@ } } -static void DumpNode(CordRep* rep, bool include_data, std::ostream* os) { +static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, + int indent) { const int kIndentStep = 1; - int indent = 0; absl::InlinedVector<CordRep*, kInlinedVectorSize> stack; absl::InlinedVector<int, kInlinedVectorSize> indents; for (;;) { @@ -1673,18 +1783,28 @@ *os << "SUBSTRING @ " << rep->substring()->start << "\n"; indent += kIndentStep; rep = rep->substring()->child; - } else { // Leaf + } else { // Leaf or ring if (rep->tag == EXTERNAL) { *os << "EXTERNAL ["; if (include_data) *os << absl::CEscape(std::string(rep->external()->base, rep->length)); *os << "]\n"; - } else { + } else if (rep->tag >= FLAT) { *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; if (include_data) *os << absl::CEscape(std::string(rep->flat()->Data(), rep->length)); *os << "]\n"; + } else { + assert(rep->tag == RING); + auto* ring = rep->ring(); + *os << "RING, entries = " << ring->entries() << "\n"; + CordRepRing::index_type head = ring->head(); + do { + DumpNode(ring->entry_child(head), include_data, os, + indent + kIndentStep); + head = ring->advance(head);; + } while (head != ring->tail()); } if (stack.empty()) break; rep = stack.back(); @@ -1778,6 +1898,15 @@ } next_node = right; } + } else if (cur_node->tag == RING) { + total_mem_usage += CordRepRing::AllocSize(cur_node->ring()->capacity()); + const CordRepRing* ring = cur_node->ring(); + CordRepRing::index_type pos = ring->head(), tail = ring->tail(); + do { + CordRep* node = ring->entry_child(pos); + assert(node->tag >= FLAT || node->tag == EXTERNAL); + RepMemoryUsageLeaf(node, &total_mem_usage); + } while ((pos = ring->advance(pos)) != tail); } else { // Since cur_node is not a leaf or a concat node it must be a substring. assert(cur_node->tag == SUBSTRING);
diff --git a/third_party/abseil-cpp/absl/strings/cord.h b/third_party/abseil-cpp/absl/strings/cord.h index abef98f..aefb5e5 100644 --- a/third_party/abseil-cpp/absl/strings/cord.h +++ b/third_party/abseil-cpp/absl/strings/cord.h
@@ -78,6 +78,8 @@ #include "absl/functional/function_ref.h" #include "absl/meta/type_traits.h" #include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_ring.h" +#include "absl/strings/internal/cord_rep_ring_reader.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/string_constant.h" #include "absl/strings/string_view.h" @@ -287,7 +289,7 @@ bool StartsWith(const Cord& rhs) const; bool StartsWith(absl::string_view rhs) const; - // Cord::EndsWidth() + // Cord::EndsWith() // // Determines whether the Cord ends with the passed string data `rhs`. bool EndsWith(absl::string_view rhs) const; @@ -361,6 +363,10 @@ friend class CharIterator; private: + using CordRep = absl::cord_internal::CordRep; + using CordRepRing = absl::cord_internal::CordRepRing; + using CordRepRingReader = absl::cord_internal::CordRepRingReader; + // Stack of right children of concat nodes that we have to visit. // Keep this at the end of the structure to avoid cache-thrashing. // TODO(jgm): Benchmark to see if there's a more optimal value than 47 for @@ -385,6 +391,10 @@ // Stack specific operator++ ChunkIterator& AdvanceStack(); + // Ring buffer specific operator++ + ChunkIterator& AdvanceRing(); + void AdvanceBytesRing(size_t n); + // Iterates `n` bytes, where `n` is expected to be greater than or equal to // `current_chunk_.size()`. void AdvanceBytesSlowPath(size_t n); @@ -398,6 +408,10 @@ absl::cord_internal::CordRep* current_leaf_ = nullptr; // The number of bytes left in the `Cord` over which we are iterating. size_t bytes_remaining_ = 0; + + // Cord reader for ring buffers. Empty if not traversing a ring buffer. + CordRepRingReader ring_reader_; + // See 'Stack' alias definition. Stack stack_of_right_children_; }; @@ -1107,6 +1121,11 @@ } inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) { + if (tree->tag == cord_internal::RING) { + current_chunk_ = ring_reader_.Reset(tree->ring()); + return; + } + stack_of_right_children_.push_back(tree); operator++(); } @@ -1126,13 +1145,33 @@ } } +inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceRing() { + current_chunk_ = ring_reader_.Next(); + return *this; +} + +inline void Cord::ChunkIterator::AdvanceBytesRing(size_t n) { + assert(n >= current_chunk_.size()); + bytes_remaining_ -= n; + if (bytes_remaining_) { + if (n == current_chunk_.size()) { + current_chunk_ = ring_reader_.Next(); + } else { + size_t offset = ring_reader_.length() - bytes_remaining_; + current_chunk_ = ring_reader_.Seek(offset); + } + } else { + current_chunk_ = {}; + } +} + inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() { ABSL_HARDENING_ASSERT(bytes_remaining_ > 0 && "Attempted to iterate past `end()`"); assert(bytes_remaining_ >= current_chunk_.size()); bytes_remaining_ -= current_chunk_.size(); if (bytes_remaining_ > 0) { - return AdvanceStack(); + return ring_reader_ ? AdvanceRing() : AdvanceStack(); } else { current_chunk_ = {}; } @@ -1174,7 +1213,7 @@ if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { RemoveChunkPrefix(n); } else if (n != 0) { - AdvanceBytesSlowPath(n); + ring_reader_ ? AdvanceBytesRing(n) : AdvanceBytesSlowPath(n); } }
diff --git a/third_party/abseil-cpp/absl/strings/cord_test.cc b/third_party/abseil-cpp/absl/strings/cord_test.cc index 7942bfc..bf7a6820 100644 --- a/third_party/abseil-cpp/absl/strings/cord_test.cc +++ b/third_party/abseil-cpp/absl/strings/cord_test.cc
@@ -367,7 +367,7 @@ for (size_t end_pos : positions) { if (end_pos < pos || end_pos > a.size()) continue; absl::Cord sa = a.Subcord(pos, end_pos - pos); - EXPECT_EQ(absl::string_view(s).substr(pos, end_pos - pos), + ASSERT_EQ(absl::string_view(s).substr(pos, end_pos - pos), std::string(sa)) << a; } @@ -379,7 +379,7 @@ for (size_t pos = 0; pos <= sh.size(); ++pos) { for (size_t n = 0; n <= sh.size() - pos; ++n) { absl::Cord sc = c.Subcord(pos, n); - EXPECT_EQ(sh.substr(pos, n), std::string(sc)) << c; + ASSERT_EQ(sh.substr(pos, n), std::string(sc)) << c; } } @@ -389,7 +389,7 @@ while (sa.size() > 1) { sa = sa.Subcord(1, sa.size() - 2); ss = ss.substr(1, ss.size() - 2); - EXPECT_EQ(ss, std::string(sa)) << a; + ASSERT_EQ(ss, std::string(sa)) << a; if (HasFailure()) break; // halt cascade }
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_internal.h b/third_party/abseil-cpp/absl/strings/internal/cord_internal.h index 96502433..cda00a4 100644 --- a/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +++ b/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
@@ -22,6 +22,7 @@ #include <type_traits> #include "absl/base/config.h" +#include "absl/base/internal/endian.h" #include "absl/base/internal/invoke.h" #include "absl/base/optimization.h" #include "absl/container/internal/compressed_tuple.h" @@ -32,6 +33,8 @@ ABSL_NAMESPACE_BEGIN namespace cord_internal { +class CordzInfo; + // Default feature enable states for cord ring buffers enum CordFeatureDefaults { kCordEnableRingBufferDefault = false, @@ -193,26 +196,7 @@ // -------------------------------------------------------------------- // Memory management - // This internal routine is called from the cold path of Unref below. Keeping - // it in a separate routine allows good inlining of Unref into many profitable - // call sites. However, the call to this function can be highly disruptive to - // the register pressure in those callers. To minimize the cost to callers, we - // use a special LLVM calling convention that preserves most registers. This - // allows the call to this routine in cold paths to not disrupt the caller's - // register pressure. This calling convention is not available on all - // platforms; we intentionally allow LLVM to ignore the attribute rather than - // attempting to hardcode the list of supported platforms. -#if defined(__clang__) && !defined(__i386__) -#if !(defined(ABSL_HAVE_MEMORY_SANITIZER) || \ - defined(ABSL_HAVE_THREAD_SANITIZER) || \ - defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ - defined(UNDEFINED_BEHAVIOR_SANITIZER)) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wattributes" - __attribute__((preserve_most)) -#pragma clang diagnostic pop -#endif // *_SANITIZER -#endif + // Destroys the provided `rep`. static void Destroy(CordRep* rep); // Increments the reference count of `rep`. @@ -383,6 +367,26 @@ return as_tree_.cordz_info != kNullCordzInfo; } + // Returns the cordz_info sampling instance for this instance, or nullptr + // if the current instance is not sampled and does not have CordzInfo data. + // Requires the current instance to hold a tree value. + CordzInfo* cordz_info() const { + assert(is_tree()); + intptr_t info = + static_cast<intptr_t>(absl::big_endian::ToHost64(as_tree_.cordz_info)); + assert(info & 1); + return reinterpret_cast<CordzInfo*>(info - 1); + } + + // Sets the current cordz_info sampling instance for this instance, or nullptr + // if the current instance is not sampled and does not have CordzInfo data. + // Requires the current instance to hold a tree value. + void set_cordz_info(CordzInfo* cordz_info) { + assert(is_tree()); + intptr_t info = reinterpret_cast<intptr_t>(cordz_info) | 1; + as_tree_.cordz_info = absl::big_endian::FromHost64(info); + } + // Returns a read only pointer to the character data inside this instance. // Requires the current instance to hold inline data. const char* as_chars() const {
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h b/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h index 55418153..a98aa9d 100644 --- a/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h +++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
@@ -43,8 +43,9 @@ static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead; static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead; -constexpr size_t AllocatedSizeToTagUnchecked(size_t size) { - return (size <= 1024) ? size / 8 : 128 + size / 32 - 1024 / 32; +constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) { + return static_cast<uint8_t>((size <= 1024) ? size / 8 + : 128 + size / 32 - 1024 / 32); } static_assert(kMinFlatSize / 8 >= FLAT, ""); @@ -65,7 +66,7 @@ // undefined if the size exceeds the maximum size that can be encoded in // a tag, i.e., if size is larger than TagToAllocatedSize(<max tag>). inline uint8_t AllocatedSizeToTag(size_t size) { - const size_t tag = AllocatedSizeToTagUnchecked(size); + const uint8_t tag = AllocatedSizeToTagUnchecked(size); assert(tag <= MAX_FLAT_TAG); return tag; }
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.h b/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.h index 268f4e4..c74d335 100644 --- a/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.h +++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.h
@@ -83,7 +83,7 @@ // `end_pos` which is the `end_pos` of the previous node (or `begin_pos`) plus // this node's length. The purpose is to allow for a binary search on this // position, while allowing O(1) prepend and append operations. - using pos_type = uint64_t; + using pos_type = size_t; // `index_type` is the type for the `head`, `tail` and `capacity` indexes. // Ring buffers are limited to having no more than four billion entries.
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version b/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version index a481df8..1d59095 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version +++ b/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version
@@ -1 +1 @@ -2020f +2021a
diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba b/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba index 36b05220..0aba9ff 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba +++ b/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba Binary files differ
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def index 44417c1..be9681d 100644 --- a/third_party/abseil-cpp/symbols_arm64_dbg.def +++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -46,6 +46,7 @@ ??$?0AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@?$__compressed_pair@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@Z ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@X@?$__compressed_pair_elem@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@$0A@$0A@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@@Z + ??$?0AEAPEAUCordRep@cord_internal@absl@@AEAPEAU012@$0A@@?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@__1@std@@QEAA@AEAPEAUCordRep@cord_internal@absl@@0@Z ??$?0AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@?$__compressed_pair@PEAUThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z ??$?0AEAPEAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PEAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@@Z ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z @@ -216,6 +217,8 @@ ??$?RW4LogSeverity@absl@@AEBQEBDHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$?RW4LogSeverity@absl@@AEBQEBDHV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAH$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$?XH@Duration@absl@@QEAAAEAV01@H@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z @@ -308,11 +311,21 @@ ??$FastIntToBuffer@G@numbers_internal@absl@@YAPEADGPEAD@Z ??$FastIntToBuffer@J@numbers_internal@absl@@YAPEADJPEAD@Z ??$FastIntToBuffer@K@numbers_internal@absl@@YAPEADKPEAD@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$FindBinary@$00@CordRepRing@cord_internal@absl@@AEBAIII_K@Z + ??$FindBinary@$0A@@CordRepRing@cord_internal@absl@@AEBAIII_K@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@AEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$00@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z ??$FormatConvertImpl@_N$0A@@str_format_internal@absl@@YA?AU?$ArgConvertResult@$0BPPPL@@01@_NVFormatConversionSpecImpl@01@PEAVFormatSinkImpl@01@@Z ??$FromChrono@_JV?$ratio@$00$0PECEA@@__1@std@@@time_internal@absl@@YA?AVDuration@1@AEBV?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@chrono@__1@std@@@Z ??$FromInt64@$00@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$00@__1@std@@@Z @@ -334,7 +347,6 @@ ??$HidePtr@X@base_internal@absl@@YA_KPEAX@Z ??$Init@H@FormatArgImpl@str_format_internal@absl@@AEAAXAEBH@Z ??$Initialize@V?$CopyValueAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$CopyValueAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@12@_K@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@12@_K@Z ??$Invoke@A6AXXZ$$V@Callable@base_internal@absl@@SAXA6AXXZ@Z ??$Invoke@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@3@@Callable@base_internal@absl@@SAX$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@2@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@2@@Z ??$InvokeFlush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@str_format_internal@absl@@YAXPEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@Vstring_view@1@@Z @@ -351,9 +363,31 @@ ??$MakeSpan@$SVFormatArgImpl@str_format_internal@absl@@@absl@@YA?AV?$Span@VFormatArgImpl@str_format_internal@absl@@@0@PEAVFormatArgImpl@str_format_internal@0@_K@Z ??$Milliseconds@N$0A@@absl@@YA?AVDuration@0@N@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPEAUCordRep@01@Vstring_view@1@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$01$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$01$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBA_KXZ ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z + ??$Partial@$$V@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@12@XZ + ??$Partial@AEAI@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@12@AEAI@Z + ??$Partial@AEAIAEAI@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@12@AEAI0@Z + ??$Partial@AEA_K@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@12@AEA_K@Z + ??$Partial@AEA_KAEA_K@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@12@AEA_K0@Z + ??$Partial@I@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@12@$$QEAI@Z + ??$Partial@II@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@12@$$QEAI0@Z + ??$Pointer@$00$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBAPEBQEAUCordRep@cord_internal@3@PEBD@Z + ??$Pointer@$00D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBAPEAPEAUCordRep@cord_internal@3@PEAD@Z + ??$Pointer@$01$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBAPEBIPEBD@Z + ??$Pointer@$01D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBAPEAIPEAD@Z + ??$Pointer@$0A@$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEB_KPEBD@Z + ??$Pointer@$0A@D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEA_KPEAD@Z ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$STLStringResizeUninitialized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z ??$SharedCompareImpl@VCord@absl@@@absl@@YAHAEBVCord@0@0@Z @@ -594,10 +628,12 @@ ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAAEAUSubRange@1@$$QEAU21@@Z ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z ??$forward@$$T@absl@@YA$$QEA$$TAEA$$T@Z + ??$forward@AEAI@absl@@YAAEAIAEAI@Z ??$forward@AEAPEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEAUCordRep@cord_internal@absl@@AEAPEAPEAU234@@Z ??$forward@AEAPEAPEBUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEBUCordRep@cord_internal@absl@@AEAPEAPEBU234@@Z ??$forward@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z ??$forward@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@YAAEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@01@AEAPEAU201@@Z + ??$forward@AEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAUCordRep@cord_internal@absl@@AEAPEAU234@@Z ??$forward@AEAPEAUPayload@status_internal@absl@@@__1@std@@YAAEAPEAUPayload@status_internal@absl@@AEAPEAU234@@Z ??$forward@AEAPEAUSubRange@absl@@@__1@std@@YAAEAPEAUSubRange@absl@@AEAPEAU23@@Z ??$forward@AEAPEAUThreadIdentity@base_internal@absl@@@__1@std@@YAAEAPEAUThreadIdentity@base_internal@absl@@AEAPEAU234@@Z @@ -633,6 +669,7 @@ ??$forward@AEBVCord@absl@@@absl@@YAAEBVCord@0@AEBV10@@Z ??$forward@AEBVstring_view@absl@@@__1@std@@YAAEBVstring_view@absl@@AEBV23@@Z ??$forward@H@absl@@YA$$QEAHAEAH@Z + ??$forward@I@absl@@YA$$QEAIAEAI@Z ??$forward@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@YA$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@01@AEAPEAPEAU201@@Z ??$forward@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z ??$forward@PEAUCordRep@cord_internal@absl@@@__1@std@@YA$$QEAPEAUCordRep@cord_internal@absl@@AEAPEAU234@@Z @@ -698,6 +735,7 @@ ??$invoke@A6AXXZ$$V@base_internal@absl@@YAXA6AXXZ@Z ??$invoke@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@3@@base_internal@absl@@YAX$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@1@@Z ??$lower_bound@PEBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@UByUnixTime@2345@@Z + ??$make_pair@AEAPEAUCordRep@cord_internal@absl@@AEAPEAU123@@__1@std@@YA?AU?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@01@AEAPEAUCordRep@cord_internal@absl@@0@Z ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AEAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z ??$min@VDuration@absl@@@__1@std@@YAAEBVDuration@absl@@AEBV23@0@Z @@ -769,8 +807,14 @@ ??0?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@QEAA@AEBQEBUPayload@status_internal@2@@Z ??0?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAUPayload@status_internal@absl@@@__1@std@@@Z ??0?$IteratorValueAdapter@V?$allocator@USubRange@absl@@@__1@std@@V?$move_iterator@PEAUSubRange@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAUSubRange@absl@@@__1@std@@@Z + ??0?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@QEAA@_K00@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEAA@_K00@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEAA@_K0@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEAA@_K@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEAA@XZ ??0?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@PEBVFormatArgImpl@str_format_internal@1@_K@Z ??0?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@XZ + ??0?$Span@D@absl@@QEAA@PEAD_K@Z ??0?$Span@I@absl@@QEAA@PEAI_K@Z ??0?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@PEAVFormatArgImpl@str_format_internal@1@_K@Z ??0?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAA@XZ @@ -918,6 +962,7 @@ ??0ByAnyChar@absl@@QEAA@Vstring_view@1@@Z ??0ByLength@absl@@QEAA@_J@Z ??0ByString@absl@@QEAA@Vstring_view@1@@Z + ??0ChunkIterator@Cord@absl@@AEAA@PEAUCordRep@cord_internal@2@@Z ??0ChunkIterator@Cord@absl@@AEAA@PEBV12@@Z ??0ChunkIterator@Cord@absl@@QEAA@XZ ??0ChunkRange@Cord@absl@@QEAA@PEBV12@@Z @@ -934,11 +979,14 @@ ??0CordRepConcat@cord_internal@absl@@QEAA@XZ ??0CordRepExternal@cord_internal@absl@@QEAA@XZ ??0CordRepFlat@cord_internal@absl@@QEAA@XZ + ??0CordRepRing@cord_internal@absl@@AEAA@I@Z + ??0CordRepRingReader@cord_internal@absl@@QEAA@XZ ??0CordRepSubstring@cord_internal@absl@@QEAA@XZ ??0Duration@absl@@AEAA@_JI@Z ??0Duration@absl@@QEAA@XZ ??0ErrnoSaver@base_internal@absl@@QEAA@XZ ??0FILERawSink@str_format_internal@absl@@QEAA@PEAU_iobuf@@@Z + ??0Filler@CordRepRing@cord_internal@absl@@QEAA@PEAV123@I@Z ??0FormatConversionSpecImpl@str_format_internal@absl@@QEAA@XZ ??0FormatSinkImpl@str_format_internal@absl@@QEAA@VFormatRawSinkImpl@12@@Z ??0GraphCycles@synchronization_internal@absl@@QEAA@XZ @@ -1148,6 +1196,7 @@ ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@Vuint128@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4LogSeverity@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV234@AEBVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -1203,6 +1252,7 @@ ??B?$unique_ptr@VTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ??B?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ??BCord@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ + ??BCordRepRingReader@cord_internal@absl@@QEBA_NXZ ??BTimeZone@absl@@QEBA?AVtime_zone@cctz@time_internal@1@XZ ??Bint128@absl@@QEBAEXZ ??Bint128@absl@@QEBANXZ @@ -1286,6 +1336,10 @@ ??Pabsl@@YA_NVDuration@0@0@Z ??Pabsl@@YA_NVint128@0@0@Z ??Pabsl@@YA_NVuint128@0@0@Z + ??R<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV123@II@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV123@II@Z@QEBA?A?<auto>@@I@Z ??R<lambda_1>@?0???A?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@_K@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0???A?$InlinedVector@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@_K@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0???A?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAAEAUPayload@status_internal@2@_K@Z@QEBA?A?<auto>@@XZ @@ -1314,8 +1368,11 @@ ??R<lambda_1>@?0??pop_back@?$InlinedVector@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAXXZ@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??pop_back@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAXXZ@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??remove_prefix@string_view@absl@@QEAAX_K@Z@QEBA?A?<auto>@@XZ + ??R<lambda_1>@?0??remove_suffix@string_view@absl@@QEAAX_K@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??replace_tree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@4@@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??set_inline_size@InlineData@cord_internal@absl@@QEAAX_K@Z@QEBA?A?<auto>@@XZ + ??R<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z ??R<lambda_2>@?0??erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@3@PEBU453@@Z@QEBA?A?<auto>@@XZ ??R?$FunctionRef@$$A6AXV?$Span@I@absl@@@Z@absl@@QEBAXV?$Span@I@1@@Z ??R?$FunctionRef@$$A6AXVstring_view@absl@@@Z@absl@@QEBAXVstring_view@1@@Z @@ -1385,6 +1442,8 @@ ?AcquireAllocatedData@?$Storage@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAV?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@23@@Z ?AcquireAllocatedData@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAV?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@23@@Z ?AcquireAllocatedData@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAV?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@23@@Z + ?Add@Filler@CordRepRing@cord_internal@absl@@QEAAXPEAUCordRep@34@_K1@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AEAAXI_K@Z ?AddNode@CordForest@absl@@AEAAXPEAUCordRep@cord_internal@2@@Z ?AddSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAX_K@Z ?AddSize@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAX_K@Z @@ -1399,9 +1458,14 @@ ?AddressIsReadable@debugging_internal@absl@@YA_NPEBX@Z ?AdvanceAndReadBytes@ChunkIterator@Cord@absl@@AEAA?AV23@_K@Z ?AdvanceBytes@ChunkIterator@Cord@absl@@AEAAX_K@Z + ?AdvanceBytesRing@ChunkIterator@Cord@absl@@AEAAX_K@Z ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AEAAX_K@Z + ?AdvanceRing@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ ?AdvanceStack@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ + ?Align@adl_barrier@internal_layout@container_internal@absl@@YA_K_K0@Z ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z + ?AllocSize@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ?AllocSize@CordRepRing@cord_internal@absl@@SA_K_K@Z ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z ?Allocate@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAPEAH_K@Z ?Allocate@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAPEAPEAUCordRep@cord_internal@3@_K@Z @@ -1410,20 +1474,24 @@ ?Allocate@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAPEAUSubRange@3@_K@Z ?AllocatedSize@CordRepFlat@cord_internal@absl@@QEBA_KXZ ?AllocatedSizeToTag@cord_internal@absl@@YAE_K@Z - ?AllocatedSizeToTagUnchecked@cord_internal@absl@@YA_K_K@Z + ?AllocatedSizeToTagUnchecked@cord_internal@absl@@YAE_K@Z ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?AnnotateConstruct@NonEmptyInlinedStorage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAX_K@Z ?AnnotateDestruct@NonEmptyInlinedStorage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAX_K@Z ?Append@Cord@absl@@QEAAX$$QEAV12@@Z ?Append@Cord@absl@@QEAAXAEBV12@@Z ?Append@Cord@absl@@QEAAXVstring_view@2@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QEAAXPEBD_K@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?AppendNode@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z ?AppendPack@str_format_internal@absl@@YAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?AppendText@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_KVstring_view@4@@Z ?AppendTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z @@ -1508,10 +1576,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@Vstring_view@4@@Z ?ConvertSpecialToEmptyAndFullToDeleted@GroupPortableImpl@container_internal@absl@@QEBAXPEAC@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@II_K@Z ?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z ?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPEAV123@PEAUCordRep@23@_K@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K11@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ ?Data@CordRepFlat@cord_internal@absl@@QEAAPEADXZ @@ -1534,13 +1606,16 @@ ?DefaultStackUnwinder@absl@@YAHPEAPEAXPEAHHHPEBX1@Z ?Delete@CordRepExternal@cord_internal@absl@@SAXPEAUCordRep@23@@Z ?Delete@CordRepFlat@cord_internal@absl@@SAXPEAUCordRep@23@@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPEAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPEBDPEADH@Z ?Description@Impl@time_zone@cctz@time_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ - ?Destroy@CordRep@cord_internal@absl@@SUXPEAU123@@Z + ?Destroy@CordRep@cord_internal@absl@@SAXPEAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAXXZ ?DestroyCordSlow@Cord@absl@@AEAAXXZ ?DidAllocate@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAA_NXZ ?DidAllocate@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAA_NXZ @@ -1550,6 +1625,7 @@ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ ?DisableRescheduling@SchedulingGuard@base_internal@absl@@CA_NXZ + ?Distance@CordRepRing@cord_internal@absl@@SA_K_K0@Z ?DivUp@cord_internal@absl@@YA_K_K0@Z ?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@Vstring_view@2@AEBVCord@2@@Z@base_internal@absl@@AEBAP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@3@Vstring_view@3@AEBVCord@3@@ZXZ ?DoLoad@?$AtomicHook@P6AXPEBDH000@Z@base_internal@absl@@AEBAP6AXPEBDH000@ZXZ @@ -1613,8 +1689,14 @@ ?Find@ByChar@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByLength@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByString@absl@@QEBA?AVstring_view@2@V32@_K@Z + ?Find@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@I_K@Z + ?Find@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@_K@Z ?FindFlatStartPiece@InlineRep@Cord@absl@@QEBA?AVstring_view@3@XZ ?FindPath@GraphCycles@synchronization_internal@absl@@QEBAHUGraphId@23@0HQEAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z + ?FindTail@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@I_K@Z + ?FindTail@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@_K@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -1708,6 +1790,7 @@ ?GetAllocator@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@XZ ?GetAllocator@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@XZ ?GetAllocator@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@USubRange@absl@@@__1@std@@XZ + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z ?GetCachedTID@base_internal@absl@@YAIXZ @@ -1716,6 +1799,7 @@ ?GetCapacity@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ ?GetCapacity@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ ?GetCapacity@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QEBAD_K@Z ?GetCond@WinHelper@Waiter@synchronization_internal@absl@@SAPEAU_RTL_CONDITION_VARIABLE@@PEAV234@@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetData@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAAEAPEAHXZ @@ -1746,12 +1830,15 @@ ?GetIsAllocated@?$Storage@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEBA_NXZ ?GetIsAllocated@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEBA_NXZ ?GetIsAllocated@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEBA_NXZ + ?GetLeafData@CordRepRing@cord_internal@absl@@SAPEBDPEBUCordRep@23@@Z ?GetLock@WinHelper@Waiter@synchronization_internal@absl@@SAPEAU_RTL_SRWLOCK@@PEAV234@@Z ?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z ?GetPayloads@Status@absl@@AEAAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@2@XZ ?GetPayloads@Status@absl@@AEBAPEBV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@2@XZ + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetProgramCounter@debugging_internal@absl@@YAPEAXPEAX@Z + ?GetRepData@CordRepRing@cord_internal@absl@@SAPEBDPEBUCordRep@23@@Z ?GetRepHi@time_internal@absl@@YA_JVDuration@2@@Z ?GetRepLo@time_internal@absl@@YAIVDuration@2@@Z ?GetSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEBA_KXZ @@ -1810,6 +1897,7 @@ ?InfiniteFuture@absl@@YA?AVTime@1@XZ ?InfinitePast@absl@@YA?AVTime@1@XZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AEAAXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PEAUCordRepExternal@12@@Z @@ -1851,7 +1939,9 @@ ?IsUnavailable@absl@@YA_NAEBVStatus@1@@Z ?IsUnimplemented@absl@@YA_NAEBVStatus@1@@Z ?IsUnknown@absl@@YA_NAEBVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QEBA_NAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?IsValidCapacity@container_internal@absl@@YA_N_K@Z + ?IsValidIndex@CordRepRing@cord_internal@absl@@AEBA_NI@Z ?Iterate@HashtablezSampler@container_internal@absl@@QEAA_JAEBV?$function@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAE_K@Z @@ -1915,14 +2005,17 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHPEBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AEAAXHPEBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@_K@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?Name@Impl@time_zone@cctz@time_internal@absl@@QEBAAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Nanoseconds@absl@@YA?AVDuration@1@_J@Z ?NegateAndSubtractOne@time_internal@absl@@YA_J_J@Z ?Never@KernelTimeout@synchronization_internal@absl@@SA?AV123@XZ ?New@CordRepFlat@cord_internal@absl@@SAPEAU123@_K@Z + ?New@CordRepRing@cord_internal@absl@@CAPEAV123@_K0@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@H@Z ?NewRep@Status@absl@@CA_KW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@XZ ?NextCapacity@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@SA_K_K@Z ?NextCapacity@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@SA_K_K@Z ?NextCapacity@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@SA_K_K@Z @@ -1976,7 +2069,11 @@ ?PrepareToModify@Status@absl@@AEAAXXZ ?Prepend@Cord@absl@@QEAAXAEBV12@@Z ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?PrependNode@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?PrevTransition@Impl@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@2345@@Z ?PrevTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z @@ -2025,13 +2122,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QEAAXPEAX@Z ?RemovePrefix@Cord@absl@@QEAAX_K@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RemoveSuffix@Cord@absl@@QEAAX_K@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RepToPointer@Status@absl@@CAPEAUStatusRep@status_internal@2@_K@Z ?Reset@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ + ?Reset@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@PEAVCordRepRing@23@@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResetToEmpty@InlineRep@Cord@absl@@AEAAXXZ ?Resize@?$ResizeUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z @@ -2042,12 +2142,14 @@ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z ?Seconds@absl@@YA?AVDuration@1@_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z ?SetAllocatedData@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAH_K@Z ?SetAllocatedData@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAPEAUCordRep@cord_internal@3@_K@Z ?SetAllocatedData@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAPEAUCordRep@cord_internal@3@_K@Z ?SetAllocatedData@?$Storage@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAPEBUCordRep@cord_internal@3@_K@Z ?SetAllocatedData@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAUPayload@status_internal@3@_K@Z ?SetAllocatedData@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAUSubRange@3@_K@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z ?SetConversionChar@FormatConversionSpecImplFriend@str_format_internal@absl@@SAXW4FormatConversionChar@3@PEAVFormatConversionSpecImpl@23@@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QEAAP6AXAEBUHashtablezInfo@23@@ZP6AX0@Z@Z @@ -2120,6 +2222,8 @@ ?StripLeadingAsciiWhitespace@absl@@YA?AVstring_view@1@V21@@Z ?StripTrailingAsciiWhitespace@absl@@YA?AVstring_view@1@V21@@Z ?StrlenInternal@string_view@absl@@CA_KPEBD@Z + ?SubLength@CordRepRing@cord_internal@absl@@AEAAXI_K@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K11@Z ?Subcord@Cord@absl@@QEBA?AV12@_K0@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PEBV62@_K@Z ?SubtractSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAX_K@Z @@ -2244,6 +2348,7 @@ ?UsingInlinedStorage@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@CA_N_K@Z ?Utf8SafeCEscape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@@Z ?Utf8SafeCHexEscape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@@Z + ?Validate@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEBDH@Z ?Value@?$Manager@C$01@FormatArgImpl@str_format_internal@absl@@SACTData@234@@Z ?Value@?$Manager@D$01@FormatArgImpl@str_format_internal@absl@@SADTData@234@@Z ?Value@?$Manager@E$01@FormatArgImpl@str_format_internal@absl@@SAETData@234@@Z @@ -2511,6 +2616,8 @@ ?__vallocate@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z ?__vdeallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ + ?advance@CordRepRing@cord_internal@absl@@QEBAII@Z + ?advance@CordRepRing@cord_internal@absl@@QEBAIII@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uday_tag@1234@U51234@@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uhour_tag@1234@U51234@@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uminute_tag@1234@U51234@@Z @@ -2615,6 +2722,7 @@ ?capacity@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ ?capacity@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ ?capacity@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ + ?capacity@CordRepRing@cord_internal@absl@@QEBAIXZ ?chunk_begin@Cord@absl@@QEBA?AVChunkIterator@12@XZ ?chunk_end@Cord@absl@@QEBA?AVChunkIterator@12@XZ ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ @@ -2637,6 +2745,7 @@ ?compare_exchange_weak@?$__atomic_base@PEAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QEAA_NAEAPEAUHashtablezInfo@container_internal@absl@@PEAU456@W4memory_order@23@2@Z ?concat@CordRep@cord_internal@absl@@QEAAPEAUCordRepConcat@23@XZ ?concat@CordRep@cord_internal@absl@@QEBAPEBUCordRepConcat@23@XZ + ?consumed@CordRepRingReader@cord_internal@absl@@QEBA_KXZ ?conversion_char@FormatConversionSpecImpl@str_format_internal@absl@@QEBA?AW4FormatConversionChar@3@XZ ?cord_ring_buffer_enabled@cord_internal@absl@@3U?$atomic@_N@__1@std@@A ?count@FILERawSink@str_format_internal@absl@@QEBA_KXZ @@ -2649,6 +2758,7 @@ ?data@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAPEBUPayload@status_internal@2@XZ ?data@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAPEAUSubRange@2@XZ ?data@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEBVFormatArgImpl@str_format_internal@2@XZ + ?data@?$Span@D@absl@@QEBAPEADXZ ?data@?$Span@I@absl@@QEBAPEAIXZ ?data@?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEAVFormatArgImpl@str_format_internal@2@XZ ?data@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBAPEBQEAUCordRep@cord_internal@absl@@XZ @@ -2721,6 +2831,7 @@ ?empty@?$InlinedVector@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEBA_NXZ ?empty@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBA_NXZ ?empty@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEBA_NXZ + ?empty@?$Span@D@absl@@QEBA_NXZ ?empty@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ?empty@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ @@ -2746,6 +2857,19 @@ ?end@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ ?end@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEBAPEAPEAUCordRep@cord_internal@3@XZ ?end@string_view@absl@@QEBAPEBDXZ + ?entries@CordRepRing@cord_internal@absl@@QEBAIII@Z + ?entries@CordRepRing@cord_internal@absl@@QEBAIXZ + ?entry_begin_pos@CordRepRing@cord_internal@absl@@QEBAAEB_KI@Z + ?entry_child@CordRepRing@cord_internal@absl@@AEAAPEAPEAUCordRep@23@XZ + ?entry_child@CordRepRing@cord_internal@absl@@QEBAAEBQEAUCordRep@23@I@Z + ?entry_data@CordRepRing@cord_internal@absl@@QEBA?AVstring_view@3@I@Z + ?entry_data_offset@CordRepRing@cord_internal@absl@@AEAAPEAIXZ + ?entry_data_offset@CordRepRing@cord_internal@absl@@QEBAAEBII@Z + ?entry_end_offset@CordRepRing@cord_internal@absl@@QEBA_KI@Z + ?entry_end_pos@CordRepRing@cord_internal@absl@@AEAAPEA_KXZ + ?entry_end_pos@CordRepRing@cord_internal@absl@@QEBAAEB_KI@Z + ?entry_length@CordRepRing@cord_internal@absl@@QEBA_KI@Z + ?entry_start_offset@CordRepRing@cord_internal@absl@@QEBA_KI@Z ?erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@2@PEBU342@@Z ?error@FILERawSink@str_format_internal@absl@@QEBAHXZ ?exchange@?$__atomic_base@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QEAAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZP6AX0@ZW4memory_order@23@@Z @@ -2863,6 +2987,8 @@ ?has_value@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@QEBA_NXZ ?has_zero_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ + ?head@CordRepRing@cord_internal@absl@@QEBAIXZ + ?head@Filler@CordRepRing@cord_internal@absl@@QEBAIXZ ?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ ?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ ?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ @@ -2877,6 +3003,8 @@ ?is_tree@InlineData@cord_internal@absl@@QEBA_NXZ ?is_tree@InlineRep@Cord@absl@@QEBA_NXZ ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ + ?length@?$Span@D@absl@@QEBA_KXZ + ?length@CordRepRingReader@cord_internal@absl@@QEBA_KXZ ?length@string_view@absl@@QEBA_KXZ ?load@?$__atomic_base@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QEBAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZW4memory_order@23@@Z ?load@?$__atomic_base@PEAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QEBAPEAUHashtablezInfo@container_internal@absl@@W4memory_order@23@@Z @@ -2959,6 +3087,7 @@ ?pop_back@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ ?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ ?pop_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ + ?pos@Filler@CordRepRing@cord_internal@absl@@QEBAIXZ ?precision@FormatConversionSpecImpl@str_format_internal@absl@@QEBAHXZ ?prev_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@1234@@Z ?prev_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z @@ -2988,8 +3117,10 @@ ?release@?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@XZ ?release@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@XZ ?release@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAVTimeZoneInfo@cctz@time_internal@absl@@XZ + ?remaining@CordRepRingReader@cord_internal@absl@@QEBA_KXZ ?remove_prefix@InlineRep@Cord@absl@@QEAAX_K@Z ?remove_prefix@string_view@absl@@QEAAX_K@Z + ?remove_suffix@string_view@absl@@QEAAX_K@Z ?rend@string_view@absl@@QEBA?AV?$reverse_iterator@PEBD@__1@std@@XZ ?replace_tree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z @@ -3005,9 +3136,13 @@ ?reset@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAVZoneInfoSource@cctz@time_internal@absl@@@Z ?resize@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z ?resize@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z + ?retreat@CordRepRing@cord_internal@absl@@QEBAII@Z + ?retreat@CordRepRing@cord_internal@absl@@QEBAIII@Z ?rfind@string_view@absl@@QEBA_KD_K@Z ?rfind@string_view@absl@@QEBA_KV12@_K@Z ?ring@CordRep@cord_internal@absl@@QEAAPEAVCordRepRing@23@XZ + ?ring@CordRep@cord_internal@absl@@QEBAPEBVCordRepRing@23@XZ + ?ring@CordRepRingReader@cord_internal@absl@@QEBAPEAVCordRepRing@23@XZ ?safe_strto128_base@numbers_internal@absl@@YA_NVstring_view@2@PEAVint128@2@H@Z ?safe_strto32_base@numbers_internal@absl@@YA_NVstring_view@2@PEAHH@Z ?safe_strto64_base@numbers_internal@absl@@YA_NVstring_view@2@PEA_JH@Z @@ -3072,6 +3207,7 @@ ?size@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBA_KXZ ?size@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEBA_KXZ ?size@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBA_KXZ + ?size@?$Span@D@absl@@QEBA_KXZ ?size@?$Span@I@absl@@QEBA_KXZ ?size@?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QEBA_KXZ ?size@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAAAEA_KXZ @@ -3106,6 +3242,7 @@ ?substring@CordRep@cord_internal@absl@@QEBAPEBUCordRepSubstring@23@XZ ?tag@InlineData@cord_internal@absl@@AEAAAEADXZ ?tag@InlineData@cord_internal@absl@@AEBADXZ + ?tail@CordRepRing@cord_internal@absl@@QEBAIXZ ?thread_identity@PerThreadSynch@base_internal@absl@@QEAAPEAUThreadIdentity@23@XZ ?throw_bad_optional_access@optional_internal@absl@@YAXXZ ?total_written@BufferRawSink@str_format_internal@absl@@QEBA_KXZ
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def index 8595539..718c8831 100644 --- a/third_party/abseil-cpp/symbols_arm64_rel.def +++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -4,6 +4,8 @@ ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z @@ -44,16 +46,23 @@ ??$EmplaceBackSlow@PEAUCordRep@cord_internal@absl@@@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAPEAUCordRep@cord_internal@2@$$QEAPEAU342@@Z ??$EmplaceBackSlow@UPayload@status_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAUPayload@status_internal@2@$$QEAU342@@Z ??$EmplaceBackSlow@USubRange@absl@@@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAUSubRange@2@$$QEAU32@@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@AEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$00@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z ??$GenericCompare@_NVstring_view@absl@@@absl@@YA_NAEBVCord@0@AEBVstring_view@0@_K@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@12@_K@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPEAUCordRep@01@Vstring_view@1@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z @@ -117,7 +126,6 @@ ??0uint128@absl@@QEAA@M@Z ??0uint128@absl@@QEAA@N@Z ??0uint128@absl@@QEAA@O@Z - ??1?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAA@XZ ??1BadStatusOrAccess@absl@@UEAA@XZ ??1CondVar@absl@@QEAA@XZ ??1GraphCycles@synchronization_internal@absl@@QEAA@XZ @@ -139,6 +147,7 @@ ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@Vuint128@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4LogSeverity@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV234@AEBVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -179,6 +188,7 @@ ?AbslParseFlag@absl@@YA_NVstring_view@1@PEAVTime@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VDuration@1@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VTime@1@@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AEAAXI_K@Z ?AddNode@CordForest@absl@@AEAAXPEAUCordRep@cord_internal@2@@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHI@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AEAAXH_K@Z @@ -193,12 +203,16 @@ ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Append@Cord@absl@@QEAAX$$QEAV12@@Z ?Append@Cord@absl@@QEAAXAEBV12@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QEAAXPEBD_K@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?AppendPack@str_format_internal@absl@@YAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?AppendTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z ?AsciiStrToLower@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z @@ -259,10 +273,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@Vstring_view@4@@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@II_K@Z ?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z ?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPEAV123@PEAUCordRep@23@_K@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K11@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ ?DataLength@Header@TimeZoneInfo@cctz@time_internal@absl@@QEBA_K_K@Z @@ -272,12 +290,15 @@ ?DecrementCount@BlockingCounter@absl@@QEAA_NXZ ?DefaultArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@XZ ?DefaultStackUnwinder@absl@@YAHPEAPEAXPEAHHHPEBX1@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPEAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPEBDPEADH@Z ?Description@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ - ?Destroy@CordRep@cord_internal@absl@@SUXPEAU123@@Z + ?Destroy@CordRep@cord_internal@absl@@SAXPEAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAXXZ ?DestroyCordSlow@Cord@absl@@AEAAXXZ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ @@ -322,7 +343,10 @@ ?Find@ByChar@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByLength@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByString@absl@@QEBA?AVstring_view@2@V32@_K@Z + ?FindFlatStartPiece@InlineRep@Cord@absl@@QEBA?AVstring_view@3@XZ ?FindPath@GraphCycles@synchronization_internal@absl@@QEBAHUGraphId@23@0HQEAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -376,13 +400,16 @@ ?FromTM@absl@@YA?AVTime@1@AEBUtm@@VTimeZone@1@@Z ?FromUDate@absl@@YA?AVTime@1@N@Z ?FromUniversal@absl@@YA?AVTime@1@_J@Z + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z ?GetCachedTID@base_internal@absl@@YAIXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QEBAD_K@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAVstring_view@2@@Z ?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z ?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetProgramCounter@debugging_internal@absl@@YAPEAXPEAX@Z ?GetSkipCount@ExponentialBiased@base_internal@absl@@QEAA_J_J@Z ?GetStackFrames@absl@@YAHPEAPEAXPEAHHH@Z @@ -408,6 +435,8 @@ ?In@Time@absl@@QEBA?AUBreakdown@12@VTimeZone@2@@Z ?InMillisecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBAKXZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z + ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AEAAXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PEAUCordRepExternal@12@@Z ?InitializeData@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@AEAAPEAPEAUCordRep@cord_internal@3@XZ @@ -435,6 +464,7 @@ ?IsUnavailable@absl@@YA_NAEBVStatus@1@@Z ?IsUnimplemented@absl@@YA_NAEBVStatus@1@@Z ?IsUnknown@absl@@YA_NAEBVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QEBA_NAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?Iterate@HashtablezSampler@container_internal@absl@@QEAA_JAEBV?$function@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAE_K@Z @@ -472,10 +502,13 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHPEBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AEAAXHPEBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@_K@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?New@CordRepFlat@cord_internal@absl@@SAPEAU123@_K@Z + ?New@CordRepRing@cord_internal@absl@@CAPEAV123@_K0@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@H@Z ?NewRep@Status@absl@@CA_KW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@XZ ?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z ?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z ?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z @@ -513,6 +546,10 @@ ?PrepareToModify@Status@absl@@AEAAXXZ ?Prepend@Cord@absl@@QEAAXAEBV12@@Z ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?PrevTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z ?PrevTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z @@ -553,12 +590,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QEAAXPEAX@Z ?RemovePrefix@Cord@absl@@QEAAX_K@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RemoveSuffix@Cord@absl@@QEAAX_K@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Rethrow@variant_internal@absl@@YAXXZ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QEAAP6AXAEBUHashtablezInfo@23@@ZP6AX0@Z@Z ?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z @@ -601,6 +642,8 @@ ?StrCat@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBVAlphaNum@1@0@Z ?StrReplaceAll@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ?StrReplaceAll@absl@@YAHV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@3@@Z + ?SubLength@CordRepRing@cord_internal@absl@@AEAAXI_K@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K11@Z ?Subcord@Cord@absl@@QEBA?AV12@_K0@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PEBV62@_K@Z ?Summarize@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def index 6039e863..b7f50e051 100644 --- a/third_party/abseil-cpp/symbols_x64_dbg.def +++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -46,6 +46,7 @@ ??$?0AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@?$__compressed_pair@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@Z ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@X@?$__compressed_pair_elem@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@$0A@$0A@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@@Z + ??$?0AEAPEAUCordRep@cord_internal@absl@@AEAPEAU012@$0A@@?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@__1@std@@QEAA@AEAPEAUCordRep@cord_internal@absl@@0@Z ??$?0AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@?$__compressed_pair@PEAUThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z ??$?0AEAPEAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PEAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@@Z ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z @@ -216,6 +217,8 @@ ??$?RW4LogSeverity@absl@@AEBQEBDHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$?RW4LogSeverity@absl@@AEBQEBDHV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAH$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$?XH@Duration@absl@@QEAAAEAV01@H@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z @@ -308,11 +311,21 @@ ??$FastIntToBuffer@G@numbers_internal@absl@@YAPEADGPEAD@Z ??$FastIntToBuffer@J@numbers_internal@absl@@YAPEADJPEAD@Z ??$FastIntToBuffer@K@numbers_internal@absl@@YAPEADKPEAD@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$FindBinary@$00@CordRepRing@cord_internal@absl@@AEBAIII_K@Z + ??$FindBinary@$0A@@CordRepRing@cord_internal@absl@@AEBAIII_K@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@AEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$00@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z ??$FormatConvertImpl@_N$0A@@str_format_internal@absl@@YA?AU?$ArgConvertResult@$0BPPPL@@01@_NVFormatConversionSpecImpl@01@PEAVFormatSinkImpl@01@@Z ??$FromChrono@_JV?$ratio@$00$0PECEA@@__1@std@@@time_internal@absl@@YA?AVDuration@1@AEBV?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@chrono@__1@std@@@Z ??$FromInt64@$00@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$00@__1@std@@@Z @@ -334,7 +347,6 @@ ??$HidePtr@X@base_internal@absl@@YA_KPEAX@Z ??$Init@H@FormatArgImpl@str_format_internal@absl@@AEAAXAEBH@Z ??$Initialize@V?$CopyValueAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$CopyValueAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@12@_K@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@12@_K@Z ??$Invoke@A6AXXZ$$V@Callable@base_internal@absl@@SAXA6AXXZ@Z ??$Invoke@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@3@@Callable@base_internal@absl@@SAX$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@2@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@2@@Z ??$InvokeFlush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@str_format_internal@absl@@YAXPEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@Vstring_view@1@@Z @@ -351,9 +363,31 @@ ??$MakeSpan@$SVFormatArgImpl@str_format_internal@absl@@@absl@@YA?AV?$Span@VFormatArgImpl@str_format_internal@absl@@@0@PEAVFormatArgImpl@str_format_internal@0@_K@Z ??$Milliseconds@N$0A@@absl@@YA?AVDuration@0@N@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPEAUCordRep@01@Vstring_view@1@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$01$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$01$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBA_KXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBA_KXZ ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z + ??$Partial@$$V@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@12@XZ + ??$Partial@AEAI@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@12@AEAI@Z + ??$Partial@AEAIAEAI@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@12@AEAI0@Z + ??$Partial@AEA_K@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@12@AEA_K@Z + ??$Partial@AEA_KAEA_K@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@12@AEA_K0@Z + ??$Partial@I@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@12@$$QEAI@Z + ??$Partial@II@?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@12@$$QEAI0@Z + ??$Pointer@$00$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBAPEBQEAUCordRep@cord_internal@3@PEBD@Z + ??$Pointer@$00D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEBAPEAPEAUCordRep@cord_internal@3@PEAD@Z + ??$Pointer@$01$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBAPEBIPEBD@Z + ??$Pointer@$01D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEBAPEAIPEAD@Z + ??$Pointer@$0A@$$CBD@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEB_KPEBD@Z + ??$Pointer@$0A@D@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEBAPEA_KPEAD@Z ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$STLStringResizeUninitialized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z ??$SharedCompareImpl@VCord@absl@@@absl@@YAHAEBVCord@0@0@Z @@ -596,10 +630,12 @@ ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAAEAUSubRange@1@$$QEAU21@@Z ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z ??$forward@$$T@absl@@YA$$QEA$$TAEA$$T@Z + ??$forward@AEAI@absl@@YAAEAIAEAI@Z ??$forward@AEAPEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEAUCordRep@cord_internal@absl@@AEAPEAPEAU234@@Z ??$forward@AEAPEAPEBUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEBUCordRep@cord_internal@absl@@AEAPEAPEBU234@@Z ??$forward@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z ??$forward@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@YAAEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@01@AEAPEAU201@@Z + ??$forward@AEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAUCordRep@cord_internal@absl@@AEAPEAU234@@Z ??$forward@AEAPEAUPayload@status_internal@absl@@@__1@std@@YAAEAPEAUPayload@status_internal@absl@@AEAPEAU234@@Z ??$forward@AEAPEAUSubRange@absl@@@__1@std@@YAAEAPEAUSubRange@absl@@AEAPEAU23@@Z ??$forward@AEAPEAUThreadIdentity@base_internal@absl@@@__1@std@@YAAEAPEAUThreadIdentity@base_internal@absl@@AEAPEAU234@@Z @@ -635,6 +671,7 @@ ??$forward@AEBVCord@absl@@@absl@@YAAEBVCord@0@AEBV10@@Z ??$forward@AEBVstring_view@absl@@@__1@std@@YAAEBVstring_view@absl@@AEBV23@@Z ??$forward@H@absl@@YA$$QEAHAEAH@Z + ??$forward@I@absl@@YA$$QEAIAEAI@Z ??$forward@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@YA$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@01@AEAPEAPEAU201@@Z ??$forward@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z ??$forward@PEAUCordRep@cord_internal@absl@@@__1@std@@YA$$QEAPEAUCordRep@cord_internal@absl@@AEAPEAU234@@Z @@ -700,6 +737,7 @@ ??$invoke@A6AXXZ$$V@base_internal@absl@@YAXA6AXXZ@Z ??$invoke@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@3@@base_internal@absl@@YAX$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AEAVstring_view@1@@Z ??$lower_bound@PEBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@UByUnixTime@2345@@Z + ??$make_pair@AEAPEAUCordRep@cord_internal@absl@@AEAPEAU123@@__1@std@@YA?AU?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@01@AEAPEAUCordRep@cord_internal@absl@@0@Z ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AEAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z ??$min@VDuration@absl@@@__1@std@@YAAEBVDuration@absl@@AEBV23@0@Z @@ -771,8 +809,14 @@ ??0?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@QEAA@AEBQEBUPayload@status_internal@2@@Z ??0?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAUPayload@status_internal@absl@@@__1@std@@@Z ??0?$IteratorValueAdapter@V?$allocator@USubRange@absl@@@__1@std@@V?$move_iterator@PEAUSubRange@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAUSubRange@absl@@@__1@std@@@Z + ??0?$Layout@_KPEAUCordRep@cord_internal@absl@@I@container_internal@absl@@QEAA@_K00@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEAA@_K00@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00@absl@@U?$integer_sequence@_K$0A@$00$01@5@@internal_layout@container_internal@absl@@QEAA@_K0@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@@absl@@U?$integer_sequence@_K$0A@$00@5@@internal_layout@container_internal@absl@@QEAA@_K@Z + ??0?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$S@absl@@U?$integer_sequence@_K$0A@@5@@internal_layout@container_internal@absl@@QEAA@XZ ??0?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@PEBVFormatArgImpl@str_format_internal@1@_K@Z ??0?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@XZ + ??0?$Span@D@absl@@QEAA@PEAD_K@Z ??0?$Span@I@absl@@QEAA@PEAI_K@Z ??0?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@PEAVFormatArgImpl@str_format_internal@1@_K@Z ??0?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAA@XZ @@ -920,6 +964,7 @@ ??0ByAnyChar@absl@@QEAA@Vstring_view@1@@Z ??0ByLength@absl@@QEAA@_J@Z ??0ByString@absl@@QEAA@Vstring_view@1@@Z + ??0ChunkIterator@Cord@absl@@AEAA@PEAUCordRep@cord_internal@2@@Z ??0ChunkIterator@Cord@absl@@AEAA@PEBV12@@Z ??0ChunkIterator@Cord@absl@@QEAA@XZ ??0ChunkRange@Cord@absl@@QEAA@PEBV12@@Z @@ -936,11 +981,14 @@ ??0CordRepConcat@cord_internal@absl@@QEAA@XZ ??0CordRepExternal@cord_internal@absl@@QEAA@XZ ??0CordRepFlat@cord_internal@absl@@QEAA@XZ + ??0CordRepRing@cord_internal@absl@@AEAA@I@Z + ??0CordRepRingReader@cord_internal@absl@@QEAA@XZ ??0CordRepSubstring@cord_internal@absl@@QEAA@XZ ??0Duration@absl@@AEAA@_JI@Z ??0Duration@absl@@QEAA@XZ ??0ErrnoSaver@base_internal@absl@@QEAA@XZ ??0FILERawSink@str_format_internal@absl@@QEAA@PEAU_iobuf@@@Z + ??0Filler@CordRepRing@cord_internal@absl@@QEAA@PEAV123@I@Z ??0FormatConversionSpecImpl@str_format_internal@absl@@QEAA@XZ ??0FormatSinkImpl@str_format_internal@absl@@QEAA@VFormatRawSinkImpl@12@@Z ??0GraphCycles@synchronization_internal@absl@@QEAA@XZ @@ -1150,6 +1198,7 @@ ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@Vuint128@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4LogSeverity@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV234@AEBVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -1205,6 +1254,7 @@ ??B?$unique_ptr@VTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ??B?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ??BCord@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ + ??BCordRepRingReader@cord_internal@absl@@QEBA_NXZ ??BTimeZone@absl@@QEBA?AVtime_zone@cctz@time_internal@1@XZ ??Bint128@absl@@QEBAEXZ ??Bint128@absl@@QEBANXZ @@ -1288,6 +1338,10 @@ ??Pabsl@@YA_NVDuration@0@0@Z ??Pabsl@@YA_NVint128@0@0@Z ??Pabsl@@YA_NVuint128@0@0@Z + ??R<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV123@II@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV123@II@Z@QEBA?A?<auto>@@I@Z ??R<lambda_1>@?0???A?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@_K@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0???A?$InlinedVector@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@_K@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0???A?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAAEAUPayload@status_internal@2@_K@Z@QEBA?A?<auto>@@XZ @@ -1316,8 +1370,11 @@ ??R<lambda_1>@?0??pop_back@?$InlinedVector@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAXXZ@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??pop_back@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAXXZ@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??remove_prefix@string_view@absl@@QEAAX_K@Z@QEBA?A?<auto>@@XZ + ??R<lambda_1>@?0??remove_suffix@string_view@absl@@QEAAX_K@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??replace_tree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@4@@Z@QEBA?A?<auto>@@XZ ??R<lambda_1>@?0??set_inline_size@InlineData@cord_internal@absl@@QEAAX_K@Z@QEBA?A?<auto>@@XZ + ??R<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z + ??R<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z ??R<lambda_2>@?0??erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@3@PEBU453@@Z@QEBA?A?<auto>@@XZ ??R?$FunctionRef@$$A6AXV?$Span@I@absl@@@Z@absl@@QEBAXV?$Span@I@1@@Z ??R?$FunctionRef@$$A6AXVstring_view@absl@@@Z@absl@@QEBAXVstring_view@1@@Z @@ -1386,6 +1443,8 @@ ?AcquireAllocatedData@?$Storage@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAV?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@23@@Z ?AcquireAllocatedData@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAV?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@23@@Z ?AcquireAllocatedData@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAV?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@23@@Z + ?Add@Filler@CordRepRing@cord_internal@absl@@QEAAXPEAUCordRep@34@_K1@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AEAAXI_K@Z ?AddNode@CordForest@absl@@AEAAXPEAUCordRep@cord_internal@2@@Z ?AddSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAX_K@Z ?AddSize@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAX_K@Z @@ -1400,9 +1459,14 @@ ?AddressIsReadable@debugging_internal@absl@@YA_NPEBX@Z ?AdvanceAndReadBytes@ChunkIterator@Cord@absl@@AEAA?AV23@_K@Z ?AdvanceBytes@ChunkIterator@Cord@absl@@AEAAX_K@Z + ?AdvanceBytesRing@ChunkIterator@Cord@absl@@AEAAX_K@Z ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AEAAX_K@Z + ?AdvanceRing@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ ?AdvanceStack@ChunkIterator@Cord@absl@@AEAAAEAV123@XZ + ?Align@adl_barrier@internal_layout@container_internal@absl@@YA_K_K0@Z ?Alloc@LowLevelAlloc@base_internal@absl@@SAPEAX_K@Z + ?AllocSize@?$LayoutImpl@V?$tuple@_KPEAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@_K$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QEBA_KXZ + ?AllocSize@CordRepRing@cord_internal@absl@@SA_K_K@Z ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPEAX_KPEAUArena@123@@Z ?Allocate@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAPEAH_K@Z ?Allocate@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAPEAPEAUCordRep@cord_internal@3@_K@Z @@ -1411,20 +1475,24 @@ ?Allocate@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAPEAUSubRange@3@_K@Z ?AllocatedSize@CordRepFlat@cord_internal@absl@@QEBA_KXZ ?AllocatedSizeToTag@cord_internal@absl@@YAE_K@Z - ?AllocatedSizeToTagUnchecked@cord_internal@absl@@YA_K_K@Z + ?AllocatedSizeToTagUnchecked@cord_internal@absl@@YAE_K@Z ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?AnnotateConstruct@NonEmptyInlinedStorage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAX_K@Z ?AnnotateDestruct@NonEmptyInlinedStorage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAX_K@Z ?Append@Cord@absl@@QEAAX$$QEAV12@@Z ?Append@Cord@absl@@QEAAXAEBV12@@Z ?Append@Cord@absl@@QEAAXVstring_view@2@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QEAAXPEBD_K@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?AppendNode@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z ?AppendPack@str_format_internal@absl@@YAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?AppendText@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_KVstring_view@4@@Z ?AppendTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z @@ -1509,10 +1577,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@Vstring_view@4@@Z ?ConvertSpecialToEmptyAndFullToDeleted@GroupSse2Impl@container_internal@absl@@QEBAXPEAC@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@II_K@Z ?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z ?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPEAV123@PEAUCordRep@23@_K@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K11@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ ?Data@CordRepFlat@cord_internal@absl@@QEAAPEADXZ @@ -1535,13 +1607,16 @@ ?DefaultStackUnwinder@absl@@YAHPEAPEAXPEAHHHPEBX1@Z ?Delete@CordRepExternal@cord_internal@absl@@SAXPEAUCordRep@23@@Z ?Delete@CordRepFlat@cord_internal@absl@@SAXPEAUCordRep@23@@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPEAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPEBDPEADH@Z ?Description@Impl@time_zone@cctz@time_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ - ?Destroy@CordRep@cord_internal@absl@@SUXPEAU123@@Z + ?Destroy@CordRep@cord_internal@absl@@SAXPEAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAXXZ ?DestroyCordSlow@Cord@absl@@AEAAXXZ ?DidAllocate@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAA_NXZ ?DidAllocate@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAA_NXZ @@ -1551,6 +1626,7 @@ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ ?DisableRescheduling@SchedulingGuard@base_internal@absl@@CA_NXZ + ?Distance@CordRepRing@cord_internal@absl@@SA_K_K0@Z ?DivUp@cord_internal@absl@@YA_K_K0@Z ?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@Vstring_view@2@AEBVCord@2@@Z@base_internal@absl@@AEBAP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@3@Vstring_view@3@AEBVCord@3@@ZXZ ?DoLoad@?$AtomicHook@P6AXPEBDH000@Z@base_internal@absl@@AEBAP6AXPEBDH000@ZXZ @@ -1614,8 +1690,14 @@ ?Find@ByChar@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByLength@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByString@absl@@QEBA?AVstring_view@2@V32@_K@Z + ?Find@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@I_K@Z + ?Find@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@_K@Z ?FindFlatStartPiece@InlineRep@Cord@absl@@QEBA?AVstring_view@3@XZ ?FindPath@GraphCycles@synchronization_internal@absl@@QEBAHUGraphId@23@0HQEAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z + ?FindTail@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@I_K@Z + ?FindTail@CordRepRing@cord_internal@absl@@QEBA?AUPosition@123@_K@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -1708,6 +1790,7 @@ ?GetAllocator@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@XZ ?GetAllocator@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@XZ ?GetAllocator@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@USubRange@absl@@@__1@std@@XZ + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z ?GetCachedTID@base_internal@absl@@YAIXZ @@ -1716,6 +1799,7 @@ ?GetCapacity@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ ?GetCapacity@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ ?GetCapacity@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QEBAD_K@Z ?GetCond@WinHelper@Waiter@synchronization_internal@absl@@SAPEAU_RTL_CONDITION_VARIABLE@@PEAV234@@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetData@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAAEAPEAHXZ @@ -1746,12 +1830,15 @@ ?GetIsAllocated@?$Storage@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEBA_NXZ ?GetIsAllocated@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEBA_NXZ ?GetIsAllocated@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEBA_NXZ + ?GetLeafData@CordRepRing@cord_internal@absl@@SAPEBDPEBUCordRep@23@@Z ?GetLock@WinHelper@Waiter@synchronization_internal@absl@@SAPEAU_RTL_SRWLOCK@@PEAV234@@Z ?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z ?GetPayloads@Status@absl@@AEAAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@2@XZ ?GetPayloads@Status@absl@@AEBAPEBV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@2@XZ + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetProgramCounter@debugging_internal@absl@@YAPEAXPEAX@Z + ?GetRepData@CordRepRing@cord_internal@absl@@SAPEBDPEBUCordRep@23@@Z ?GetRepHi@time_internal@absl@@YA_JVDuration@2@@Z ?GetRepLo@time_internal@absl@@YAIVDuration@2@@Z ?GetSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEBA_KXZ @@ -1810,6 +1897,7 @@ ?InfiniteFuture@absl@@YA?AVTime@1@XZ ?InfinitePast@absl@@YA?AVTime@1@XZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AEAAXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PEAUCordRepExternal@12@@Z @@ -1851,7 +1939,9 @@ ?IsUnavailable@absl@@YA_NAEBVStatus@1@@Z ?IsUnimplemented@absl@@YA_NAEBVStatus@1@@Z ?IsUnknown@absl@@YA_NAEBVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QEBA_NAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?IsValidCapacity@container_internal@absl@@YA_N_K@Z + ?IsValidIndex@CordRepRing@cord_internal@absl@@AEBA_NI@Z ?Iterate@HashtablezSampler@container_internal@absl@@QEAA_JAEBV?$function@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAE_K@Z @@ -1915,14 +2005,17 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHPEBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AEAAXHPEBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@_K@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?Name@Impl@time_zone@cctz@time_internal@absl@@QEBAAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Nanoseconds@absl@@YA?AVDuration@1@_J@Z ?NegateAndSubtractOne@time_internal@absl@@YA_J_J@Z ?Never@KernelTimeout@synchronization_internal@absl@@SA?AV123@XZ ?New@CordRepFlat@cord_internal@absl@@SAPEAU123@_K@Z + ?New@CordRepRing@cord_internal@absl@@CAPEAV123@_K0@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@H@Z ?NewRep@Status@absl@@CA_KW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@XZ ?NextCapacity@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@SA_K_K@Z ?NextCapacity@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@SA_K_K@Z ?NextCapacity@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@SA_K_K@Z @@ -1976,7 +2069,11 @@ ?PrepareToModify@Status@absl@@AEAAXXZ ?Prepend@Cord@absl@@QEAAXAEBV12@@Z ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?PrependNode@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?PrevTransition@Impl@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@2345@@Z ?PrevTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z @@ -2025,13 +2122,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QEAAXPEAX@Z ?RemovePrefix@Cord@absl@@QEAAX_K@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RemoveSuffix@Cord@absl@@QEAAX_K@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RepToPointer@Status@absl@@CAPEAUStatusRep@status_internal@2@_K@Z ?Reset@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ ?Reset@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXXZ + ?Reset@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@PEAVCordRepRing@23@@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResetToEmpty@InlineRep@Cord@absl@@AEAAXXZ ?Resize@?$ResizeUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z @@ -2042,12 +2142,14 @@ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z ?Seconds@absl@@YA?AVDuration@1@_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z ?SetAllocatedData@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAH_K@Z ?SetAllocatedData@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAPEAUCordRep@cord_internal@3@_K@Z ?SetAllocatedData@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAPEAUCordRep@cord_internal@3@_K@Z ?SetAllocatedData@?$Storage@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAPEBUCordRep@cord_internal@3@_K@Z ?SetAllocatedData@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAUPayload@status_internal@3@_K@Z ?SetAllocatedData@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXPEAUSubRange@3@_K@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z ?SetConversionChar@FormatConversionSpecImplFriend@str_format_internal@absl@@SAXW4FormatConversionChar@3@PEAVFormatConversionSpecImpl@23@@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QEAAP6AXAEBUHashtablezInfo@23@@ZP6AX0@Z@Z @@ -2119,6 +2221,8 @@ ?StripLeadingAsciiWhitespace@absl@@YA?AVstring_view@1@V21@@Z ?StripTrailingAsciiWhitespace@absl@@YA?AVstring_view@1@V21@@Z ?StrlenInternal@string_view@absl@@CA_KPEBD@Z + ?SubLength@CordRepRing@cord_internal@absl@@AEAAXI_K@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K11@Z ?Subcord@Cord@absl@@QEBA?AV12@_K0@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PEBV62@_K@Z ?SubtractSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAX_K@Z @@ -2242,6 +2346,7 @@ ?UsingInlinedStorage@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@CA_N_K@Z ?Utf8SafeCEscape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@@Z ?Utf8SafeCHexEscape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@@Z + ?Validate@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEBDH@Z ?Value@?$Manager@C$01@FormatArgImpl@str_format_internal@absl@@SACTData@234@@Z ?Value@?$Manager@D$01@FormatArgImpl@str_format_internal@absl@@SADTData@234@@Z ?Value@?$Manager@E$01@FormatArgImpl@str_format_internal@absl@@SAETData@234@@Z @@ -2510,6 +2615,8 @@ ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z ?__vdeallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ ?_mm_cmpgt_epi8_fixed@container_internal@absl@@YA?AT__m128i@@T3@0@Z + ?advance@CordRepRing@cord_internal@absl@@QEBAII@Z + ?advance@CordRepRing@cord_internal@absl@@QEBAIII@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uday_tag@1234@U51234@@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uhour_tag@1234@U51234@@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uminute_tag@1234@U51234@@Z @@ -2614,6 +2721,7 @@ ?capacity@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ ?capacity@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ ?capacity@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ + ?capacity@CordRepRing@cord_internal@absl@@QEBAIXZ ?chunk_begin@Cord@absl@@QEBA?AVChunkIterator@12@XZ ?chunk_end@Cord@absl@@QEBA?AVChunkIterator@12@XZ ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ @@ -2636,6 +2744,7 @@ ?compare_exchange_weak@?$__atomic_base@PEAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QEAA_NAEAPEAUHashtablezInfo@container_internal@absl@@PEAU456@W4memory_order@23@2@Z ?concat@CordRep@cord_internal@absl@@QEAAPEAUCordRepConcat@23@XZ ?concat@CordRep@cord_internal@absl@@QEBAPEBUCordRepConcat@23@XZ + ?consumed@CordRepRingReader@cord_internal@absl@@QEBA_KXZ ?conversion_char@FormatConversionSpecImpl@str_format_internal@absl@@QEBA?AW4FormatConversionChar@3@XZ ?cord_ring_buffer_enabled@cord_internal@absl@@3U?$atomic@_N@__1@std@@A ?count@FILERawSink@str_format_internal@absl@@QEBA_KXZ @@ -2648,6 +2757,7 @@ ?data@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAPEBUPayload@status_internal@2@XZ ?data@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAPEAUSubRange@2@XZ ?data@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEBVFormatArgImpl@str_format_internal@2@XZ + ?data@?$Span@D@absl@@QEBAPEADXZ ?data@?$Span@I@absl@@QEBAPEAIXZ ?data@?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEAVFormatArgImpl@str_format_internal@2@XZ ?data@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBAPEBQEAUCordRep@cord_internal@absl@@XZ @@ -2720,6 +2830,7 @@ ?empty@?$InlinedVector@PEBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEBA_NXZ ?empty@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBA_NXZ ?empty@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEBA_NXZ + ?empty@?$Span@D@absl@@QEBA_NXZ ?empty@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ?empty@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ ?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEBA_NXZ @@ -2745,6 +2856,19 @@ ?end@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ ?end@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEBAPEAPEAUCordRep@cord_internal@3@XZ ?end@string_view@absl@@QEBAPEBDXZ + ?entries@CordRepRing@cord_internal@absl@@QEBAIII@Z + ?entries@CordRepRing@cord_internal@absl@@QEBAIXZ + ?entry_begin_pos@CordRepRing@cord_internal@absl@@QEBAAEB_KI@Z + ?entry_child@CordRepRing@cord_internal@absl@@AEAAPEAPEAUCordRep@23@XZ + ?entry_child@CordRepRing@cord_internal@absl@@QEBAAEBQEAUCordRep@23@I@Z + ?entry_data@CordRepRing@cord_internal@absl@@QEBA?AVstring_view@3@I@Z + ?entry_data_offset@CordRepRing@cord_internal@absl@@AEAAPEAIXZ + ?entry_data_offset@CordRepRing@cord_internal@absl@@QEBAAEBII@Z + ?entry_end_offset@CordRepRing@cord_internal@absl@@QEBA_KI@Z + ?entry_end_pos@CordRepRing@cord_internal@absl@@AEAAPEA_KXZ + ?entry_end_pos@CordRepRing@cord_internal@absl@@QEBAAEB_KI@Z + ?entry_length@CordRepRing@cord_internal@absl@@QEBA_KI@Z + ?entry_start_offset@CordRepRing@cord_internal@absl@@QEBA_KI@Z ?erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@2@PEBU342@@Z ?error@FILERawSink@str_format_internal@absl@@QEBAHXZ ?exchange@?$__atomic_base@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QEAAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZP6AX0@ZW4memory_order@23@@Z @@ -2862,6 +2986,8 @@ ?has_value@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@QEBA_NXZ ?has_zero_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ + ?head@CordRepRing@cord_internal@absl@@QEBAIXZ + ?head@Filler@CordRepRing@cord_internal@absl@@QEBAIXZ ?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ ?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ ?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ @@ -2876,6 +3002,8 @@ ?is_tree@InlineData@cord_internal@absl@@QEBA_NXZ ?is_tree@InlineRep@Cord@absl@@QEBA_NXZ ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ + ?length@?$Span@D@absl@@QEBA_KXZ + ?length@CordRepRingReader@cord_internal@absl@@QEBA_KXZ ?length@string_view@absl@@QEBA_KXZ ?load@?$__atomic_base@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QEBAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZW4memory_order@23@@Z ?load@?$__atomic_base@PEAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QEBAPEAUHashtablezInfo@container_internal@absl@@W4memory_order@23@@Z @@ -2958,6 +3086,7 @@ ?pop_back@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ ?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ ?pop_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ + ?pos@Filler@CordRepRing@cord_internal@absl@@QEBAIXZ ?precision@FormatConversionSpecImpl@str_format_internal@absl@@QEBAHXZ ?prev_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@1234@@Z ?prev_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z @@ -2987,8 +3116,10 @@ ?release@?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@XZ ?release@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@XZ ?release@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAVTimeZoneInfo@cctz@time_internal@absl@@XZ + ?remaining@CordRepRingReader@cord_internal@absl@@QEBA_KXZ ?remove_prefix@InlineRep@Cord@absl@@QEAAX_K@Z ?remove_prefix@string_view@absl@@QEAAX_K@Z + ?remove_suffix@string_view@absl@@QEAAX_K@Z ?rend@string_view@absl@@QEBA?AV?$reverse_iterator@PEBD@__1@std@@XZ ?replace_tree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z @@ -3004,9 +3135,13 @@ ?reset@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAVZoneInfoSource@cctz@time_internal@absl@@@Z ?resize@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z ?resize@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z + ?retreat@CordRepRing@cord_internal@absl@@QEBAII@Z + ?retreat@CordRepRing@cord_internal@absl@@QEBAIII@Z ?rfind@string_view@absl@@QEBA_KD_K@Z ?rfind@string_view@absl@@QEBA_KV12@_K@Z ?ring@CordRep@cord_internal@absl@@QEAAPEAVCordRepRing@23@XZ + ?ring@CordRep@cord_internal@absl@@QEBAPEBVCordRepRing@23@XZ + ?ring@CordRepRingReader@cord_internal@absl@@QEBAPEAVCordRepRing@23@XZ ?safe_strto128_base@numbers_internal@absl@@YA_NVstring_view@2@PEAVint128@2@H@Z ?safe_strto32_base@numbers_internal@absl@@YA_NVstring_view@2@PEAHH@Z ?safe_strto64_base@numbers_internal@absl@@YA_NVstring_view@2@PEA_JH@Z @@ -3071,6 +3206,7 @@ ?size@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBA_KXZ ?size@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEBA_KXZ ?size@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBA_KXZ + ?size@?$Span@D@absl@@QEBA_KXZ ?size@?$Span@I@absl@@QEBA_KXZ ?size@?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QEBA_KXZ ?size@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAAAEA_KXZ @@ -3105,6 +3241,7 @@ ?substring@CordRep@cord_internal@absl@@QEBAPEBUCordRepSubstring@23@XZ ?tag@InlineData@cord_internal@absl@@AEAAAEADXZ ?tag@InlineData@cord_internal@absl@@AEBADXZ + ?tail@CordRepRing@cord_internal@absl@@QEBAIXZ ?thread_identity@PerThreadSynch@base_internal@absl@@QEAAPEAUThreadIdentity@23@XZ ?throw_bad_optional_access@optional_internal@absl@@YAXXZ ?total_written@BufferRawSink@str_format_internal@absl@@QEBA_KXZ
diff --git a/third_party/abseil-cpp/symbols_x64_rel.def b/third_party/abseil-cpp/symbols_x64_rel.def index 985ac8c..fdd47fe6 100644 --- a/third_party/abseil-cpp/symbols_x64_rel.def +++ b/third_party/abseil-cpp/symbols_x64_rel.def
@@ -4,6 +4,8 @@ ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z @@ -44,16 +46,23 @@ ??$EmplaceBackSlow@PEAUCordRep@cord_internal@absl@@@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAPEAUCordRep@cord_internal@2@$$QEAPEAU342@@Z ??$EmplaceBackSlow@UPayload@status_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAUPayload@status_internal@2@$$QEAU342@@Z ??$EmplaceBackSlow@USubRange@absl@@@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAUSubRange@2@$$QEAU32@@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@AEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$00@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z ??$GenericCompare@_NVstring_view@absl@@@absl@@YA_NAEBVCord@0@AEBVstring_view@0@_K@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@12@_K@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPEAUCordRep@01@Vstring_view@1@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z @@ -119,7 +128,6 @@ ??0uint128@absl@@QEAA@M@Z ??0uint128@absl@@QEAA@N@Z ??0uint128@absl@@QEAA@O@Z - ??1?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAA@XZ ??1BadStatusOrAccess@absl@@UEAA@XZ ??1CondVar@absl@@QEAA@XZ ??1GraphCycles@synchronization_internal@absl@@QEAA@XZ @@ -141,6 +149,7 @@ ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@Vuint128@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4LogSeverity@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV234@AEBVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -180,6 +189,7 @@ ?AbslParseFlag@absl@@YA_NVstring_view@1@PEAVTime@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VDuration@1@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VTime@1@@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AEAAXI_K@Z ?AddNode@CordForest@absl@@AEAAXPEAUCordRep@cord_internal@2@@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHI@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AEAAXH_K@Z @@ -194,12 +204,16 @@ ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Append@Cord@absl@@QEAAX$$QEAV12@@Z ?Append@Cord@absl@@QEAAXAEBV12@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QEAAXPEBD_K@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?AppendPack@str_format_internal@absl@@YAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?AppendTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z ?AsciiStrToLower@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z @@ -260,10 +274,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@Vstring_view@4@@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@II_K@Z ?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z ?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPEAV123@PEAUCordRep@23@_K@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K11@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ ?DataLength@Header@TimeZoneInfo@cctz@time_internal@absl@@QEBA_K_K@Z @@ -273,12 +291,15 @@ ?DecrementCount@BlockingCounter@absl@@QEAA_NXZ ?DefaultArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@XZ ?DefaultStackUnwinder@absl@@YAHPEAPEAXPEAHHHPEBX1@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPEAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPEBDPEADH@Z ?Description@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ - ?Destroy@CordRep@cord_internal@absl@@SUXPEAU123@@Z + ?Destroy@CordRep@cord_internal@absl@@SAXPEAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAXXZ ?DestroyCordSlow@Cord@absl@@AEAAXXZ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ @@ -324,6 +345,8 @@ ?Find@ByLength@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByString@absl@@QEBA?AVstring_view@2@V32@_K@Z ?FindPath@GraphCycles@synchronization_internal@absl@@QEBAHUGraphId@23@0HQEAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -377,13 +400,16 @@ ?FromTM@absl@@YA?AVTime@1@AEBUtm@@VTimeZone@1@@Z ?FromUDate@absl@@YA?AVTime@1@N@Z ?FromUniversal@absl@@YA?AVTime@1@_J@Z + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z ?GetCachedTID@base_internal@absl@@YAIXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QEBAD_K@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAVstring_view@2@@Z ?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z ?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetProgramCounter@debugging_internal@absl@@YAPEAXPEAX@Z ?GetSkipCount@ExponentialBiased@base_internal@absl@@QEAA_J_J@Z ?GetStackFrames@absl@@YAHPEAPEAXPEAHHH@Z @@ -409,6 +435,8 @@ ?In@Time@absl@@QEBA?AUBreakdown@12@VTimeZone@2@@Z ?InMillisecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBAKXZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z + ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AEAAXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PEAUCordRepExternal@12@@Z ?InitializeData@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@AEAAPEAPEAUCordRep@cord_internal@3@XZ @@ -436,6 +464,7 @@ ?IsUnavailable@absl@@YA_NAEBVStatus@1@@Z ?IsUnimplemented@absl@@YA_NAEBVStatus@1@@Z ?IsUnknown@absl@@YA_NAEBVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QEBA_NAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?Iterate@HashtablezSampler@container_internal@absl@@QEAA_JAEBV?$function@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAE_K@Z @@ -473,10 +502,13 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHPEBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AEAAXHPEBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@_K@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?New@CordRepFlat@cord_internal@absl@@SAPEAU123@_K@Z + ?New@CordRepRing@cord_internal@absl@@CAPEAV123@_K0@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@H@Z ?NewRep@Status@absl@@CA_KW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@XZ ?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z ?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z ?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z @@ -514,6 +546,10 @@ ?PrepareToModify@Status@absl@@AEAAXXZ ?Prepend@Cord@absl@@QEAAXAEBV12@@Z ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?PrevTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z ?PrevTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z @@ -554,12 +590,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QEAAXPEAX@Z ?RemovePrefix@Cord@absl@@QEAAX_K@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RemoveSuffix@Cord@absl@@QEAAX_K@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Rethrow@variant_internal@absl@@YAXXZ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QEAAP6AXAEBUHashtablezInfo@23@@ZP6AX0@Z@Z ?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z @@ -602,6 +642,8 @@ ?StrCat@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBVAlphaNum@1@0@Z ?StrReplaceAll@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ?StrReplaceAll@absl@@YAHV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@3@@Z + ?SubLength@CordRepRing@cord_internal@absl@@AEAAXI_K@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K11@Z ?Subcord@Cord@absl@@QEBA?AV12@_K0@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PEBV62@_K@Z ?Summarize@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel_asan.def b/third_party/abseil-cpp/symbols_x64_rel_asan.def index c00d23b..a29b5e1 100644 --- a/third_party/abseil-cpp/symbols_x64_rel_asan.def +++ b/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -4,6 +4,8 @@ ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z @@ -44,16 +46,23 @@ ??$EmplaceBackSlow@PEAUCordRep@cord_internal@absl@@@?$Storage@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAPEAUCordRep@cord_internal@2@$$QEAPEAU342@@Z ??$EmplaceBackSlow@UPayload@status_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAUPayload@status_internal@2@$$QEAU342@@Z ??$EmplaceBackSlow@USubRange@absl@@@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAAEAUSubRange@2@$$QEAU32@@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV012@II@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@AEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$00@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AEAAXPEBV234@II@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_1>@?0???$Fill@$0A@@012@AEAAXPEBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$00@012@CAPEAV012@PEAV012@0_K1@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV234@PEAV234@0_K1@Z@@CordRepRing@cord_internal@absl@@QEBAXII$$QEAV<lambda_2>@?0???$AddRing@$0A@@012@CAPEAV012@PEAV012@0_K1@Z@@Z ??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z ??$GenericCompare@HVstring_view@absl@@@absl@@YAHAEBVCord@0@AEBVstring_view@0@_K@Z ??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z ??$GenericCompare@_NVstring_view@absl@@@absl@@YA_NAEBVCord@0@AEBVstring_view@0@_K@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@12@_K@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPEAUCordRep@01@Vstring_view@1@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z @@ -127,7 +136,6 @@ ??0uint128@absl@@QEAA@M@Z ??0uint128@absl@@QEAA@N@Z ??0uint128@absl@@QEAA@O@Z - ??1?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAA@XZ ??1?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAA@XZ ??1?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@XZ ??1?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@XZ @@ -158,6 +166,7 @@ ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@Vuint128@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4LogSeverity@0@@Z ??6absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV234@AEBVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AEAV456@AEBV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -197,6 +206,7 @@ ?AbslParseFlag@absl@@YA_NVstring_view@1@PEAVTime@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VDuration@1@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VTime@1@@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AEAAXI_K@Z ?AddNode@CordForest@absl@@AEAAXPEAUCordRep@cord_internal@2@@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHI@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AEAAXH_K@Z @@ -213,12 +223,16 @@ ?AnnotateDestruct@NonEmptyInlinedStorage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAX_K@Z ?Append@Cord@absl@@QEAAX$$QEAV12@@Z ?Append@Cord@absl@@QEAAXAEBV12@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QEAAXPEBD_K@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z ?AppendPack@str_format_internal@absl@@YAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?AppendTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z ?AsciiStrToLower@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z @@ -278,10 +292,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NMAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z ?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@II_K@Z ?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z ?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPEAV123@PEAUCordRep@23@_K@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K11@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAUCordRep@23@_K@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ ?DataLength@Header@TimeZoneInfo@cctz@time_internal@absl@@QEBA_K_K@Z @@ -291,12 +309,15 @@ ?DecrementCount@BlockingCounter@absl@@QEAA_NXZ ?DefaultArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@XZ ?DefaultStackUnwinder@absl@@YAHPEAPEAXPEAHHHPEBX1@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPEAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPEBDPEADH@Z ?Description@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Destroy@CordRep@cord_internal@absl@@SAXPEAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPEAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AEAAXXZ ?DestroyCordSlow@Cord@absl@@AEAAXXZ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ @@ -341,7 +362,10 @@ ?Find@ByChar@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByLength@absl@@QEBA?AVstring_view@2@V32@_K@Z ?Find@ByString@absl@@QEBA?AVstring_view@2@V32@_K@Z + ?FindFlatStartPiece@InlineRep@Cord@absl@@QEBA?AVstring_view@3@XZ ?FindPath@GraphCycles@synchronization_internal@absl@@QEBAHUGraphId@23@0HQEAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -395,13 +419,16 @@ ?FromTM@absl@@YA?AVTime@1@AEBUtm@@VTimeZone@1@@Z ?FromUDate@absl@@YA?AVTime@1@N@Z ?FromUniversal@absl@@YA?AVTime@1@_J@Z + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z ?GetCachedTID@base_internal@absl@@YAIXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QEBAD_K@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAVstring_view@2@@Z ?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z ?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z ?GetProgramCounter@debugging_internal@absl@@YAPEAXPEAX@Z ?GetSkipCount@ExponentialBiased@base_internal@absl@@QEAA_J_J@Z ?GetStackFrames@absl@@YAHPEAPEAXPEAHHH@Z @@ -427,6 +454,8 @@ ?In@Time@absl@@QEBA?AUBreakdown@12@VTimeZone@2@@Z ?InMillisecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBAKXZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPEAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z + ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AEAAXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PEAUCordRepExternal@12@@Z ?InitializeData@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@AEAAPEAPEAUCordRep@cord_internal@3@XZ @@ -454,6 +483,7 @@ ?IsUnavailable@absl@@YA_NAEBVStatus@1@@Z ?IsUnimplemented@absl@@YA_NAEBVStatus@1@@Z ?IsUnknown@absl@@YA_NAEBVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QEBA_NAEAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?Iterate@HashtablezSampler@container_internal@absl@@QEAA_JAEBV?$function@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAE_K@Z @@ -491,10 +521,13 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AEAAXHPEBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AEAAXHPEBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@_K@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?New@CordRepFlat@cord_internal@absl@@SAPEAU123@_K@Z + ?New@CordRepRing@cord_internal@absl@@CAPEAV123@_K0@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@H@Z ?NewRep@Status@absl@@CA_KW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@XZ ?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z ?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z ?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z @@ -532,6 +565,10 @@ ?PrepareToModify@Status@absl@@AEAAXXZ ?Prepend@Cord@absl@@QEAAXAEBV12@@Z ?Prepend@Cord@absl@@QEAAXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@PEAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@Vstring_view@3@_K@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@_K2@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@PEAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@@Z ?PrevTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z ?PrevTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PEAUcivil_transition@time_zone@234@@Z @@ -572,12 +609,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QEAAXPEAX@Z ?RemovePrefix@Cord@absl@@QEAAX_K@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?RemoveSuffix@Cord@absl@@QEAAX_K@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K1@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Rethrow@variant_internal@absl@@YAXXZ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QEAA?AVstring_view@3@_K@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QEAAX_K@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPEAUThreadIdentity@12@P6AXPEAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QEAAP6AXAEBUHashtablezInfo@23@@ZP6AX0@Z@Z ?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z @@ -620,6 +661,8 @@ ?StrCat@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBVAlphaNum@1@0@Z ?StrReplaceAll@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ?StrReplaceAll@absl@@YAHV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@3@@Z + ?SubLength@CordRepRing@cord_internal@absl@@AEAAXI_K@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPEAV123@PEAV123@_K11@Z ?Subcord@Cord@absl@@QEBA?AV12@_K0@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PEBV62@_K@Z ?Summarize@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def index 95de89e1..b9ba368 100644 --- a/third_party/abseil-cpp/symbols_x86_dbg.def +++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -49,6 +49,7 @@ ??$?0AAPAPBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PAPBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z ??$?0AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@12@@?$__compressed_pair@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@__1@std@@QAE@AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@12@@Z ??$?0AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@X@?$__compressed_pair_elem@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@$0A@$0A@@__1@std@@QAE@AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@12@@Z + ??$?0AAPAUCordRep@cord_internal@absl@@AAPAU012@$0A@@?$pair@PAUCordRep@cord_internal@absl@@PAU123@@__1@std@@QAE@AAPAUCordRep@cord_internal@absl@@0@Z ??$?0AAPAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@?$__compressed_pair@PAUThreadIdentity@base_internal@absl@@P6AXPAX@Z@__1@std@@QAE@AAPAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z ??$?0AAPAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAUThreadIdentity@base_internal@absl@@@Z ??$?0AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z @@ -216,6 +217,8 @@ ??$?RW4LogSeverity@absl@@ABQBDHAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@ABQBD$$QAHAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$?RW4LogSeverity@absl@@ABQBDHV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@ABQBD$$QAH$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$?XH@Duration@absl@@QAEAAV01@H@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV012@PAV012@0II@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV012@PAV012@0II@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@ABVCord@absl@@@Cord@absl@@AAEXABV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AAEX$$QAV01@@Z @@ -308,11 +311,21 @@ ??$FastIntToBuffer@G@numbers_internal@absl@@YAPADGPAD@Z ??$FastIntToBuffer@J@numbers_internal@absl@@YAPADJPAD@Z ??$FastIntToBuffer@K@numbers_internal@absl@@YAPADKPAD@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AAEXPBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AAEXPBV012@II@Z + ??$FindBinary@$00@CordRepRing@cord_internal@absl@@ABEIIII@Z + ??$FindBinary@$0A@@CordRepRing@cord_internal@absl@@ABEIIII@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@ABV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$AddRing@$00@012@CAPAV012@PAV012@0II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$AddRing@$0A@@012@CAPAV012@PAV012@0II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AAEXPBV234@II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$Fill@$00@012@AAEXPBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AAEXPBV234@II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$Fill@$0A@@012@AAEXPBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_2>@?0???$AddRing@$00@012@CAPAV012@PAV012@0II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_2>@?0???$AddRing@$0A@@012@CAPAV012@PAV012@0II@Z@@Z ??$FormatConvertImpl@_N$0A@@str_format_internal@absl@@YA?AU?$ArgConvertResult@$0BPPPL@@01@_NVFormatConversionSpecImpl@01@PAVFormatSinkImpl@01@@Z ??$FromChrono@_JV?$ratio@$00$0PECEA@@__1@std@@@time_internal@absl@@YA?AVDuration@1@ABV?$duration@_JV?$ratio@$00$0PECEA@@__1@std@@@chrono@__1@std@@@Z ??$FromInt64@$00@time_internal@absl@@YA?AVDuration@1@_JV?$ratio@$00$00@__1@std@@@Z @@ -334,7 +347,6 @@ ??$HidePtr@X@base_internal@absl@@YAIPAX@Z ??$Init@H@FormatArgImpl@str_format_internal@absl@@AAEXABH@Z ??$Initialize@V?$CopyValueAdapter@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@@?$Storage@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXV?$CopyValueAdapter@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@12@I@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PBUPayload@status_internal@absl@@@12@I@Z ??$Invoke@A6AXXZ$$V@Callable@base_internal@absl@@SAXA6AXXZ@Z ??$Invoke@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AAVstring_view@3@@Callable@base_internal@absl@@SAX$$QAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@2@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AAVstring_view@2@@Z ??$InvokeFlush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@str_format_internal@absl@@YAXPAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@Vstring_view@1@@Z @@ -351,9 +363,29 @@ ??$MakeSpan@$SVFormatArgImpl@str_format_internal@absl@@@absl@@YA?AV?$Span@VFormatArgImpl@str_format_internal@absl@@@0@PAVFormatArgImpl@str_format_internal@0@I@Z ??$Milliseconds@N$0A@@absl@@YA?AVDuration@0@N@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPAUCordRep@01@Vstring_view@1@$$QAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$00$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$01$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$01$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@container_internal@absl@@QBEIXZ + ??$Offset@$0A@$0A@@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@container_internal@absl@@QBEIXZ ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PBD0W4chars_format@1@@Z ??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NVstring_view@1@UParsedFormatConsumer@ParsedFormatBase@01@@Z + ??$Partial@$$V@?$Layout@IPAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@12@XZ + ??$Partial@AAI@?$Layout@IPAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@12@AAI@Z + ??$Partial@AAIAAI@?$Layout@IPAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@12@AAI0@Z + ??$Partial@I@?$Layout@IPAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@12@$$QAI@Z + ??$Partial@II@?$Layout@IPAUCordRep@cord_internal@absl@@I@container_internal@absl@@SA?AV?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@12@$$QAI0@Z + ??$Pointer@$00$$CBD@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@container_internal@absl@@QBEPBQAUCordRep@cord_internal@3@PBD@Z + ??$Pointer@$00D@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@container_internal@absl@@QBEPAPAUCordRep@cord_internal@3@PAD@Z + ??$Pointer@$01$$CBD@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QBEPBIPBD@Z + ??$Pointer@$01D@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QBEPAIPAD@Z + ??$Pointer@$0A@$$CBD@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@container_internal@absl@@QBEPBIPBD@Z + ??$Pointer@$0A@D@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@container_internal@absl@@QBEPAIPAD@Z ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$STLStringResizeUninitialized@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@I@Z ??$SharedCompareImpl@VCord@absl@@@absl@@YAHABVCord@0@0@Z @@ -599,6 +631,7 @@ ??$forward@AAPAPBUCordRep@cord_internal@absl@@@__1@std@@YAAAPAPBUCordRep@cord_internal@absl@@AAPAPBU234@@Z ??$forward@AAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAAAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAPAPBV23456@@Z ??$forward@AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@YAAAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@01@AAPAU201@@Z + ??$forward@AAPAUCordRep@cord_internal@absl@@@__1@std@@YAAAPAUCordRep@cord_internal@absl@@AAPAU234@@Z ??$forward@AAPAUPayload@status_internal@absl@@@__1@std@@YAAAPAUPayload@status_internal@absl@@AAPAU234@@Z ??$forward@AAPAUSubRange@absl@@@__1@std@@YAAAPAUSubRange@absl@@AAPAU23@@Z ??$forward@AAPAUThreadIdentity@base_internal@absl@@@__1@std@@YAAAPAUThreadIdentity@base_internal@absl@@AAPAU234@@Z @@ -633,6 +666,7 @@ ??$forward@ABVCord@absl@@@absl@@YAABVCord@0@ABV10@@Z ??$forward@ABVstring_view@absl@@@__1@std@@YAABVstring_view@absl@@ABV23@@Z ??$forward@H@absl@@YA$$QAHAAH@Z + ??$forward@I@absl@@YA$$QAIAAI@Z ??$forward@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@YA$$QAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@01@AAPAPAU201@@Z ??$forward@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAPAPBV23456@@Z ??$forward@PAUCordRep@cord_internal@absl@@@__1@std@@YA$$QAPAUCordRep@cord_internal@absl@@AAPAU234@@Z @@ -698,6 +732,7 @@ ??$invoke@A6AXXZ$$V@base_internal@absl@@YAXA6AXXZ@Z ??$invoke@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AAVstring_view@3@@base_internal@absl@@YAX$$QAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@AAVstring_view@1@@Z ??$lower_bound@PBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@__1@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@UByUnixTime@2345@@Z + ??$make_pair@AAPAUCordRep@cord_internal@absl@@AAPAU123@@__1@std@@YA?AU?$pair@PAUCordRep@cord_internal@absl@@PAU123@@01@AAPAUCordRep@cord_internal@absl@@0@Z ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z ??$min@VDuration@absl@@@__1@std@@YAABVDuration@absl@@ABV23@0@Z @@ -769,8 +804,14 @@ ??0?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@QAE@ABQBUPayload@status_internal@2@@Z ??0?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@QAE@ABV?$move_iterator@PAUPayload@status_internal@absl@@@__1@std@@@Z ??0?$IteratorValueAdapter@V?$allocator@USubRange@absl@@@__1@std@@V?$move_iterator@PAUSubRange@absl@@@23@@inlined_vector_internal@absl@@QAE@ABV?$move_iterator@PAUSubRange@absl@@@__1@std@@@Z + ??0?$Layout@IPAUCordRep@cord_internal@absl@@I@container_internal@absl@@QAE@III@Z + ??0?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QAE@III@Z + ??0?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00@absl@@U?$integer_sequence@I$0A@$00$01@5@@internal_layout@container_internal@absl@@QAE@II@Z + ??0?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@@absl@@U?$integer_sequence@I$0A@$00@5@@internal_layout@container_internal@absl@@QAE@I@Z + ??0?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$S@absl@@U?$integer_sequence@I$0A@@5@@internal_layout@container_internal@absl@@QAE@XZ ??0?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QAE@PBVFormatArgImpl@str_format_internal@1@I@Z ??0?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QAE@XZ + ??0?$Span@D@absl@@QAE@PADI@Z ??0?$Span@I@absl@@QAE@PAII@Z ??0?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QAE@PAVFormatArgImpl@str_format_internal@1@I@Z ??0?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAE@XZ @@ -918,6 +959,7 @@ ??0ByAnyChar@absl@@QAE@Vstring_view@1@@Z ??0ByLength@absl@@QAE@H@Z ??0ByString@absl@@QAE@Vstring_view@1@@Z + ??0ChunkIterator@Cord@absl@@AAE@PAUCordRep@cord_internal@2@@Z ??0ChunkIterator@Cord@absl@@AAE@PBV12@@Z ??0ChunkIterator@Cord@absl@@QAE@XZ ??0ChunkRange@Cord@absl@@QAE@PBV12@@Z @@ -934,11 +976,14 @@ ??0CordRepConcat@cord_internal@absl@@QAE@XZ ??0CordRepExternal@cord_internal@absl@@QAE@XZ ??0CordRepFlat@cord_internal@absl@@QAE@XZ + ??0CordRepRing@cord_internal@absl@@AAE@I@Z + ??0CordRepRingReader@cord_internal@absl@@QAE@XZ ??0CordRepSubstring@cord_internal@absl@@QAE@XZ ??0Duration@absl@@AAE@_JI@Z ??0Duration@absl@@QAE@XZ ??0ErrnoSaver@base_internal@absl@@QAE@XZ ??0FILERawSink@str_format_internal@absl@@QAE@PAU_iobuf@@@Z + ??0Filler@CordRepRing@cord_internal@absl@@QAE@PAV123@I@Z ??0FormatConversionSpecImpl@str_format_internal@absl@@QAE@XZ ??0FormatSinkImpl@str_format_internal@absl@@QAE@VFormatRawSinkImpl@12@@Z ??0GraphCycles@synchronization_internal@absl@@QAE@XZ @@ -1148,6 +1193,7 @@ ??6absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV123@Vuint128@0@@Z ??6absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV123@W4LogSeverity@0@@Z ??6absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV234@ABVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV456@ABV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV456@ABV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV456@ABV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -1203,6 +1249,7 @@ ??B?$unique_ptr@VTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBE_NXZ ??B?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBE_NXZ ??BCord@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ + ??BCordRepRingReader@cord_internal@absl@@QBE_NXZ ??BTimeZone@absl@@QBE?AVtime_zone@cctz@time_internal@1@XZ ??Bint128@absl@@QBEEXZ ??Bint128@absl@@QBENXZ @@ -1286,6 +1333,10 @@ ??Pabsl@@YA_NVDuration@0@0@Z ??Pabsl@@YA_NVint128@0@0@Z ??Pabsl@@YA_NVuint128@0@0@Z + ??R<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@0II@Z@QBE?A?<auto>@@I@Z + ??R<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@0II@Z@QBE?A?<auto>@@I@Z + ??R<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AAEXPBV123@II@Z@QBE?A?<auto>@@I@Z + ??R<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AAEXPBV123@II@Z@QBE?A?<auto>@@I@Z ??R<lambda_1>@?0???A?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEAAPAUCordRep@cord_internal@2@I@Z@QBE?A?<auto>@@XZ ??R<lambda_1>@?0???A?$InlinedVector@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEAAPAUCordRep@cord_internal@2@I@Z@QBE?A?<auto>@@XZ ??R<lambda_1>@?0???A?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEAAUPayload@status_internal@2@I@Z@QBE?A?<auto>@@XZ @@ -1314,8 +1365,11 @@ ??R<lambda_1>@?0??pop_back@?$InlinedVector@PBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEXXZ@QBE?A?<auto>@@XZ ??R<lambda_1>@?0??pop_back@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QAEXXZ@QBE?A?<auto>@@XZ ??R<lambda_1>@?0??remove_prefix@string_view@absl@@QAEXI@Z@QBE?A?<auto>@@XZ + ??R<lambda_1>@?0??remove_suffix@string_view@absl@@QAEXI@Z@QBE?A?<auto>@@XZ ??R<lambda_1>@?0??replace_tree@InlineRep@Cord@absl@@QAEXPAUCordRep@cord_internal@4@@Z@QBE?A?<auto>@@XZ ??R<lambda_1>@?0??set_inline_size@InlineData@cord_internal@absl@@QAEXI@Z@QBE?A?<auto>@@XZ + ??R<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@0II@Z@QBE?A?<auto>@@I@Z + ??R<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@0II@Z@QBE?A?<auto>@@I@Z ??R<lambda_2>@?0??erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEPAUPayload@status_internal@3@PBU453@@Z@QBE?A?<auto>@@XZ ??R?$FunctionRef@$$A6AXV?$Span@I@absl@@@Z@absl@@QBEXV?$Span@I@1@@Z ??R?$FunctionRef@$$A6AXVstring_view@absl@@@Z@absl@@QBEXVstring_view@1@@Z @@ -1383,6 +1437,8 @@ ?AcquireAllocatedData@?$Storage@PBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAV?$AllocationTransaction@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@23@@Z ?AcquireAllocatedData@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAV?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@23@@Z ?AcquireAllocatedData@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAV?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@23@@Z + ?Add@Filler@CordRepRing@cord_internal@absl@@QAEXPAUCordRep@34@II@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AAEXII@Z ?AddNode@CordForest@absl@@AAEXPAUCordRep@cord_internal@2@@Z ?AddSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEXI@Z ?AddSize@?$Storage@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXI@Z @@ -1397,9 +1453,14 @@ ?AddressIsReadable@debugging_internal@absl@@YA_NPBX@Z ?AdvanceAndReadBytes@ChunkIterator@Cord@absl@@AAE?AV23@I@Z ?AdvanceBytes@ChunkIterator@Cord@absl@@AAEXI@Z + ?AdvanceBytesRing@ChunkIterator@Cord@absl@@AAEXI@Z ?AdvanceBytesSlowPath@ChunkIterator@Cord@absl@@AAEXI@Z + ?AdvanceRing@ChunkIterator@Cord@absl@@AAEAAV123@XZ ?AdvanceStack@ChunkIterator@Cord@absl@@AAEAAV123@XZ + ?Align@adl_barrier@internal_layout@container_internal@absl@@YAIII@Z ?Alloc@LowLevelAlloc@base_internal@absl@@SAPAXI@Z + ?AllocSize@?$LayoutImpl@V?$tuple@IPAUCordRep@cord_internal@absl@@I@__1@std@@U?$integer_sequence@I$0A@$00$01@absl@@U45@@internal_layout@container_internal@absl@@QBEIXZ + ?AllocSize@CordRepRing@cord_internal@absl@@SAII@Z ?AllocWithArena@LowLevelAlloc@base_internal@absl@@SAPAXIPAUArena@123@@Z ?Allocate@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEPAHI@Z ?Allocate@?$AllocationTransaction@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEPAPAUCordRep@cord_internal@3@I@Z @@ -1408,20 +1469,24 @@ ?Allocate@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEPAUSubRange@3@I@Z ?AllocatedSize@CordRepFlat@cord_internal@absl@@QBEIXZ ?AllocatedSizeToTag@cord_internal@absl@@YAEI@Z - ?AllocatedSizeToTagUnchecked@cord_internal@absl@@YAII@Z + ?AllocatedSizeToTagUnchecked@cord_internal@absl@@YAEI@Z ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?AnnotateConstruct@NonEmptyInlinedStorage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEXI@Z ?AnnotateDestruct@NonEmptyInlinedStorage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEXI@Z ?Append@Cord@absl@@QAEX$$QAV12@@Z ?Append@Cord@absl@@QAEXABV12@@Z ?Append@Cord@absl@@QAEXVstring_view@2@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@PAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@Vstring_view@3@I@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QAEXID@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QAEXVstring_view@3@@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QAEXPBDI@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@II@Z ?AppendNode@CordForest@absl@@AAEPAUCordRep@cord_internal@2@PAU342@0@Z ?AppendPack@str_format_internal@absl@@YAAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@@Z ?AppendText@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAEIVstring_view@4@@Z ?AppendTree@InlineRep@Cord@absl@@QAEXPAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z @@ -1506,10 +1571,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NOABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NABUUnboundConversion@34@Vstring_view@4@@Z ?ConvertSpecialToEmptyAndFullToDeleted@GroupSse2Impl@container_internal@absl@@QBEXPAC@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@III@Z ?CopyCordToString@absl@@YAXABVCord@1@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QBEXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@ABEXPAD@Z ?Crash@Helper@internal_statusor@absl@@SAXABVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPAV123@PAUCordRep@23@I@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPAV123@PAUCordRep@23@III@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPAV123@PAUCordRep@23@I@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPAUThreadIdentity@12@XZ ?Data@CordRepFlat@cord_internal@absl@@QAEPADXZ @@ -1532,13 +1601,16 @@ ?DefaultStackUnwinder@absl@@YAHPAPAXPAHHHPBX1@Z ?Delete@CordRepExternal@cord_internal@absl@@SAXPAUCordRep@23@@Z ?Delete@CordRepFlat@cord_internal@absl@@SAXPAUCordRep@23@@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPBDPADH@Z ?Description@Impl@time_zone@cctz@time_internal@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneInfo@cctz@time_internal@absl@@UBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Destroy@CordRep@cord_internal@absl@@SAXPAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AAEXXZ ?DestroyCordSlow@Cord@absl@@AAEXXZ ?DidAllocate@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAE_NXZ ?DidAllocate@?$AllocationTransaction@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAE_NXZ @@ -1548,6 +1620,7 @@ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ ?DisableRescheduling@SchedulingGuard@base_internal@absl@@CA_NXZ + ?Distance@CordRepRing@cord_internal@absl@@SAIII@Z ?DivUp@cord_internal@absl@@YAIII@Z ?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@Vstring_view@2@ABVCord@2@@Z@base_internal@absl@@ABEP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@3@Vstring_view@3@ABVCord@3@@ZXZ ?DoLoad@?$AtomicHook@P6AXPBDH000@Z@base_internal@absl@@ABEP6AXPBDH000@ZXZ @@ -1611,8 +1684,14 @@ ?Find@ByChar@absl@@QBE?AVstring_view@2@V32@I@Z ?Find@ByLength@absl@@QBE?AVstring_view@2@V32@I@Z ?Find@ByString@absl@@QBE?AVstring_view@2@V32@I@Z + ?Find@CordRepRing@cord_internal@absl@@QBE?AUPosition@123@I@Z + ?Find@CordRepRing@cord_internal@absl@@QBE?AUPosition@123@II@Z ?FindFlatStartPiece@InlineRep@Cord@absl@@QBE?AVstring_view@3@XZ ?FindPath@GraphCycles@synchronization_internal@absl@@QBEHUGraphId@23@0HQAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@ABE?AUPosition@123@II@Z + ?FindTail@CordRepRing@cord_internal@absl@@QBE?AUPosition@123@I@Z + ?FindTail@CordRepRing@cord_internal@absl@@QBE?AUPosition@123@II@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@ABE?AUPosition@123@II@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -1705,6 +1784,7 @@ ?GetAllocator@?$AllocationTransaction@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAV?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@XZ ?GetAllocator@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAV?$allocator@UPayload@status_internal@absl@@@__1@std@@XZ ?GetAllocator@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAV?$allocator@USubRange@absl@@@__1@std@@XZ + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QAE?AV?$Span@D@3@I@Z ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAI@Z ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAII@Z ?GetCachedTID@base_internal@absl@@YAIXZ @@ -1713,6 +1793,7 @@ ?GetCapacity@?$AllocationTransaction@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAIXZ ?GetCapacity@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAIXZ ?GetCapacity@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAIXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QBEDI@Z ?GetCond@WinHelper@Waiter@synchronization_internal@absl@@SAPAU_RTL_CONDITION_VARIABLE@@PAV234@@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetData@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEAAPAHXZ @@ -1743,12 +1824,15 @@ ?GetIsAllocated@?$Storage@PBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QBE_NXZ ?GetIsAllocated@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QBE_NXZ ?GetIsAllocated@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QBE_NXZ + ?GetLeafData@CordRepRing@cord_internal@absl@@SAPBDPBUCordRep@23@@Z ?GetLock@WinHelper@Waiter@synchronization_internal@absl@@SAPAU_RTL_SRWLOCK@@PAV234@@Z ?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPAUThreadIdentity@base_internal@2@XZ ?GetPayload@Status@absl@@QBE?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z ?GetPayloads@Status@absl@@AAEPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@2@XZ ?GetPayloads@Status@absl@@ABEPBV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@2@XZ + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QAE?AV?$Span@D@3@I@Z ?GetProgramCounter@debugging_internal@absl@@YAPAXPAX@Z + ?GetRepData@CordRepRing@cord_internal@absl@@SAPBDPBUCordRep@23@@Z ?GetRepHi@time_internal@absl@@YA_JVDuration@2@@Z ?GetRepLo@time_internal@absl@@YAIVDuration@2@@Z ?GetSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QBEIXZ @@ -1807,6 +1891,7 @@ ?InfiniteFuture@absl@@YA?AVTime@1@XZ ?InfinitePast@absl@@YA?AVTime@1@XZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXABV123@@Z ?InitTree@ChunkIterator@Cord@absl@@AAEXPAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AAEXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PAUCordRepExternal@12@@Z @@ -1848,7 +1933,9 @@ ?IsUnavailable@absl@@YA_NABVStatus@1@@Z ?IsUnimplemented@absl@@YA_NABVStatus@1@@Z ?IsUnknown@absl@@YA_NABVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QBE_NAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?IsValidCapacity@container_internal@absl@@YA_NI@Z + ?IsValidIndex@CordRepRing@cord_internal@absl@@ABE_NI@Z ?Iterate@HashtablezSampler@container_internal@absl@@QAE_JABV?$function@$$A6AXABUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAEI@Z @@ -1912,14 +1999,17 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QAEXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AAEXHPBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AAEXHPBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@I@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?Name@Impl@time_zone@cctz@time_internal@absl@@QBEABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Nanoseconds@absl@@YA?AVDuration@1@_J@Z ?NegateAndSubtractOne@time_internal@absl@@YA_J_J@Z ?Never@KernelTimeout@synchronization_internal@absl@@SA?AV123@XZ ?New@CordRepFlat@cord_internal@absl@@SAPAU123@I@Z + ?New@CordRepRing@cord_internal@absl@@CAPAV123@II@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPAUArena@123@H@Z ?NewRep@Status@absl@@CAIW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QAE?AVstring_view@3@XZ ?NextCapacity@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@SAII@Z ?NextCapacity@?$Storage@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@SAII@Z ?NextCapacity@?$Storage@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@SAII@Z @@ -1973,7 +2063,11 @@ ?PrepareToModify@Status@absl@@AAEXXZ ?Prepend@Cord@absl@@QAEXABV12@@Z ?Prepend@Cord@absl@@QAEXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@PAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@Vstring_view@3@I@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@II@Z ?PrependNode@CordForest@absl@@AAEPAUCordRep@cord_internal@2@PAU342@0@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QAEXPAUCordRep@cord_internal@3@@Z ?PrevTransition@Impl@time_zone@cctz@time_internal@absl@@QBE_NABV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PAUcivil_transition@2345@@Z ?PrevTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z @@ -2022,13 +2116,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QAEXPAX@Z ?RemovePrefix@Cord@absl@@QAEXI@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@II@Z ?RemoveSuffix@Cord@absl@@QAEXI@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@II@Z ?RepToPointer@Status@absl@@CAPAUStatusRep@status_internal@2@I@Z ?Reset@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEXXZ ?Reset@?$AllocationTransaction@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXXZ ?Reset@?$AllocationTransaction@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXXZ ?Reset@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXXZ ?Reset@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXXZ + ?Reset@CordRepRingReader@cord_internal@absl@@QAE?AVstring_view@3@PAVCordRepRing@23@@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AAE_NABV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResetToEmpty@InlineRep@Cord@absl@@AAEXXZ ?Resize@?$ResizeUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@I@Z @@ -2039,12 +2136,14 @@ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPBDI@Z ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@PA_J@Z ?Seconds@absl@@YA?AVDuration@1@_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QAE?AVstring_view@3@I@Z ?SetAllocatedData@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEXPAHI@Z ?SetAllocatedData@?$Storage@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAPAUCordRep@cord_internal@3@I@Z ?SetAllocatedData@?$Storage@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAPAUCordRep@cord_internal@3@I@Z ?SetAllocatedData@?$Storage@PBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAPBUCordRep@cord_internal@3@I@Z ?SetAllocatedData@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAUPayload@status_internal@3@I@Z ?SetAllocatedData@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXPAUSubRange@3@I@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QAEXI@Z ?SetConversionChar@FormatConversionSpecImplFriend@str_format_internal@absl@@SAXW4FormatConversionChar@3@PAVFormatConversionSpecImpl@23@@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPAUThreadIdentity@12@P6AXPAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QAEP6AXABUHashtablezInfo@23@@ZP6AX0@Z@Z @@ -2116,6 +2215,8 @@ ?StripLeadingAsciiWhitespace@absl@@YA?AVstring_view@1@V21@@Z ?StripTrailingAsciiWhitespace@absl@@YA?AVstring_view@1@V21@@Z ?StrlenInternal@string_view@absl@@CAIPBD@Z + ?SubLength@CordRepRing@cord_internal@absl@@AAEXII@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@III@Z ?Subcord@Cord@absl@@QBE?AV12@II@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PBV62@I@Z ?SubtractSize@?$Storage@H$0CP@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEXI@Z @@ -2239,6 +2340,7 @@ ?UsingInlinedStorage@Storage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@CA_NI@Z ?Utf8SafeCEscape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@@Z ?Utf8SafeCHexEscape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@@Z + ?Validate@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PBDH@Z ?Value@?$Manager@C$01@FormatArgImpl@str_format_internal@absl@@SACTData@234@@Z ?Value@?$Manager@D$01@FormatArgImpl@str_format_internal@absl@@SADTData@234@@Z ?Value@?$Manager@E$01@FormatArgImpl@str_format_internal@absl@@SAETData@234@@Z @@ -2507,6 +2609,8 @@ ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z ?__vdeallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AAEXXZ ?_mm_cmpgt_epi8_fixed@container_internal@absl@@YA?AT__m128i@@T3@0@Z + ?advance@CordRepRing@cord_internal@absl@@QBEII@Z + ?advance@CordRepRing@cord_internal@absl@@QBEIII@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uday_tag@1234@U51234@@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uhour_tag@1234@U51234@@Z ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uminute_tag@1234@U51234@@Z @@ -2611,6 +2715,7 @@ ?capacity@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEIXZ ?capacity@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QBEIXZ ?capacity@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QBEIXZ + ?capacity@CordRepRing@cord_internal@absl@@QBEIXZ ?chunk_begin@Cord@absl@@QBE?AVChunkIterator@12@XZ ?chunk_end@Cord@absl@@QBE?AVChunkIterator@12@XZ ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXXZ @@ -2633,6 +2738,7 @@ ?compare_exchange_weak@?$__atomic_base@PAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QAE_NAAPAUHashtablezInfo@container_internal@absl@@PAU456@W4memory_order@23@2@Z ?concat@CordRep@cord_internal@absl@@QAEPAUCordRepConcat@23@XZ ?concat@CordRep@cord_internal@absl@@QBEPBUCordRepConcat@23@XZ + ?consumed@CordRepRingReader@cord_internal@absl@@QBEIXZ ?conversion_char@FormatConversionSpecImpl@str_format_internal@absl@@QBE?AW4FormatConversionChar@3@XZ ?cord_ring_buffer_enabled@cord_internal@absl@@3U?$atomic@_N@__1@std@@A ?count@FILERawSink@str_format_internal@absl@@QBEIXZ @@ -2645,6 +2751,7 @@ ?data@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QBEPBUPayload@status_internal@2@XZ ?data@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QAEPAUSubRange@2@XZ ?data@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QBEPBVFormatArgImpl@str_format_internal@2@XZ + ?data@?$Span@D@absl@@QBEPADXZ ?data@?$Span@I@absl@@QBEPAIXZ ?data@?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QBEPAVFormatArgImpl@str_format_internal@2@XZ ?data@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QBEPBQAUCordRep@cord_internal@absl@@XZ @@ -2717,6 +2824,7 @@ ?empty@?$InlinedVector@PBUCordRep@cord_internal@absl@@$0CP@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@absl@@QBE_NXZ ?empty@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QBE_NXZ ?empty@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QBE_NXZ + ?empty@?$Span@D@absl@@QBE_NXZ ?empty@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBE_NXZ ?empty@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QBE_NXZ ?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QBE_NXZ @@ -2742,6 +2850,19 @@ ?end@ChunkRange@Cord@absl@@QBE?AVChunkIterator@23@XZ ?end@Storage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QBEPAPAUCordRep@cord_internal@3@XZ ?end@string_view@absl@@QBEPBDXZ + ?entries@CordRepRing@cord_internal@absl@@QBEIII@Z + ?entries@CordRepRing@cord_internal@absl@@QBEIXZ + ?entry_begin_pos@CordRepRing@cord_internal@absl@@QBEABII@Z + ?entry_child@CordRepRing@cord_internal@absl@@AAEPAPAUCordRep@23@XZ + ?entry_child@CordRepRing@cord_internal@absl@@QBEABQAUCordRep@23@I@Z + ?entry_data@CordRepRing@cord_internal@absl@@QBE?AVstring_view@3@I@Z + ?entry_data_offset@CordRepRing@cord_internal@absl@@AAEPAIXZ + ?entry_data_offset@CordRepRing@cord_internal@absl@@QBEABII@Z + ?entry_end_offset@CordRepRing@cord_internal@absl@@QBEII@Z + ?entry_end_pos@CordRepRing@cord_internal@absl@@AAEPAIXZ + ?entry_end_pos@CordRepRing@cord_internal@absl@@QBEABII@Z + ?entry_length@CordRepRing@cord_internal@absl@@QBEII@Z + ?entry_start_offset@CordRepRing@cord_internal@absl@@QBEII@Z ?erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEPAUPayload@status_internal@2@PBU342@@Z ?error@FILERawSink@str_format_internal@absl@@QBEHXZ ?exchange@?$__atomic_base@P6AXABUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QAEP6AXABUHashtablezInfo@container_internal@absl@@@ZP6AX0@ZW4memory_order@23@@Z @@ -2859,6 +2980,8 @@ ?has_value@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@QBE_NXZ ?has_zero_flag@FormatConversionSpecImpl@str_format_internal@absl@@QBE_NXZ ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ + ?head@CordRepRing@cord_internal@absl@@QBEIXZ + ?head@Filler@CordRepRing@cord_internal@absl@@QBEIXZ ?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ ?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ ?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ @@ -2873,6 +2996,8 @@ ?is_tree@InlineData@cord_internal@absl@@QBE_NXZ ?is_tree@InlineRep@Cord@absl@@QBE_NXZ ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ + ?length@?$Span@D@absl@@QBEIXZ + ?length@CordRepRingReader@cord_internal@absl@@QBEIXZ ?length@string_view@absl@@QBEIXZ ?load@?$__atomic_base@P6AXABUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QBEP6AXABUHashtablezInfo@container_internal@absl@@@ZW4memory_order@23@@Z ?load@?$__atomic_base@PAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QBEPAUHashtablezInfo@container_internal@absl@@W4memory_order@23@@Z @@ -2955,6 +3080,7 @@ ?pop_back@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QAEXXZ ?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QAEXXZ ?pop_front@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXXZ + ?pos@Filler@CordRepRing@cord_internal@absl@@QBEIXZ ?precision@FormatConversionSpecImpl@str_format_internal@absl@@QBEHXZ ?prev_transition@time_zone@cctz@time_internal@absl@@QBE_NABV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PAUcivil_transition@1234@@Z ?prev_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z @@ -2984,8 +3110,10 @@ ?release@?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@__1@std@@QAEPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@23@XZ ?release@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAEPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@XZ ?release@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEPAVTimeZoneInfo@cctz@time_internal@absl@@XZ + ?remaining@CordRepRingReader@cord_internal@absl@@QBEIXZ ?remove_prefix@InlineRep@Cord@absl@@QAEXI@Z ?remove_prefix@string_view@absl@@QAEXI@Z + ?remove_suffix@string_view@absl@@QAEXI@Z ?rend@string_view@absl@@QBE?AV?$reverse_iterator@PBD@__1@std@@XZ ?replace_tree@InlineRep@Cord@absl@@QAEXPAUCordRep@cord_internal@3@@Z ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z @@ -3001,9 +3129,13 @@ ?reset@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXPAVZoneInfoSource@cctz@time_internal@absl@@@Z ?resize@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z ?resize@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z + ?retreat@CordRepRing@cord_internal@absl@@QBEII@Z + ?retreat@CordRepRing@cord_internal@absl@@QBEIII@Z ?rfind@string_view@absl@@QBEIDI@Z ?rfind@string_view@absl@@QBEIV12@I@Z ?ring@CordRep@cord_internal@absl@@QAEPAVCordRepRing@23@XZ + ?ring@CordRep@cord_internal@absl@@QBEPBVCordRepRing@23@XZ + ?ring@CordRepRingReader@cord_internal@absl@@QBEPAVCordRepRing@23@XZ ?safe_strto128_base@numbers_internal@absl@@YA_NVstring_view@2@PAVint128@2@H@Z ?safe_strto32_base@numbers_internal@absl@@YA_NVstring_view@2@PAHH@Z ?safe_strto64_base@numbers_internal@absl@@YA_NVstring_view@2@PA_JH@Z @@ -3068,6 +3200,7 @@ ?size@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QBEIXZ ?size@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QBEIXZ ?size@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QBEIXZ + ?size@?$Span@D@absl@@QBEIXZ ?size@?$Span@I@absl@@QBEIXZ ?size@?$Span@VFormatArgImpl@str_format_internal@absl@@@absl@@QBEIXZ ?size@?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QAEAAIXZ @@ -3102,6 +3235,7 @@ ?substring@CordRep@cord_internal@absl@@QBEPBUCordRepSubstring@23@XZ ?tag@InlineData@cord_internal@absl@@AAEAADXZ ?tag@InlineData@cord_internal@absl@@ABEDXZ + ?tail@CordRepRing@cord_internal@absl@@QBEIXZ ?thread_identity@PerThreadSynch@base_internal@absl@@QAEPAUThreadIdentity@23@XZ ?throw_bad_optional_access@optional_internal@absl@@YAXXZ ?total_written@BufferRawSink@str_format_internal@absl@@QBEIXZ
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def index e938a24d..0c67af2f 100644 --- a/third_party/abseil-cpp/symbols_x86_rel.def +++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -4,6 +4,8 @@ ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z ??$?RW4LogSeverity@absl@@ABQBDHAAPBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@ABQBD$$QAHAAPBD@Z + ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV012@PAV012@0II@Z + ??$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV012@PAV012@0II@Z ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ??$AppendImpl@ABVCord@absl@@@Cord@absl@@AAEXABV01@@Z ??$AppendImpl@VCord@absl@@@Cord@absl@@AAEX$$QAV01@@Z @@ -44,16 +46,23 @@ ??$EmplaceBackSlow@PAUCordRep@cord_internal@absl@@@?$Storage@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AAEAAPAUCordRep@cord_internal@2@$$QAPAU342@@Z ??$EmplaceBackSlow@UPayload@status_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AAEAAUPayload@status_internal@2@$$QAU342@@Z ??$EmplaceBackSlow@USubRange@absl@@@?$Storage@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@AAEAAUSubRange@2@$$QAU32@@Z + ??$Fill@$00@CordRepRing@cord_internal@absl@@AAEXPBV012@II@Z + ??$Fill@$0A@@CordRepRing@cord_internal@absl@@AAEXPBV012@II@Z ??$FindSubstitutions@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@strings_internal@absl@@YA?AV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@Vstring_view@1@ABV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ??$Flush@V?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z ??$Flush@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z ??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z ??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPAXVstring_view@2@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$AddRing@$00@012@CAPAV012@PAV012@0II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$AddRing@$0A@@012@CAPAV012@PAV012@0II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$00@CordRepRing@cord_internal@absl@@AAEXPBV234@II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$Fill@$00@012@AAEXPBV012@II@Z@@Z + ??$ForEach@V<lambda_1>@?0???$Fill@$0A@@CordRepRing@cord_internal@absl@@AAEXPBV234@II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_1>@?0???$Fill@$0A@@012@AAEXPBV012@II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_2>@?0???$AddRing@$00@012@CAPAV012@PAV012@0II@Z@@Z + ??$ForEach@V<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV234@PAV234@0II@Z@@CordRepRing@cord_internal@absl@@QBEXII$$QAV<lambda_2>@?0???$AddRing@$0A@@012@CAPAV012@PAV012@0II@Z@@Z ??$GenericCompare@HVCord@absl@@@absl@@YAHABVCord@0@0I@Z ??$GenericCompare@HVstring_view@absl@@@absl@@YAHABVCord@0@ABVstring_view@0@I@Z ??$GenericCompare@_NVCord@absl@@@absl@@YA_NABVCord@0@0I@Z ??$GenericCompare@_NVstring_view@absl@@@absl@@YA_NABVCord@0@ABVstring_view@0@I@Z - ??$Initialize@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PBUPayload@status_internal@absl@@@12@I@Z ??$NewExternalRep@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@cord_internal@absl@@YAPAUCordRep@01@Vstring_view@1@$$QAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@1@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z ??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PBD0W4chars_format@1@@Z ??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PBD0W4chars_format@1@@Z @@ -117,7 +126,6 @@ ??0uint128@absl@@QAE@M@Z ??0uint128@absl@@QAE@N@Z ??0uint128@absl@@QAE@O@Z - ??1?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAE@XZ ??1BadStatusOrAccess@absl@@UAE@XZ ??1CondVar@absl@@QAE@XZ ??1GraphCycles@synchronization_internal@absl@@QAE@XZ @@ -139,6 +147,7 @@ ??6absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV123@Vuint128@0@@Z ??6absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV123@W4LogSeverity@0@@Z ??6absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV123@W4StatusCode@0@@Z + ??6cord_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV234@ABVCordRepRing@01@@Z ??6detail@cctz@time_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV456@ABV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV456@ABV?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@0123@@Z ??6detail@cctz@time_internal@absl@@YAAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@AAV456@ABV?$civil_time@Uminute_tag@detail@cctz@time_internal@absl@@@0123@@Z @@ -177,6 +186,7 @@ ?AbslParseFlag@absl@@YA_NVstring_view@1@PAVTime@1@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VDuration@1@@Z ?AbslUnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VTime@1@@Z + ?AddDataOffset@CordRepRing@cord_internal@absl@@AAEXII@Z ?AddNode@CordForest@absl@@AAEXPAUCordRep@cord_internal@2@@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AAEXHI@Z ?AddWithCarry@?$BigUnsigned@$03@strings_internal@absl@@AAEXH_K@Z @@ -191,12 +201,16 @@ ?AlreadyExistsError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Append@Cord@absl@@QAEX$$QAV12@@Z ?Append@Cord@absl@@QAEXABV12@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@PAUCordRep@23@@Z + ?Append@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@Vstring_view@3@I@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QAEXID@Z ?Append@FormatSinkImpl@str_format_internal@absl@@QAEXVstring_view@3@@Z ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NVstring_view@4@@Z ?AppendArray@InlineRep@Cord@absl@@QAEXPBDI@Z + ?AppendLeaf@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@II@Z ?AppendPack@str_format_internal@absl@@YAAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PAV345@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z ?AppendPieces@strings_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$initializer_list@Vstring_view@absl@@@5@@Z + ?AppendSlow@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@@Z ?AppendTree@InlineRep@Cord@absl@@QAEXPAUCordRep@cord_internal@3@@Z ?ApplySubstitutions@strings_internal@absl@@YAHVstring_view@2@PAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@56@@Z ?AsciiStrToLower@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z @@ -257,10 +271,14 @@ ?ConvertFloatImpl@str_format_internal@absl@@YA_NNABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z ?ConvertFloatImpl@str_format_internal@absl@@YA_NOABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NABUUnboundConversion@34@Vstring_view@4@@Z + ?Copy@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@III@Z ?CopyCordToString@absl@@YAXABVCord@1@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyTo@InlineRep@Cord@absl@@QBEXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?CopyToArraySlowPath@Cord@absl@@ABEXPAD@Z ?Crash@Helper@internal_statusor@absl@@SAXABVStatus@3@@Z + ?Create@CordRepRing@cord_internal@absl@@SAPAV123@PAUCordRep@23@I@Z + ?CreateFromLeaf@CordRepRing@cord_internal@absl@@CAPAV123@PAUCordRep@23@III@Z + ?CreateSlow@CordRepRing@cord_internal@absl@@CAPAV123@PAUCordRep@23@I@Z ?CreateThreadIdentity@synchronization_internal@absl@@YAPAUThreadIdentity@base_internal@2@XZ ?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPAUThreadIdentity@12@XZ ?DataLength@Header@TimeZoneInfo@cctz@time_internal@absl@@QBEII@Z @@ -270,12 +288,15 @@ ?DecrementCount@BlockingCounter@absl@@QAE_NXZ ?DefaultArena@LowLevelAlloc@base_internal@absl@@SAPAUArena@123@XZ ?DefaultStackUnwinder@absl@@YAHPAPAXPAHHHPBX1@Z + ?Delete@CordRepRing@cord_internal@absl@@CAXPAV123@@Z ?DeleteArena@LowLevelAlloc@base_internal@absl@@SA_NPAUArena@123@@Z ?Demangle@debugging_internal@absl@@YA_NPBDPADH@Z ?Description@TimeZoneInfo@cctz@time_internal@absl@@UBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Description@TimeZoneLibC@cctz@time_internal@absl@@UBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ ?Destroy@CordRep@cord_internal@absl@@SAXPAU123@@Z + ?Destroy@CordRepRing@cord_internal@absl@@CAXPAV123@@Z ?Destroy@PerThreadSem@synchronization_internal@absl@@CAXPAUThreadIdentity@base_internal@3@@Z + ?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@AAEXXZ ?DestroyCordSlow@Cord@absl@@AAEXXZ ?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ ?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ @@ -321,6 +342,8 @@ ?Find@ByLength@absl@@QBE?AVstring_view@2@V32@I@Z ?Find@ByString@absl@@QBE?AVstring_view@2@V32@I@Z ?FindPath@GraphCycles@synchronization_internal@absl@@QBEHUGraphId@23@0HQAU423@@Z + ?FindSlow@CordRepRing@cord_internal@absl@@ABE?AUPosition@123@II@Z + ?FindTailSlow@CordRepRing@cord_internal@absl@@ABE?AUPosition@123@II@Z ?FiveToTheNth@?$BigUnsigned@$03@strings_internal@absl@@SA?AV123@H@Z ?FiveToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@SA?AV123@H@Z ?FixedOffsetFromName@cctz@time_internal@absl@@YA_NABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PAV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@56@@Z @@ -374,13 +397,16 @@ ?FromTM@absl@@YA?AVTime@1@ABUtm@@VTimeZone@1@@Z ?FromUDate@absl@@YA?AVTime@1@N@Z ?FromUniversal@absl@@YA?AVTime@1@_J@Z + ?GetAppendBuffer@CordRepRing@cord_internal@absl@@QAE?AV?$Span@D@3@I@Z ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAI@Z ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAII@Z ?GetCachedTID@base_internal@absl@@YAIXZ + ?GetCharacter@CordRepRing@cord_internal@absl@@QBEDI@Z ?GetCurrentTimeNanos@absl@@YA_JXZ ?GetFlatAux@Cord@absl@@CA_NPAUCordRep@cord_internal@2@PAVstring_view@2@@Z ?GetId@GraphCycles@synchronization_internal@absl@@QAE?AUGraphId@23@PAX@Z ?GetPayload@Status@absl@@QBE?AV?$optional@VCord@absl@@@2@Vstring_view@2@@Z + ?GetPrependBuffer@CordRepRing@cord_internal@absl@@QAE?AV?$Span@D@3@I@Z ?GetProgramCounter@debugging_internal@absl@@YAPAXPAX@Z ?GetSkipCount@ExponentialBiased@base_internal@absl@@QAE_J_J@Z ?GetStackFrames@absl@@YAHPAPAXPAHHH@Z @@ -406,6 +432,8 @@ ?In@Time@absl@@QBE?AUBreakdown@12@VTimeZone@2@@Z ?InMillisecondsFromNow@KernelTimeout@synchronization_internal@absl@@ABEKXZ ?Init@PerThreadSem@synchronization_internal@absl@@CAXPAUThreadIdentity@base_internal@3@@Z + ?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEXABV123@@Z + ?InitTree@ChunkIterator@Cord@absl@@AAEXPAUCordRep@cord_internal@3@@Z ?Initialize@ExponentialBiased@base_internal@absl@@AAEXXZ ?InitializeCordRepExternal@cord_internal@absl@@YAXVstring_view@2@PAUCordRepExternal@12@@Z ?InitializeData@Storage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@AAEPAPAUCordRep@cord_internal@3@XZ @@ -433,6 +461,7 @@ ?IsUnavailable@absl@@YA_NABVStatus@1@@Z ?IsUnimplemented@absl@@YA_NABVStatus@1@@Z ?IsUnknown@absl@@YA_NABVStatus@1@@Z + ?IsValid@CordRepRing@cord_internal@absl@@QBE_NAAV?$basic_ostream@DU?$char_traits@D@__1@std@@@__1@std@@@Z ?Iterate@HashtablezSampler@container_internal@absl@@QAE_JABV?$function@$$A6AXABUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@Z ?LengthModToString@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@W4LengthMod@12@@Z ?LengthToTag@CordTestAccess@strings_internal@absl@@SAEI@Z @@ -469,10 +498,13 @@ ?MultiplyByTenToTheNth@?$BigUnsigned@$0FE@@strings_internal@absl@@QAEXH@Z ?MultiplyStep@?$BigUnsigned@$03@strings_internal@absl@@AAEXHPBIHH@Z ?MultiplyStep@?$BigUnsigned@$0FE@@strings_internal@absl@@AAEXHPBIHH@Z + ?Mutable@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@I@Z ?MutexDelay@synchronization_internal@absl@@YAHHH@Z ?New@CordRepFlat@cord_internal@absl@@SAPAU123@I@Z + ?New@CordRepRing@cord_internal@absl@@CAPAV123@II@Z ?NewArena@LowLevelAlloc@base_internal@absl@@SAPAUArena@123@H@Z ?NewRep@Status@absl@@CAIW4StatusCode@2@Vstring_view@2@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@Z + ?Next@CordRepRingReader@cord_internal@absl@@QAE?AVstring_view@3@XZ ?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z ?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PAUcivil_transition@time_zone@234@@Z ?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PAUcivil_transition@time_zone@234@@Z @@ -510,6 +542,10 @@ ?PrepareToModify@Status@absl@@AAEXXZ ?Prepend@Cord@absl@@QAEXABV12@@Z ?Prepend@Cord@absl@@QAEXVstring_view@2@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@PAUCordRep@23@@Z + ?Prepend@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@Vstring_view@3@I@Z + ?PrependLeaf@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@II@Z + ?PrependSlow@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@PAUCordRep@23@@Z ?PrependTree@InlineRep@Cord@absl@@QAEXPAUCordRep@cord_internal@3@@Z ?PrevTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z ?PrevTransition@TimeZoneInfo@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__1@std@@V?$duration@_JV?$ratio@$00$00@__1@std@@@234@@chrono@__1@std@@PAUcivil_transition@time_zone@234@@Z @@ -550,12 +586,16 @@ ?RemoveExtraAsciiWhitespace@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z ?RemoveNode@GraphCycles@synchronization_internal@absl@@QAEXPAX@Z ?RemovePrefix@Cord@absl@@QAEXI@Z + ?RemovePrefix@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@II@Z ?RemoveSuffix@Cord@absl@@QAEXI@Z + ?RemoveSuffix@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@II@Z ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AAE_NABV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z ?Rethrow@variant_internal@absl@@YAXXZ ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPBDI@Z ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@PA_J@Z + ?Seek@CordRepRingReader@cord_internal@absl@@QAE?AVstring_view@3@I@Z + ?SetCapacityForTesting@CordRepRing@cord_internal@absl@@QAEXI@Z ?SetCurrentThreadIdentity@base_internal@absl@@YAXPAUThreadIdentity@12@P6AXPAX@Z@Z ?SetDisposeCallback@HashtablezSampler@container_internal@absl@@QAEP6AXABUHashtablezInfo@23@@ZP6AX0@Z@Z ?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z @@ -598,6 +638,8 @@ ?StrCat@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@ABVAlphaNum@1@0@Z ?StrReplaceAll@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@1@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@4@@Z ?StrReplaceAll@absl@@YAHV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@3@@Z + ?SubLength@CordRepRing@cord_internal@absl@@AAEXII@Z + ?SubRing@CordRepRing@cord_internal@absl@@SAPAV123@PAV123@III@Z ?Subcord@Cord@absl@@QBE?AV12@II@Z ?SubstituteAndAppendArray@substitute_internal@absl@@YAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@2@PBV62@I@Z ?Summarize@str_format_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@VUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 53c170f..8c722ef0 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -5829,6 +5829,16 @@ # Style of the self-alignment line (align-items). optional LineStyle crossAlignment + # Configuration data for the highlighting of Flex item elements. + type FlexItemHighlightConfig extends object + properties + # Style of the box representing the item's base size + optional BoxStyle baseSizeBox + # Style of the border around the box representing the item's base size + optional LineStyle baseSizeBorder + # Style of the arrow representing if the item grew or shrank + optional LineStyle flexibilityArrow + # Style information for drawing a line. type LineStyle extends object properties @@ -5888,6 +5898,8 @@ optional GridHighlightConfig gridHighlightConfig # The flex container highlight configuration (default: all transparent). optional FlexContainerHighlightConfig flexContainerHighlightConfig + # The flex item highlight configuration (default: all transparent). + optional FlexItemHighlightConfig flexItemHighlightConfig # The contrast algorithm to use for the contrast ratio (default: aa). optional ContrastAlgorithm contrastAlgorithm
diff --git a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc index 29b193f..a08b2d3 100644 --- a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
@@ -24,7 +24,7 @@ const KURL js_url_b("https://example.com/b.js"); Member<BoxedV8Module> module_empty = nullptr; - Member<BoxedV8Module> module_deleted(WTF::kHashTableDeletedValue); + Member<BoxedV8Module> module_deleted(kMemberDeletedValue); v8::Local<v8::Module> local_module_a = ModuleTestBase::CompileModule( scope.GetIsolate(), "export const a = 'a';", js_url_a);
diff --git a/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc b/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc index 049a849..3b83f26a 100644 --- a/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc +++ b/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc
@@ -182,10 +182,10 @@ IsolatedWorldCSPDelegate* delegate = MakeGarbageCollected<IsolatedWorldCSPDelegate>( - window, std::move(self_origin), world_id, + window, self_origin, world_id, policy.IsEmpty() ? CSPType::kEmpty : CSPType::kNonEmpty); csp->BindToDelegate(*delegate); - csp->DidReceiveHeader(policy, + csp->DidReceiveHeader(policy, *self_origin, network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP);
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 1798b496..21d8a7a 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1637,12 +1637,6 @@ data_deps = [ ":unit_tests_data" ] - # FIXME: Enable mojo unittests on Android after fixing data dependency. - # crbug.com/741925 - if (!is_android) { - deps += [ "//third_party/blink/renderer/core/mojo:unit_tests" ] - } - if (!is_mac) { sources += [ "scroll/scroll_animator_test.cc",
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h index 2b658a6..509ab57 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.h +++ b/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -56,7 +56,7 @@ #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" #include "third_party/blink/renderer/platform/loader/fetch/https_state.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/core/execution_context/remote_security_context.cc b/third_party/blink/renderer/core/execution_context/remote_security_context.cc index 3c3f90b..08180f0 100644 --- a/third_party/blink/renderer/core/execution_context/remote_security_context.cc +++ b/third_party/blink/renderer/core/execution_context/remote_security_context.cc
@@ -29,13 +29,11 @@ scoped_refptr<SecurityOrigin> origin) { DCHECK(origin); SetSecurityOrigin(std::move(origin)); - GetContentSecurityPolicy()->SetupSelf(*GetSecurityOrigin()); } void RemoteSecurityContext::ResetReplicatedContentSecurityPolicy() { DCHECK(GetSecurityOrigin()); SetContentSecurityPolicy(MakeGarbageCollected<ContentSecurityPolicy>()); - GetContentSecurityPolicy()->SetupSelf(*GetSecurityOrigin()); } void RemoteSecurityContext::ResetAndEnforceSandboxFlags(
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc index 39f76ba..5ee3800 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h" +#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h" #include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h" #include "third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h"
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index 365ae1e..eb4839f 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -184,33 +184,9 @@ ApplyPolicySideEffectsToDelegate(); } -void ContentSecurityPolicy::SetupSelf(const SecurityOrigin& security_origin) { - // Ensure that 'self' processes correctly. - self_protocol_ = security_origin.Protocol(); - self_source_ = network::mojom::blink::CSPSource::New( - self_protocol_, security_origin.Host(), - security_origin.Port() == DefaultPortForProtocol(self_protocol_) - ? url::PORT_UNSPECIFIED - : security_origin.Port(), - "", /*is_host_wildcard=*/false, /*is_port_wildcard=*/false); -} - -void ContentSecurityPolicy::SetupSelf(const ContentSecurityPolicy& other) { - self_protocol_ = other.self_protocol_; - if (other.self_source_) { - self_source_ = other.self_source_.Clone(); - } -} - void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() { DCHECK(delegate_); - const SecurityOrigin* self_origin = - delegate_->GetSecurityOrigin()->GetOriginOrPrecursorOriginIfOpaque(); - DCHECK(self_origin); - - SetupSelf(*self_origin); - // Set mixed content checking and sandbox flags, then dump all the parsing // error messages, then poke at histograms. if (sandbox_mask_ != network::mojom::blink::WebSandboxFlags::kNone) { @@ -307,7 +283,6 @@ void ContentSecurityPolicy::CopyStateFrom(const ContentSecurityPolicy* other) { DCHECK(policies_.IsEmpty()); - SetupSelf(*other); policies_ = mojo::Clone(other->policies_); for (const auto& policy : policies_) ComputeInternalStateForParsedPolicy(*policy); @@ -319,7 +294,14 @@ const ContentSecurityPolicy* other) { for (const auto& policy : other->policies_) { if (policy->plugin_types) { - DidReceiveHeader(CSPDirectiveListPluginTypesText(*policy), + KURL url; + url.SetProtocol(policy->self_origin->scheme); + url.SetHost(policy->self_origin->host); + url.SetPort(policy->self_origin->port == url::PORT_UNSPECIFIED + ? 0 + : policy->self_origin->port); + scoped_refptr<SecurityOrigin> self_origin = SecurityOrigin::Create(url); + DidReceiveHeader(CSPDirectiveListPluginTypesText(*policy), *self_origin, policy->header->type, policy->header->source); } } @@ -327,18 +309,20 @@ void ContentSecurityPolicy::DidReceiveHeaders( const ContentSecurityPolicyResponseHeaders& headers) { + scoped_refptr<SecurityOrigin> self_origin = + SecurityOrigin::Create(headers.ResponseUrl()); if (headers.ShouldParseWasmEval()) supports_wasm_eval_ = true; Vector<network::mojom::blink::ContentSecurityPolicyPtr> parsed_policies; if (!headers.ContentSecurityPolicy().IsEmpty()) { - parsed_policies = Parse(headers.ContentSecurityPolicy(), + parsed_policies = Parse(headers.ContentSecurityPolicy(), *self_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); } if (!headers.ContentSecurityPolicyReportOnly().IsEmpty()) { for (auto& policy : Parse(headers.ContentSecurityPolicyReportOnly(), - ContentSecurityPolicyType::kReport, + *self_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP)) { parsed_policies.push_back(std::move(policy)); } @@ -358,18 +342,17 @@ void ContentSecurityPolicy::DidReceiveHeader( const String& header, + const SecurityOrigin& self_origin, ContentSecurityPolicyType type, ContentSecurityPolicySource source) { - AddPolicies(Parse(header, type, source)); + AddPolicies(Parse(header, self_origin, type, source)); } void ContentSecurityPolicy::AddPolicies( Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies) { Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies_to_report; if (delegate_) { - for (const auto& policy : policies) { - policies_to_report.push_back(FillInSelf(policy)); - } + policies_to_report = mojo::Clone(policies); } for (network::mojom::blink::ContentSecurityPolicyPtr& policy : policies) { @@ -396,6 +379,7 @@ Vector<network::mojom::blink::ContentSecurityPolicyPtr> ContentSecurityPolicy::Parse(const String& header, + const SecurityOrigin& self_origin, ContentSecurityPolicyType type, ContentSecurityPolicySource source) { Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies; @@ -422,10 +406,8 @@ // header1,header2 OR header1 // ^ ^ - network::mojom::blink::ContentSecurityPolicyPtr policy = - CSPDirectiveListParse(this, begin, position, type, source); - - policies.push_back(std::move(policy)); + policies.push_back(CSPDirectiveListParse(this, begin, position, self_origin, + type, source)); // Skip the comma, and begin the next header from the current position. DCHECK(position == end || *position == ','); @@ -483,30 +465,14 @@ } void ContentSecurityPolicy::ReportAccumulatedHeaders() const { - WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies; - for (const auto& policy : policies_) - policies.push_back(FillInSelf(policy)); - DCHECK(delegate_); - delegate_->DidAddContentSecurityPolicies(std::move(policies)); + delegate_->DidAddContentSecurityPolicies(mojo::Clone(GetParsedPolicies())); } void ContentSecurityPolicy::SetOverrideAllowInlineStyle(bool value) { override_inline_style_allowed_ = value; } -void ContentSecurityPolicy::SetOverrideURLForSelf(const KURL& url) { - // Create a temporary CSPSource so that 'self' expressions can be resolved - // before we bind to an execution context (for 'frame-ancestor' resolution, - // for example). This CSPSource will be overwritten when we bind this object - // to an execution context. - scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::Create(url); - self_protocol_ = origin->Protocol(); - self_source_ = network::mojom::blink::CSPSource::New( - self_protocol_, origin->Host(), origin->Port(), "", - /*is_host_wildcard=*/false, /*is_port_wildcard=*/false); -} - // static void ContentSecurityPolicy::FillInCSPHashValues( const String& source, @@ -1570,19 +1536,6 @@ return false; } -bool ContentSecurityPolicy::UrlMatchesSelf(const KURL& url) const { - DCHECK(self_source_); - return CSPSourceMatchesAsSelf(*self_source_, self_protocol_, url); -} - -bool ContentSecurityPolicy::ProtocolEqualsSelf(const String& protocol) const { - return EqualIgnoringASCIICase(protocol, self_protocol_); -} - -const String& ContentSecurityPolicy::GetSelfProtocol() const { - return self_protocol_; -} - // static bool ContentSecurityPolicy::ShouldBypassMainWorld( const ExecutionContext* context) { @@ -1770,20 +1723,9 @@ return should_bypass_csp; } -WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> +const WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>& ContentSecurityPolicy::GetParsedPolicies() const { - WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> list; - for (const auto& policy : policies_) - list.push_back(FillInSelf(policy)); - return list; -} - -network::mojom::blink::ContentSecurityPolicyPtr -ContentSecurityPolicy::FillInSelf( - const network::mojom::blink::ContentSecurityPolicyPtr& csp) const { - network::mojom::blink::ContentSecurityPolicyPtr clone = csp->Clone(); - clone->self_origin = GetSelfSource() ? GetSelfSource()->Clone() : nullptr; - return clone; + return policies_; } bool ContentSecurityPolicy::HasPolicyFromSource(
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/third_party/blink/renderer/core/frame/csp/content_security_policy.h index 0d5dae14..7fd05aca 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.h +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.h
@@ -194,13 +194,12 @@ bool IsBound(); void BindToDelegate(ContentSecurityPolicyDelegate&); - void SetupSelf(const SecurityOrigin&); - void SetupSelf(const ContentSecurityPolicy&); void CopyStateFrom(const ContentSecurityPolicy*); void CopyPluginTypesFrom(const ContentSecurityPolicy*); void DidReceiveHeaders(const ContentSecurityPolicyResponseHeaders&); void DidReceiveHeader(const String&, + const SecurityOrigin& self_origin, network::mojom::ContentSecurityPolicyType, network::mojom::ContentSecurityPolicySource); void ReportAccumulatedHeaders() const; @@ -398,18 +397,10 @@ return insecure_request_policy_; } - bool UrlMatchesSelf(const KURL&) const; - bool ProtocolEqualsSelf(const String&) const; - const String& GetSelfProtocol() const; - bool ExperimentalFeaturesEnabled() const; bool ShouldSendCSPHeader(ResourceType) const; - network::mojom::blink::CSPSource* GetSelfSource() const { - return self_source_.get(); - } - // Whether the main world's CSP should be bypassed based on the current // javascript world we are in. // Note: This is deprecated. New usages should not be added. Operations in an @@ -438,10 +429,8 @@ bool SupportsWasmEval() const { return supports_wasm_eval_; } void SetSupportsWasmEval(bool value) { supports_wasm_eval_ = value; } - // Retrieve a copy of the parsed policies. - // TODO(antoniosartori): Make this return a const reference once we remove - // SetupSelf and this does not need to modify anything in the parsed policies. - WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> + // Retrieve the parsed policies. + const WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>& GetParsedPolicies() const; // Retrieves the parsed sandbox flags. A lot of the time the execution @@ -482,6 +471,7 @@ Vector<network::mojom::blink::ContentSecurityPolicyPtr> Parse( const String&, + const SecurityOrigin& self_origin, network::mojom::ContentSecurityPolicyType, network::mojom::ContentSecurityPolicySource); void ApplyPolicySideEffectsToDelegate(); @@ -537,12 +527,6 @@ LocalFrame* = nullptr, Element* = nullptr); - // Clone |csp| and set the self_origin to SelfOrigin(). - // TODO(antoniosartori): Get rid of this when we will correctly track - // self_origin inside network::mojom::blink::ContentSecurityPolicy. - network::mojom::blink::ContentSecurityPolicyPtr FillInSelf( - const network::mojom::blink::ContentSecurityPolicyPtr& csp) const; - Member<ContentSecurityPolicyDelegate> delegate_; bool override_inline_style_allowed_ = false; Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies_; @@ -563,7 +547,6 @@ String disable_eval_error_message_; mojom::blink::InsecureRequestPolicy insecure_request_policy_; - network::mojom::blink::CSPSourcePtr self_source_; String self_protocol_; bool supports_wasm_eval_ = false;
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc index 3872e4c..862650f 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
@@ -33,7 +33,22 @@ } int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - String header = String::FromUTF8(data, size); + // We need two pieces of input: a URL and a CSP string. Split |data| in two at + // the first whitespace. + const uint8_t* it = data; + for (; it < data + size; it++) { + if (base::IsAsciiWhitespace(*reinterpret_cast<const char*>(it))) { + it++; + break; + } + } + if (it == data + size) { + // Not much point in going on with an empty CSP string. + return EXIT_SUCCESS; + } + + String url = String(data, it - 1 - data); + String header = String(it, size - (it - data)); unsigned hash = header.IsNull() ? 0 : header.Impl()->GetHash(); // Use the 'hash' value to pick header_type and header_source input. @@ -52,9 +67,11 @@ : network::mojom::ContentSecurityPolicySource::kOriginPolicy; } + scoped_refptr<SecurityOrigin> self_origin = SecurityOrigin::Create(KURL(url)); + // Construct and initialize a policy from the string. auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(header, header_type, header_source); + csp->DidReceiveHeader(header, *self_origin, header_type, header_source); auto& context = g_page_holder->GetFrame().DomWindow()->GetSecurityContext(); context.SetContentSecurityPolicy(csp);
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index 74d8c11..e28ea1ac 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -37,7 +37,7 @@ public: ContentSecurityPolicyTest() : csp(MakeGarbageCollected<ContentSecurityPolicy>()), - secure_url("https://example.test/image.png"), + secure_url("https://example.test/index.html"), secure_origin(SecurityOrigin::Create(secure_url)) {} ~ContentSecurityPolicyTest() override { execution_context->NotifyContextDestroyed(); @@ -84,7 +84,8 @@ SCOPED_TRACE(testing::Message() << "[Enforce] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader(test.header, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.expected_policy, csp->GetInsecureRequestPolicy()); @@ -112,7 +113,8 @@ SCOPED_TRACE(testing::Message() << "[Report-Only] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport, + csp->DidReceiveHeader(test.header, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone, csp->GetInsecureRequestPolicy()); @@ -131,9 +133,9 @@ TEST_F(ContentSecurityPolicyTest, CopyStateFrom) { csp->DidReceiveHeader("script-src 'none'; plugin-types application/x-type-1", - ContentSecurityPolicyType::kReport, + *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); - csp->DidReceiveHeader("img-src http://example.com", + csp->DidReceiveHeader("img-src http://example.com", *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); @@ -166,9 +168,9 @@ TEST_F(ContentSecurityPolicyTest, CopyPluginTypesFrom) { csp->DidReceiveHeader("script-src 'none'; plugin-types application/x-type-1", - ContentSecurityPolicyType::kEnforce, + *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); - csp->DidReceiveHeader("img-src http://example.com", + csp->DidReceiveHeader("img-src http://example.com", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -198,7 +200,7 @@ TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithConnectSrc) { EXPECT_FALSE(csp->IsActiveForConnections()); - csp->DidReceiveHeader("connect-src 'none';", + csp->DidReceiveHeader("connect-src 'none';", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsActiveForConnections()); @@ -206,7 +208,7 @@ TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithDefaultSrc) { EXPECT_FALSE(csp->IsActiveForConnections()); - csp->DidReceiveHeader("default-src 'none';", + csp->DidReceiveHeader("default-src 'none';", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsActiveForConnections()); @@ -218,13 +220,15 @@ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_EQ(network::mojom::blink::WebSandboxFlags::kNone, csp->GetSandboxMask()); - csp->DidReceiveHeader("sandbox;", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("sandbox;", *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kMeta); EXPECT_EQ(network::mojom::blink::WebSandboxFlags::kNone, csp->GetSandboxMask()); execution_context->GetSecurityContext().SetSandboxFlags( network::mojom::blink::WebSandboxFlags::kAll); - csp->DidReceiveHeader("sandbox;", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("sandbox;", *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(network::mojom::blink::WebSandboxFlags::kAll, csp->GetSandboxMask()); @@ -236,7 +240,7 @@ TEST_F(ContentSecurityPolicyTest, ObjectSrc) { const KURL url("https://example.test"); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("object-src 'none';", + csp->DidReceiveHeader("object-src 'none';", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kMeta); EXPECT_FALSE(csp->AllowRequest(mojom::blink::RequestContextType::OBJECT, @@ -262,7 +266,7 @@ TEST_F(ContentSecurityPolicyTest, ConnectSrc) { const KURL url("https://example.test"); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("connect-src 'none';", + csp->DidReceiveHeader("connect-src 'none';", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kMeta); EXPECT_FALSE(csp->AllowRequest(mojom::blink::RequestContextType::SUBRESOURCE, @@ -327,7 +331,8 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kEnforce, + policy->DidReceiveHeader(test.policy, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed, policy->AllowScriptFromSource( @@ -342,7 +347,8 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kReport, + policy->DidReceiveHeader(test.policy, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, @@ -391,6 +397,7 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(window->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(String("script-src ") + test.policy, + *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed, @@ -402,7 +409,7 @@ // Enforce 'style-src' policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(window->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(String("style-src ") + test.policy, + policy->DidReceiveHeader(String("style-src ") + test.policy, *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed, @@ -415,7 +422,7 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(window->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(String("script-src ") + test.policy, - ContentSecurityPolicyType::kReport, + *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowInline(ContentSecurityPolicy::InlineType::kScript, element, content, String(test.nonce), @@ -425,7 +432,7 @@ // Report 'style-src' policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate(window->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(String("style-src ") + test.policy, + policy->DidReceiveHeader(String("style-src ") + test.policy, *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowInline(ContentSecurityPolicy::InlineType::kStyle, @@ -497,9 +504,11 @@ MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kEnforce, + policy->DidReceiveHeader(test.policy1, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); - policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kReport, + policy->DidReceiveHeader(test.policy2, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed1, policy->AllowScriptFromSource( @@ -519,9 +528,11 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kReport, + policy->DidReceiveHeader(test.policy1, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); - policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kEnforce, + policy->DidReceiveHeader(test.policy2, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, @@ -541,9 +552,11 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kEnforce, + policy->DidReceiveHeader(test.policy1, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); - policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kEnforce, + policy->DidReceiveHeader(test.policy2, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_EQ(test.allowed1 && test.allowed2, policy->AllowScriptFromSource( @@ -558,9 +571,11 @@ policy = MakeGarbageCollected<ContentSecurityPolicy>(); policy->BindToDelegate( execution_context->GetContentSecurityPolicyDelegate()); - policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kReport, + policy->DidReceiveHeader(test.policy1, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); - policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kReport, + policy->DidReceiveHeader(test.policy2, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, @@ -627,7 +642,7 @@ secure_origin); // https://example.com execution_context->SetURL(secure_url); // https://example.com csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("default-src https://example.com", + csp->DidReceiveHeader("default-src https://example.com", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -674,7 +689,7 @@ secure_origin); // https://example.com execution_context->SetURL(secure_url); // https://example.com csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("default-src https://example.com", + csp->DidReceiveHeader("default-src https://example.com", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -722,7 +737,7 @@ secure_origin); // https://example.com execution_context->SetURL(secure_url); // https://example.com csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("default-src https://example.com", + csp->DidReceiveHeader("default-src https://example.com", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -769,7 +784,7 @@ execution_context->GetSecurityContext().SetSecurityOrigin(secure_origin); execution_context->SetURL(BlankURL()); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("script-src http://example.com", + csp->DidReceiveHeader("script-src http://example.com", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -811,7 +826,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesNoDirective) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details; @@ -827,14 +842,14 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesSimpleDirective) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one two three", + csp->DidReceiveHeader("trusted-types one two three", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); } TEST_F(ContentSecurityPolicyTest, TrustedTypesWhitespace) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one\ntwo\rthree", + csp->DidReceiveHeader("trusted-types one\ntwo\rthree", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -865,7 +880,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesEmpty) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("trusted-types", *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details; @@ -883,7 +899,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesStar) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("trusted-types *", *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details; @@ -900,7 +917,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesStarMix) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types abc * def", + csp->DidReceiveHeader("trusted-types abc * def", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -932,7 +949,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeDupe) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); csp->DidReceiveHeader("trusted-types somepolicy 'allow-duplicates'", - ContentSecurityPolicyType::kEnforce, + *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details; @@ -948,7 +965,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeDupeStar) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types * 'allow-duplicates'", + csp->DidReceiveHeader("trusted-types * 'allow-duplicates'", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -965,7 +982,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesReserved) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one \"two\" 'three'", + csp->DidReceiveHeader("trusted-types one \"two\" 'three'", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); @@ -1017,7 +1034,8 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesReportingStar) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kReport, + csp->DidReceiveHeader("trusted-types *", *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details; @@ -1034,7 +1052,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReportingSimple) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types a b c", + csp->DidReceiveHeader("trusted-types a b c", *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); @@ -1050,7 +1068,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeEnforce) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one\ntwo\rthree", + csp->DidReceiveHeader("trusted-types one\ntwo\rthree", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsRequireTrustedTypes()); @@ -1059,7 +1077,7 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReport) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one\ntwo\rthree", + csp->DidReceiveHeader("trusted-types one\ntwo\rthree", *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsRequireTrustedTypes()); @@ -1068,9 +1086,10 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndEnforce) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one", ContentSecurityPolicyType::kReport, + csp->DidReceiveHeader("trusted-types one", *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); - csp->DidReceiveHeader("trusted-types two", + csp->DidReceiveHeader("trusted-types two", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsRequireTrustedTypes()); @@ -1079,9 +1098,11 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndNonTTEnforce) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types one", ContentSecurityPolicyType::kReport, + csp->DidReceiveHeader("trusted-types one", *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); - csp->DidReceiveHeader("script-src none", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("script-src none", *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsRequireTrustedTypes()); EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla")); @@ -1090,12 +1111,12 @@ TEST_F(ContentSecurityPolicyTest, RequireTrustedTypeForEnforce) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("require-trusted-types-for ''", + csp->DidReceiveHeader("require-trusted-types-for ''", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_FALSE(csp->IsRequireTrustedTypes()); - csp->DidReceiveHeader("require-trusted-types-for 'script'", + csp->DidReceiveHeader("require-trusted-types-for 'script'", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsRequireTrustedTypes()); @@ -1104,7 +1125,7 @@ TEST_F(ContentSecurityPolicyTest, RequireTrustedTypeForReport) { execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("require-trusted-types-for 'script'", + csp->DidReceiveHeader("require-trusted-types-for 'script'", *secure_origin, ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(csp->IsRequireTrustedTypes()); @@ -1112,7 +1133,8 @@ TEST_F(ContentSecurityPolicyTest, DefaultPolicy) { csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader("trusted-types *", *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details; @@ -1131,7 +1153,7 @@ // Directive name is case insensitive. csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader("sCrIpt-sRc http://example.com", + csp->DidReceiveHeader("sCrIpt-sRc http://example.com", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); @@ -1148,7 +1170,8 @@ csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->DidReceiveHeader( "SCRipt-SRC http://example.com; script-src http://not-example.com;", - ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); + *secure_origin, ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kHTTP); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_TRUE(csp->AllowScriptFromSource( @@ -1261,7 +1284,7 @@ secure_origin = secure_origin->DeriveNewOpaqueOrigin(); CreateExecutionContext(); csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); - csp->DidReceiveHeader("default-src 'self';", + csp->DidReceiveHeader("default-src 'self';", *secure_origin, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kMeta); EXPECT_TRUE(csp->AllowRequest(mojom::blink::RequestContextType::SUBRESOURCE, @@ -1272,6 +1295,32 @@ ReportingDisposition::kSuppressReporting)); } +TEST_F(ContentSecurityPolicyTest, SelfForDataMatchesNothing) { + const KURL url("https://example.test"); + auto reference_origin = SecurityOrigin::Create(url); + const KURL data_url("data:text/html,hello"); + secure_origin = SecurityOrigin::CreateWithReferenceOrigin( + data_url, reference_origin.get()); + + CreateExecutionContext(); + csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); + csp->DidReceiveHeader("default-src 'self';", *secure_origin, + ContentSecurityPolicyType::kEnforce, + ContentSecurityPolicySource::kMeta); + EXPECT_TRUE(csp->AllowRequest(mojom::blink::RequestContextType::SUBRESOURCE, + network::mojom::RequestDestination::kEmpty, url, + String(), IntegrityMetadataSet(), + kParserInserted, url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); + EXPECT_FALSE(csp->AllowRequest(mojom::blink::RequestContextType::SUBRESOURCE, + network::mojom::RequestDestination::kEmpty, + data_url, String(), IntegrityMetadataSet(), + kParserInserted, url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); +} + TEST_F(ContentSecurityPolicyTest, ReasonableRestrictionMetrics) { struct TestCase { const char* header; @@ -1304,7 +1353,8 @@ SCOPED_TRACE(testing::Message() << "[Enforce] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader(test.header, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); auto dummy = std::make_unique<DummyPageHolder>(); csp->BindToDelegate( @@ -1330,7 +1380,8 @@ SCOPED_TRACE(testing::Message() << "[ReportOnly] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport, + csp->DidReceiveHeader(test.header, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); auto dummy = std::make_unique<DummyPageHolder>(); csp->BindToDelegate( @@ -1380,7 +1431,8 @@ SCOPED_TRACE(testing::Message() << "[Enforce] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce, + csp->DidReceiveHeader(test.header, *secure_origin, + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); auto dummy = std::make_unique<DummyPageHolder>(); csp->BindToDelegate( @@ -1396,7 +1448,8 @@ SCOPED_TRACE(testing::Message() << "[ReportOnly] Header: `" << test.header << "`"); csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport, + csp->DidReceiveHeader(test.header, *secure_origin, + ContentSecurityPolicyType::kReport, ContentSecurityPolicySource::kHTTP); auto dummy = std::make_unique<DummyPageHolder>(); csp->BindToDelegate(
diff --git a/third_party/blink/renderer/core/frame/csp/conversion_util_fuzzer.cc b/third_party/blink/renderer/core/frame/csp/conversion_util_fuzzer.cc index 400b61e..b8b7b192 100644 --- a/third_party/blink/renderer/core/frame/csp/conversion_util_fuzzer.cc +++ b/third_party/blink/renderer/core/frame/csp/conversion_util_fuzzer.cc
@@ -47,13 +47,14 @@ : network::mojom::ContentSecurityPolicySource::kOriginPolicy; } + scoped_refptr<SecurityOrigin> self_origin = SecurityOrigin::Create(KURL(url)); + // Construct a policy from the string. auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(header, header_type, header_source); - csp->SetupSelf(*SecurityOrigin::Create(KURL(url))); + csp->DidReceiveHeader(header, *self_origin, header_type, header_source); - Vector<network::mojom::blink::ContentSecurityPolicyPtr> parsed_policies = - csp->GetParsedPolicies(); + const Vector<network::mojom::blink::ContentSecurityPolicyPtr>& + parsed_policies = csp->GetParsedPolicies(); if (parsed_policies.size() > 0) { network::mojom::blink::ContentSecurityPolicyPtr converted_csp = ConvertToMojoBlink(ConvertToPublic(parsed_policies[0]->Clone()));
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index 29a23d9..d93fff1 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/weborigin/known_ports.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h" @@ -243,6 +244,7 @@ void ParseReportURI(const String& name, const String& value, + const SecurityOrigin& self_origin, network::mojom::blink::ContentSecurityPolicy& csp, ContentSecurityPolicy* policy) { // report-to supersedes report-uri @@ -262,14 +264,9 @@ ? WebFeature::kReportUriMultipleEndpoints : WebFeature::kReportUriSingleEndpoint); - // Ignore right away report-uri endpoints which would be blocked later when - // reporting because of Mixed Content and report a warning. - if (!policy->GetSelfSource()) { - return; - } csp.report_endpoints.erase( std::remove_if(csp.report_endpoints.begin(), csp.report_endpoints.end(), - [policy](const String& endpoint) { + [policy, &self_origin](const String& endpoint) { KURL parsed_endpoint = KURL(endpoint); if (!parsed_endpoint.IsValid()) { // endpoint is not absolute, so it cannot violate @@ -277,8 +274,7 @@ return false; } if (MixedContentChecker::IsMixedContent( - policy->GetSelfSource()->scheme, - parsed_endpoint)) { + self_origin.Protocol(), parsed_endpoint)) { policy->ReportMixedContentReportURI(endpoint); return true; } @@ -353,6 +349,7 @@ void AddDirective(const String& name, const String& value, + const SecurityOrigin& self_origin, network::mojom::blink::ContentSecurityPolicy& csp, ContentSecurityPolicy* policy) { DCHECK(!name.IsEmpty()); @@ -419,7 +416,7 @@ ParseReportTo(name, value, csp, policy); return; case CSPDirectiveName::ReportURI: - ParseReportURI(name, value, csp, policy); + ParseReportURI(name, value, self_origin, csp, policy); return; case CSPDirectiveName::RequireTrustedTypesFor: csp.require_trusted_types_for = @@ -519,6 +516,7 @@ // void Parse(const UChar* begin, const UChar* end, + const SecurityOrigin& self_origin, bool should_parse_wasm_eval, network::mojom::blink::ContentSecurityPolicy& csp, ContentSecurityPolicy* policy) { @@ -531,11 +529,11 @@ SkipUntil<UChar>(position, end, ';'); // |name| and |value| must always be initialized in order to avoid mojo - // |serialization errors. + // serialization errors. String name, value = ""; if (ParseDirective(directive_begin, position, &name, &value, policy)) { DCHECK(!name.IsEmpty()); - AddDirective(name, value, csp, policy); + AddDirective(name, value, self_origin, csp, policy); } DCHECK(position == end || *position == ';'); @@ -684,6 +682,7 @@ bool CheckSource(ContentSecurityPolicy* policy, const network::mojom::blink::CSPSourceList* directive, + const network::mojom::blink::CSPSource& self_origin, const KURL& url, ResourceRequest::RedirectStatus redirect_status) { // If |url| is empty, fall back to the policy URL to ensure that <object>'s @@ -693,7 +692,7 @@ return true; return CSPSourceListAllows( - *directive, *(policy->GetSelfSource()), + *directive, self_origin, url.IsEmpty() ? policy->FallbackUrlForPlugin() : url, redirect_status); } @@ -862,7 +861,8 @@ return true; // We ignore URL-based allowlists if we're allowing dynamic script injection. - if (CheckSource(policy, directive.source_list, url, redirect_status) && + if (CheckSource(policy, directive.source_list, *csp.self_origin, url, + redirect_status) && !CheckDynamic(directive.source_list, effective_type)) return true; @@ -936,12 +936,31 @@ return CheckDynamic(worker_src, CSPDirectiveName::WorkerSrc); } +network::mojom::blink::CSPSourcePtr ComputeSelfOrigin( + const SecurityOrigin& self_origin) { + DCHECK(self_origin.Protocol()); + return network::mojom::blink::CSPSource::New( + self_origin.Protocol(), + // Forget the host for file schemes. Host can anyway only be `localhost` + // or empty and this is platform dependent. + // + // TODO(antoniosartori): Consider returning mojom::CSPSource::New() for + // file: urls, so that 'self' for file: would match nothing. + self_origin.Protocol() == "file" ? "" : self_origin.Host(), + self_origin.Port() == DefaultPortForProtocol(self_origin.Protocol()) + ? url::PORT_UNSPECIFIED + : self_origin.Port(), + "", + /*is_host_wildcard=*/false, /*is_port_wildcard=*/false); +} + } // namespace network::mojom::blink::ContentSecurityPolicyPtr CSPDirectiveListParse( ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, + const SecurityOrigin& self_origin, ContentSecurityPolicyType type, ContentSecurityPolicySource source, bool should_parse_wasm_eval) { @@ -950,7 +969,11 @@ String(begin, static_cast<wtf_size_t>(end - begin)).StripWhiteSpace(), type, source); - Parse(begin, end, should_parse_wasm_eval, *csp, policy); + const SecurityOrigin& real_self_origin = + *(self_origin.GetOriginOrPrecursorOriginIfOpaque()); + csp->self_origin = ComputeSelfOrigin(real_self_origin); + + Parse(begin, end, real_self_origin, should_parse_wasm_eval, *csp, policy); return csp; } @@ -1191,11 +1214,12 @@ reporting_disposition == ReportingDisposition::kReport ? CheckSourceAndReportViolation(csp, policy, directive, url, type, url_before_redirects, redirect_status) - : CheckSource(policy, directive.source_list, url, redirect_status); + : CheckSource(policy, directive.source_list, *csp.self_origin, url, + redirect_status); if (type == CSPDirectiveName::BaseURI) { - if (result && - !CheckSource(policy, directive.source_list, url, redirect_status)) { + if (result && !CheckSource(policy, directive.source_list, *csp.self_origin, + url, redirect_status)) { policy->Count(WebFeature::kBaseWouldBeBlockedByDefaultSrc); } }
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h index d5b1714..e777eb8 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -11,7 +11,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" -#include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -19,6 +18,9 @@ namespace blink { +class KURL; +class SecurityOrigin; + enum class ResourceType : uint8_t; struct CORE_EXPORT CSPOperativeDirective { @@ -31,6 +33,7 @@ ContentSecurityPolicy*, const UChar* begin, const UChar* end, + const SecurityOrigin& self_origin, network::mojom::ContentSecurityPolicyType, network::mojom::ContentSecurityPolicySource, bool should_parse_wasm_eval = false);
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index 83080e20..7679bfe 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -29,8 +29,6 @@ CSPDirectiveListTest() : csp(MakeGarbageCollected<ContentSecurityPolicy>()) {} void SetUp() override { scoped_feature_list_.InitWithFeatures({network::features::kReporting}, {}); - csp->SetupSelf( - *SecurityOrigin::CreateFromString("https://example.test/image.png")); } network::mojom::blink::ContentSecurityPolicyPtr CreateList( @@ -42,7 +40,10 @@ const UChar* begin = characters.data(); const UChar* end = begin + characters.size(); - return CSPDirectiveListParse(csp.Get(), begin, end, type, source); + scoped_refptr<SecurityOrigin> self_origin = + SecurityOrigin::Create(KURL("https://example.test/index.html")); + return CSPDirectiveListParse(csp.Get(), begin, end, *self_origin, type, + source); } protected:
diff --git a/third_party/blink/renderer/core/frame/csp/csp_source.cc b/third_party/blink/renderer/core/frame/csp/csp_source.cc index fec9276f..d0c2877 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_source.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_source.cc
@@ -170,15 +170,14 @@ } bool CSPSourceMatchesAsSelf(const network::mojom::blink::CSPSource& source, - const String& self_protocol, const KURL& url) { // https://w3c.github.io/webappsec-csp/#match-url-to-source-expression // Step 4. SchemeMatchingResult schemes_match = - SchemeMatches(source, url.Protocol(), self_protocol); + SchemeMatches(source, url.Protocol(), source.scheme); bool hosts_match = HostMatches(source, url.Host()); PortMatchingResult ports_match = PortMatches( - source, self_protocol, url.HasPort() ? url.Port() : url::PORT_UNSPECIFIED, + source, source.scheme, url.HasPort() ? url.Port() : url::PORT_UNSPECIFIED, url.Protocol()); // check if the origin is exactly matching @@ -188,19 +187,16 @@ return true; } - String self_scheme = - (source.scheme.IsEmpty() ? self_protocol : source.scheme); - bool ports_match_or_defaults = (ports_match == PortMatchingResult::kMatchingExact || - ((IsDefaultPortForProtocol(source.port, self_scheme) || + ((IsDefaultPortForProtocol(source.port, source.scheme) || source.port == url::PORT_UNSPECIFIED) && (!url.HasPort() || IsDefaultPortForProtocol(url.Port(), url.Protocol())))); return hosts_match && ports_match_or_defaults && (url.Protocol() == "https" || url.Protocol() == "wss" || - self_scheme == "http"); + source.scheme == "http"); } bool CSPSourceIsSchemeOnly(const network::mojom::blink::CSPSource& source) {
diff --git a/third_party/blink/renderer/core/frame/csp/csp_source.h b/third_party/blink/renderer/core/frame/csp/csp_source.h index 2f489b18..24a67ca 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_source.h +++ b/third_party/blink/renderer/core/frame/csp/csp_source.h
@@ -30,7 +30,6 @@ CORE_EXPORT bool CSPSourceMatchesAsSelf(const network::mojom::blink::CSPSource& source, - const String& self_protocol, const KURL& url); } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/csp/csp_source_test.cc b/third_party/blink/renderer/core/frame/csp/csp_source_test.cc index f0bd0b9..9ef2f4e 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_source_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_source_test.cc
@@ -443,7 +443,7 @@ test.self_source.path, test.self_source.host_wildcard, test.self_source.port_wildcard); EXPECT_EQ(test.expected, - CSPSourceMatchesAsSelf(*self_source, "", KURL(base, test.url))); + CSPSourceMatchesAsSelf(*self_source, KURL(base, test.url))); } }
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc index d28ab7194..17ae142 100644 --- a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc +++ b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
@@ -546,8 +546,7 @@ return HasSourceMatchInList(source_list.sources, self_source.scheme, url, redirect_status); } - if (source_list.allow_self && - CSPSourceMatchesAsSelf(self_source, self_source.scheme, url)) { + if (source_list.allow_self && CSPSourceMatchesAsSelf(self_source, url)) { return true; }
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc index ea73f2a..004b0db 100644 --- a/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc +++ b/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
@@ -33,6 +33,8 @@ void SetUp() override { KURL secure_url("https://example.test/image.png"); + self_source = network::mojom::blink::CSPSource::New("https", "example.test", + 443, "", false, false); context = MakeGarbageCollected<NullExecutionContext>(); context->GetSecurityContext().SetSecurityOrigin( SecurityOrigin::Create(secure_url)); @@ -41,6 +43,7 @@ Persistent<ContentSecurityPolicy> csp; Persistent<ExecutionContext> context; + network::mojom::blink::CSPSourcePtr self_source; }; TEST_F(SourceListDirectiveTest, BasicMatchingNone) { @@ -50,9 +53,9 @@ CSPSourceListParse("script-src", sources, csp.Get()); ASSERT_TRUE(source_list); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example.com/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example.test/"))); } @@ -78,29 +81,29 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example.com/bar"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://foo.example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://foo.example.com/bar"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "ftp://example.com/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "data:https://example.test/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "blob:https://example.test/"))); EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + CSPSourceListAllows(*source_list, *self_source, KURL(base, "filesystem:https://example.test/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "file:///etc/hosts"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "applewebdata://example.test/"))); } @@ -110,33 +113,31 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - // With a protocol of 'file', '*' allows 'file:': - scoped_refptr<const SecurityOrigin> origin = - SecurityOrigin::CreateFromValidTuple("file", "", 0); - csp->SetupSelf(*origin); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + auto self_origin = + network::mojom::blink::CSPSource::New("file", "", -1, "", false, false); + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "file:///etc/hosts"))); // The other results are the same as above: - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "http://example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "https://example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "http://example.com/bar"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "http://foo.example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "http://foo.example.com/bar"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "data:https://example.test/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "blob:https://example.test/"))); EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + CSPSourceListAllows(*source_list, *self_origin, KURL(base, "filesystem:https://example.test/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_origin, KURL(base, "applewebdata://example.test/"))); } @@ -146,11 +147,11 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example.com/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://not-example.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example.test/"))); } @@ -160,9 +161,9 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example.test/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "blob:https://example.test/"))); } @@ -172,28 +173,26 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example1.com:8000/foo/"))); EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example1.com:8000/foo/bar"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example2.com/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example2.com/foo/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://not-example.com/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example1.com/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example1.com/foo"))); - EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example1.com:9000/foo/"))); - EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example1.com:8000/FOO/"))); + EXPECT_FALSE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example1.com:9000/foo/"))); + EXPECT_FALSE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example1.com:8000/FOO/"))); } TEST_F(SourceListDirectiveTest, WildcardMatching) { @@ -203,47 +202,45 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example1.com/foo/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example1.com:8000/foo/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example1.com:9000/foo/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://foo.example2.com/bar/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://foo.test/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://foo.bar.test/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example1.com/foo/"))); EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example1.com:8000/foo/"))); EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example1.com:9000/foo/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://foo.test/"))); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://foo.bar.test/"))); + EXPECT_FALSE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "https://example1.com:8000/foo"))); + EXPECT_FALSE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "https://example2.com:8000/bar"))); EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "https://example1.com:8000/foo"))); - EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "https://example2.com:8000/bar"))); - EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://foo.example2.com:8000/bar"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example2.foo.com/bar"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://foo.test.bar/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "https://example2.com/bar/"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://test/"))); } @@ -253,35 +250,28 @@ network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("script-src", sources, csp.Get()); - EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example1.com/foo/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); - EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example1.com/bar/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); - EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example2.com/bar/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); - EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example2.com/foo/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); - EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "https://example1.com/foo/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); - EXPECT_TRUE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "https://example1.com/bar/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_TRUE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example1.com/foo/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_TRUE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example1.com/bar/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_TRUE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example2.com/bar/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_TRUE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example2.com/foo/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_TRUE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "https://example1.com/foo/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_TRUE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "https://example1.com/bar/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); - EXPECT_FALSE( - CSPSourceListAllows(*source_list, *csp->GetSelfSource(), - KURL(base, "http://example3.com/foo/"), - ResourceRequest::RedirectStatus::kFollowedRedirect)); + EXPECT_FALSE(CSPSourceListAllows( + *source_list, *self_source, KURL(base, "http://example3.com/foo/"), + ResourceRequest::RedirectStatus::kFollowedRedirect)); } TEST_F(SourceListDirectiveTest, AllowAllInline) { @@ -527,9 +517,9 @@ String sources = "http://*:111"; network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("default-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://a.com:111"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://a.com:222"))); } // When the host-part is "*", the path must still be checked. @@ -538,9 +528,9 @@ String sources = "http://*/welcome.html"; network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("default-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://a.com/welcome.html"))); - EXPECT_FALSE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_FALSE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://a.com/passwords.txt"))); } // When the host-part is "*" and the expression-source is not "*", then every @@ -549,7 +539,7 @@ String sources = "http://*"; network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("default-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://a.com"))); } } @@ -561,7 +551,7 @@ String sources = "http://ExAmPle.com"; network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("default-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://example.com"))); } // Wildcard sources should match hosts case-insensitively. @@ -569,7 +559,7 @@ String sources = "http://*.ExAmPle.com"; network::mojom::blink::CSPSourceListPtr source_list = CSPSourceListParse("default-src", sources, csp.Get()); - EXPECT_TRUE(CSPSourceListAllows(*source_list, *csp->GetSelfSource(), + EXPECT_TRUE(CSPSourceListAllows(*source_list, *self_source, KURL(base, "http://www.example.com"))); } }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window_test.cc b/third_party/blink/renderer/core/frame/local_dom_window_test.cc index a141adf..78601512 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window_test.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window_test.cc
@@ -217,13 +217,11 @@ // Set a CSP for the main world. const char* kMainWorldCSP = "connect-src https://google.com;"; GetFrame().DomWindow()->GetContentSecurityPolicy()->DidReceiveHeader( - kMainWorldCSP, ContentSecurityPolicyType::kEnforce, - ContentSecurityPolicySource::kHTTP); - Vector<network::mojom::blink::ContentSecurityPolicyPtr> - parsed_main_world_csp = GetFrame() - .DomWindow() - ->GetContentSecurityPolicy() - ->GetParsedPolicies(); + kMainWorldCSP, *(GetFrame().DomWindow()->GetSecurityOrigin()), + ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); + const Vector< + network::mojom::blink::ContentSecurityPolicyPtr>& parsed_main_world_csp = + GetFrame().DomWindow()->GetContentSecurityPolicy()->GetParsedPolicies(); LocalFrame* frame = &GetFrame(); ScriptState* main_world_script_state = ToScriptStateForMainWorld(frame); @@ -248,7 +246,8 @@ SecurityOrigin::Create(KURL("chrome-extension://123"))); // Returns the csp headers being used for the current world. - auto get_csp = [this]() { + auto get_csp = [this]() + -> const Vector<network::mojom::blink::ContentSecurityPolicyPtr>& { auto* csp = GetFrame().DomWindow()->GetContentSecurityPolicyForCurrentWorld(); return csp->GetParsedPolicies();
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 3bad8f4e..eaaabab 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -165,6 +165,7 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h" #include "third_party/blink/renderer/core/svg/svg_document_extensions.h" +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -227,10 +228,11 @@ class BackForwardCacheBufferLimitTracker { public: BackForwardCacheBufferLimitTracker() - : max_buffered_bytes_per_process_(base::GetFieldTrialParamByFeatureAsInt( - blink::features::kLoadingTasksUnfreezable, - "max_buffered_bytes_per_process", - kDefaultMaxBufferedBodyBytesPerProcess)) {} + : max_buffered_bytes_per_process_( + blink::GetLoadingTasksUnfreezableParamAsInt( + "max_buffered_bytes_per_process", + kDefaultMaxBufferedBodyBytesPerProcess)) {} + BackForwardCacheBufferLimitTracker(BackForwardCacheBufferLimitTracker&) = delete; @@ -2432,7 +2434,7 @@ WebURLLoader::DeferType LocalFrame::GetLoadDeferType() { if (GetPage()->GetPageScheduler()->IsInBackForwardCache() && - base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable)) { + IsInflightNetworkRequestBackForwardCacheSupportEnabled()) { return WebURLLoader::DeferType::kDeferredWithBackForwardCache; } if (paused_ || frozen_)
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index f7762ba..db0c546 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -313,16 +313,16 @@ void RegisterMockedHttpURLLoadWithCSP(const std::string& file_name, const std::string& csp, bool report_only = false) { - WebURLResponse response; + std::string full_string = base_url_ + file_name; + KURL url = ToKURL(full_string); + WebURLResponse response = WebURLResponse(url); response.SetMimeType("text/html"); response.AddHttpHeaderField( report_only ? WebString("Content-Security-Policy-Report-Only") : WebString("Content-Security-Policy"), WebString::FromUTF8(csp)); - std::string full_string = base_url_ + file_name; RegisterMockedURLLoadWithCustomResponse( - ToKURL(full_string), - test::CoreTestDataPath(WebString::FromUTF8(file_name)), response); + url, test::CoreTestDataPath(WebString::FromUTF8(file_name)), response); } void RegisterMockedHttpURLLoadWithMimeType(const std::string& file_name,
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc index 420308b..c6a5778 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element.cc +++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -207,7 +207,8 @@ UpdateContainerPolicy(); } } else if (name == html_names::kCspAttr) { - if (value.Contains('\n') || value.Contains('\r') || value.Contains(',')) { + if (value.Contains('\n') || value.Contains('\r') || + !MatchesTheSerializedCSPGrammar(value.GetString())) { required_csp_ = g_null_atom; GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::blink::ConsoleMessageSource::kOther,
diff --git a/third_party/blink/renderer/core/inspector/inspector_contrast.cc b/third_party/blink/renderer/core/inspector/inspector_contrast.cc index ab69b7b..541b6f65 100644 --- a/third_party/blink/renderer/core/inspector/inspector_contrast.cc +++ b/third_party/blink/renderer/core/inspector/inspector_contrast.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/css/css_gradient_value.h" #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -200,13 +201,16 @@ if (!text_node || top_element->firstChild()->nextSibling()) return result; - Vector<Color> bgcolors = GetBackgroundColors(top_element); + float text_opacity = 1.0f; + Vector<Color> bgcolors = GetBackgroundColors(top_element, &text_opacity); if (bgcolors.IsEmpty()) return result; Color text_color = static_cast<const cssvalue::CSSColorValue*>(text_color_value)->Value(); + text_color = text_color.CombineWithAlpha(text_opacity); + float contrast_ratio = color_utils::GetContrastRatio( SkColor(bgcolors.at(0).Blend(text_color)), SkColor(bgcolors.at(0))); @@ -239,7 +243,8 @@ return info; } -Vector<Color> InspectorContrast::GetBackgroundColors(Element* element) { +Vector<Color> InspectorContrast::GetBackgroundColors(Element* element, + float* text_opacity) { Vector<Color> colors; // TODO: only support the single text child node here. // Follow up with a larger fix post-merge. @@ -256,7 +261,8 @@ // Start with the "default" page color (typically white). colors.push_back(view->BaseBackgroundColor()); - GetColorsFromRect(content_bounds, text_node->GetDocument(), element, colors); + GetColorsFromRect(content_bounds, text_node->GetDocument(), element, colors, + text_opacity); return colors; } @@ -274,13 +280,16 @@ bool InspectorContrast::GetColorsFromRect(PhysicalRect rect, Document& document, Element* top_element, - Vector<Color>& colors) { + Vector<Color>& colors, + float* text_opacity) { std::vector<Member<Node>> elements_under_rect = ElementsFromRect(rect, document); bool found_opaque_color = false; bool found_top_element = false; + *text_opacity = 1.0f; + for (auto e = elements_under_rect.begin(); !found_top_element && e != elements_under_rect.end(); ++e) { const Element* element = To<Element>(e->Get()); @@ -313,6 +322,12 @@ if (style->HasOpacity()) { background_color = background_color.CombineWithAlpha( background_color.Alpha() / 255 * style->Opacity()); + // If the background element is the ancestor of the top element or is the + // top element, the opacity affects the text color of the top element. + if (element == top_element || + FlatTreeTraversal::IsDescendantOf(*top_element, *element)) { + *text_opacity *= style->Opacity(); + } } bool found_non_transparent_color = false;
diff --git a/third_party/blink/renderer/core/inspector/inspector_contrast.h b/third_party/blink/renderer/core/inspector/inspector_contrast.h index 99b352d..c5f339f7 100644 --- a/third_party/blink/renderer/core/inspector/inspector_contrast.h +++ b/third_party/blink/renderer/core/inspector/inspector_contrast.h
@@ -39,7 +39,7 @@ explicit InspectorContrast(Document*); ContrastInfo GetContrast(Element*); std::vector<ContrastInfo> GetElementsWithContrastIssues(size_t max_elements); - Vector<Color> GetBackgroundColors(Element*); + Vector<Color> GetBackgroundColors(Element*, float* text_opacity); TextInfo GetTextInfo(Element*); private: @@ -49,7 +49,8 @@ bool GetColorsFromRect(PhysicalRect rect, Document& document, Element* top_element, - Vector<Color>& colors); + Vector<Color>& colors, + float* text_opacity); void CollectNodesAndBuildRTreeIfNeeded(); cc::RTree<Member<Node>> rtree_;
diff --git a/third_party/blink/renderer/core/inspector/inspector_contrast_test.cc b/third_party/blink/renderer/core/inspector/inspector_contrast_test.cc index 1e1b8c4..52265d2 100644 --- a/third_party/blink/renderer/core/inspector/inspector_contrast_test.cc +++ b/third_party/blink/renderer/core/inspector/inspector_contrast_test.cc
@@ -38,9 +38,11 @@ GetDocument().View()->UpdateAllLifecyclePhasesForTest(); Element* target = GetDocument().getElementById("target"); InspectorContrast contrast(&GetDocument()); - Vector<Color> colors = contrast.GetBackgroundColors(target); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); EXPECT_EQ(1u, colors.size()); EXPECT_EQ("#ff0000", colors.at(0).Serialized()); + EXPECT_EQ(1.0f, fg_opacity); } TEST_F(InspectorContrastTest, GetBackgroundColorsNoText) { @@ -55,8 +57,10 @@ GetDocument().View()->UpdateAllLifecyclePhasesForTest(); Element* target = GetDocument().getElementById("target"); InspectorContrast contrast(&GetDocument()); - Vector<Color> colors = contrast.GetBackgroundColors(target); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); EXPECT_EQ(0u, colors.size()); + EXPECT_EQ(1.0f, fg_opacity); } TEST_F(InspectorContrastTest, GetBackgroundColorsBgOpacity) { @@ -69,9 +73,11 @@ GetDocument().View()->UpdateAllLifecyclePhasesForTest(); Element* target = GetDocument().getElementById("target"); InspectorContrast contrast(&GetDocument()); - Vector<Color> colors = contrast.GetBackgroundColors(target); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); EXPECT_EQ(1u, colors.size()); EXPECT_EQ("#e5e5e5", colors.at(0).Serialized()); + EXPECT_EQ(1.0f, fg_opacity); } TEST_F(InspectorContrastTest, GetBackgroundColorsBgOpacityParent) { @@ -83,9 +89,25 @@ GetDocument().View()->UpdateAllLifecyclePhasesForTest(); Element* target = GetDocument().getElementById("target"); InspectorContrast contrast(&GetDocument()); - Vector<Color> colors = contrast.GetBackgroundColors(target); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); EXPECT_EQ(1u, colors.size()); EXPECT_EQ("#e5e5e5", colors.at(0).Serialized()); + EXPECT_EQ(0.1f, fg_opacity); +} + +TEST_F(InspectorContrastTest, GetBackgroundColorsElementWithOpacity) { + GetDocument().body()->setInnerHTML(R"HTML( + <div id="target" style="opacity: 0.1; color: black;">test</div> + )HTML"); + GetDocument().View()->UpdateAllLifecyclePhasesForTest(); + Element* target = GetDocument().getElementById("target"); + InspectorContrast contrast(&GetDocument()); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); + EXPECT_EQ(1u, colors.size()); + EXPECT_EQ("#ffffff", colors.at(0).Serialized()); + EXPECT_EQ(0.1f, fg_opacity); } TEST_F(InspectorContrastTest, GetBackgroundColorsBgHidden) { @@ -98,9 +120,11 @@ GetDocument().View()->UpdateAllLifecyclePhasesForTest(); Element* target = GetDocument().getElementById("target"); InspectorContrast contrast(&GetDocument()); - Vector<Color> colors = contrast.GetBackgroundColors(target); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); EXPECT_EQ(1u, colors.size()); EXPECT_EQ("#ffffff", colors.at(0).Serialized()); + EXPECT_EQ(1.0f, fg_opacity); } TEST_F(InspectorContrastTest, GetBackgroundColorsWithOpacity) { @@ -116,9 +140,11 @@ GetDocument().View()->UpdateAllLifecyclePhasesForTest(); Element* target = GetDocument().getElementById("target"); InspectorContrast contrast(&GetDocument()); - Vector<Color> colors = contrast.GetBackgroundColors(target); + float fg_opacity = 1.0f; + Vector<Color> colors = contrast.GetBackgroundColors(target, &fg_opacity); EXPECT_EQ(1u, colors.size()); EXPECT_EQ("#040404", colors.at(0).Serialized()); + EXPECT_EQ(1.0f, fg_opacity); } TEST_F(InspectorContrastTest, GetContrast) { @@ -129,6 +155,9 @@ <div id="target2" style="color: hsla(200,0%,0%,0.701960784313725); background-color: white;"> test </div> + <div id="target3" style="color: black; opacity: 0.1;"> + test + </div> )HTML"); GetDocument().View()->UpdateAllLifecyclePhasesForTest(); InspectorContrast contrast(&GetDocument()); @@ -139,11 +168,11 @@ EXPECT_EQ(7.0, contrast_info_1.threshold_aaa); EXPECT_FLOAT_EQ(1, contrast_info_1.contrast_ratio); ContrastInfo contrast_info_2 = - contrast.GetContrast(GetDocument().getElementById("target2")); + contrast.GetContrast(GetDocument().getElementById("target3")); EXPECT_EQ(true, contrast_info_2.able_to_compute_contrast); EXPECT_EQ(4.5, contrast_info_2.threshold_aa); EXPECT_EQ(7.0, contrast_info_2.threshold_aaa); - EXPECT_FLOAT_EQ(8.58742, contrast_info_2.contrast_ratio); + EXPECT_NEAR(1.25, contrast_info_2.contrast_ratio, 0.01); } } // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc index f7994d4a..5f842725 100644 --- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -2332,7 +2332,8 @@ String* computed_font_size, String* computed_font_weight) { InspectorContrast contrast(&element->GetDocument()); - *colors = contrast.GetBackgroundColors(element); + float text_opacity = 1.0f; + *colors = contrast.GetBackgroundColors(element, &text_opacity); auto text_info = contrast.GetTextInfo(element); *computed_font_size = text_info.font_size; *computed_font_weight = text_info.font_weight;
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index 00a730b..3e9bde7 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -438,6 +438,21 @@ return flex_config_info; } +std::unique_ptr<protocol::DictionaryValue> BuildFlexItemHighlightConfigInfo( + const InspectorFlexItemHighlightConfig& flex_config) { + std::unique_ptr<protocol::DictionaryValue> flex_config_info = + protocol::DictionaryValue::create(); + + AppendBoxStyleConfig(flex_config.base_size_box, flex_config_info, + "baseSizeBox"); + AppendLineStyleConfig(flex_config.base_size_border, flex_config_info, + "baseSizeBorder"); + AppendLineStyleConfig(flex_config.flexibility_arrow, flex_config_info, + "flexibilityArrow"); + + return flex_config_info; +} + std::unique_ptr<protocol::DictionaryValue> BuildGridHighlightConfigInfo( const InspectorGridHighlightConfig& grid_config) { std::unique_ptr<protocol::DictionaryValue> grid_config_info = @@ -699,6 +714,11 @@ layout_object.IsLayoutNGFlexibleBox(); } +bool IsLayoutNGFlexItem(const LayoutObject& layout_object) { + return IsLayoutNGFlexibleBox(*layout_object.Parent()) && + To<LayoutBox>(layout_object).IsFlexItemIncludingNG(); +} + std::unique_ptr<protocol::DictionaryValue> BuildAreaNamePaths(Node* node, float scale) { LayoutObject* layout_object = node->GetLayoutObject(); @@ -944,7 +964,7 @@ return flex_lines; } -std::unique_ptr<protocol::DictionaryValue> BuildFlexInfo( +std::unique_ptr<protocol::DictionaryValue> BuildFlexContainerInfo( Node* node, const InspectorFlexContainerHighlightConfig& flex_container_highlight_config, @@ -1032,6 +1052,39 @@ return flex_info; } +std::unique_ptr<protocol::DictionaryValue> BuildFlexItemInfo( + Node* node, + const InspectorFlexItemHighlightConfig& flex_item_highlight_config, + float scale) { + std::unique_ptr<protocol::DictionaryValue> flex_info = + protocol::DictionaryValue::create(); + + LayoutObject* layout_object = node->GetLayoutObject(); + Length base_size = Length::Auto(); + + const Length& flex_basis = layout_object->StyleRef().FlexBasis(); + const Length& size = IsHorizontalFlex(layout_object->Parent()) + ? layout_object->StyleRef().Width() + : layout_object->StyleRef().Height(); + + if (flex_basis.IsFixed()) { + base_size = flex_basis; + } else if (flex_basis.IsAuto() && size.IsFixed()) { + base_size = size; + } + + // For now, we only care about the cases where we can know the base size. + if (base_size.IsSpecified()) { + flex_info->setDouble("baseSize", base_size.Pixels() * scale); + + flex_info->setValue( + "flexItemHighlightConfig", + BuildFlexItemHighlightConfigInfo(flex_item_highlight_config)); + } + + return flex_info; +} + std::unique_ptr<protocol::DictionaryValue> BuildGridInfo( Node* node, const InspectorGridHighlightConfig& grid_highlight_config, @@ -1314,6 +1367,8 @@ InspectorFlexContainerHighlightConfig::InspectorFlexContainerHighlightConfig() = default; +InspectorFlexItemHighlightConfig::InspectorFlexItemHighlightConfig() = default; + InspectorHighlightBase::InspectorHighlightBase(float scale) : highlight_paths_(protocol::ListValue::create()), scale_(scale) {} @@ -1684,14 +1739,22 @@ } if (highlight_config.flex_container_highlight_config) { - flex_info_ = protocol::ListValue::create(); + flex_container_info_ = protocol::ListValue::create(); // Some objects are flexible boxes even though display:flex is not set, we // need to avoid those. if (IsLayoutNGFlexibleBox(*layout_object)) { - flex_info_->pushValue(BuildFlexInfo( + flex_container_info_->pushValue(BuildFlexContainerInfo( node, *(highlight_config.flex_container_highlight_config), scale_)); } } + + if (highlight_config.flex_item_highlight_config) { + flex_item_info_ = protocol::ListValue::create(); + if (IsLayoutNGFlexItem(*layout_object)) { + flex_item_info_->pushValue(BuildFlexItemInfo( + node, *(highlight_config.flex_item_highlight_config), scale_)); + } + } } std::unique_ptr<protocol::DictionaryValue> InspectorHighlight::AsProtocolValue() @@ -1737,8 +1800,10 @@ object->setValue("elementInfo", element_info_->clone()); if (grid_info_ && grid_info_->size() > 0) object->setValue("gridInfo", grid_info_->clone()); - if (flex_info_ && flex_info_->size() > 0) - object->setValue("flexInfo", flex_info_->clone()); + if (flex_container_info_ && flex_container_info_->size() > 0) + object->setValue("flexInfo", flex_container_info_->clone()); + if (flex_item_info_ && flex_item_info_->size() > 0) + object->setValue("flexItemInfo", flex_item_info_->clone()); return object; } @@ -1902,7 +1967,7 @@ return nullptr; } - return BuildFlexInfo(node, config, scale); + return BuildFlexContainerInfo(node, config, scale); } // static @@ -1927,6 +1992,9 @@ config.flex_container_highlight_config = std::make_unique<InspectorFlexContainerHighlightConfig>( InspectorHighlight::DefaultFlexContainerConfig()); + config.flex_item_highlight_config = + std::make_unique<InspectorFlexItemHighlightConfig>( + InspectorHighlight::DefaultFlexItemConfig()); return config; } @@ -1978,6 +2046,18 @@ } // static +InspectorFlexItemHighlightConfig InspectorHighlight::DefaultFlexItemConfig() { + InspectorFlexItemHighlightConfig config; + config.base_size_box = + base::Optional<BoxStyle>(InspectorHighlight::DefaultBoxStyle()); + config.base_size_border = + base::Optional<LineStyle>(InspectorHighlight::DefaultLineStyle()); + config.flexibility_arrow = + base::Optional<LineStyle>(InspectorHighlight::DefaultLineStyle()); + return config; +} + +// static LineStyle InspectorHighlight::DefaultLineStyle() { LineStyle style; style.color = Color(255, 0, 0, 0);
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h index a39b487..0c4c98c 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.h +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -102,6 +102,17 @@ base::Optional<LineStyle> cross_alignment; }; +struct CORE_EXPORT InspectorFlexItemHighlightConfig { + USING_FAST_MALLOC(InspectorFlexItemHighlightConfig); + + public: + InspectorFlexItemHighlightConfig(); + + base::Optional<BoxStyle> base_size_box; + base::Optional<LineStyle> base_size_border; + base::Optional<LineStyle> flexibility_arrow; +}; + struct CORE_EXPORT InspectorHighlightConfig { USING_FAST_MALLOC(InspectorHighlightConfig); @@ -131,6 +142,7 @@ std::unique_ptr<InspectorGridHighlightConfig> grid_highlight_config; std::unique_ptr<InspectorFlexContainerHighlightConfig> flex_container_highlight_config; + std::unique_ptr<InspectorFlexItemHighlightConfig> flex_item_highlight_config; }; struct InspectorHighlightContrastInfo { @@ -199,6 +211,7 @@ static InspectorHighlightConfig DefaultConfig(); static InspectorGridHighlightConfig DefaultGridConfig(); static InspectorFlexContainerHighlightConfig DefaultFlexContainerConfig(); + static InspectorFlexItemHighlightConfig DefaultFlexItemConfig(); void AppendEventTargetQuads(Node* event_target_node, const InspectorHighlightConfig&); std::unique_ptr<protocol::DictionaryValue> AsProtocolValue() const override; @@ -223,7 +236,8 @@ std::unique_ptr<protocol::DictionaryValue> distance_info_; std::unique_ptr<protocol::DictionaryValue> element_info_; std::unique_ptr<protocol::ListValue> grid_info_; - std::unique_ptr<protocol::ListValue> flex_info_; + std::unique_ptr<protocol::ListValue> flex_container_info_; + std::unique_ptr<protocol::ListValue> flex_item_info_; bool show_rulers_; bool show_extension_lines_; bool show_accessibility_info_;
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index 28ee986..16e21a7 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -1553,6 +1553,26 @@ } // static +std::unique_ptr<InspectorFlexItemHighlightConfig> +InspectorOverlayAgent::ToFlexItemHighlightConfig( + protocol::Overlay::FlexItemHighlightConfig* config) { + if (!config) { + return nullptr; + } + std::unique_ptr<InspectorFlexItemHighlightConfig> highlight_config = + std::make_unique<InspectorFlexItemHighlightConfig>(); + + highlight_config->base_size_box = + InspectorOverlayAgent::ToBoxStyle(config->getBaseSizeBox(nullptr)); + highlight_config->base_size_border = + InspectorOverlayAgent::ToLineStyle(config->getBaseSizeBorder(nullptr)); + highlight_config->flexibility_arrow = + InspectorOverlayAgent::ToLineStyle(config->getFlexibilityArrow(nullptr)); + + return highlight_config; +} + +// static base::Optional<LineStyle> InspectorOverlayAgent::ToLineStyle( protocol::Overlay::LineStyle* config) { if (!config) { @@ -1643,6 +1663,11 @@ highlight_config->flex_container_highlight_config = InspectorOverlayAgent::ToFlexContainerHighlightConfig( config->getFlexContainerHighlightConfig(nullptr)); + + highlight_config->flex_item_highlight_config = + InspectorOverlayAgent::ToFlexItemHighlightConfig( + config->getFlexItemHighlightConfig(nullptr)); + return highlight_config; }
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h index ca25054..0557bc5 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -149,6 +149,8 @@ static std::unique_ptr<InspectorFlexContainerHighlightConfig> ToFlexContainerHighlightConfig( protocol::Overlay::FlexContainerHighlightConfig*); + static std::unique_ptr<InspectorFlexItemHighlightConfig> + ToFlexItemHighlightConfig(protocol::Overlay::FlexItemHighlightConfig*); static base::Optional<LineStyle> ToLineStyle(protocol::Overlay::LineStyle*); static base::Optional<BoxStyle> ToBoxStyle(protocol::Overlay::BoxStyle*); static std::unique_ptr<InspectorHighlightConfig> ToHighlightConfig(
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc index cb9d926..a948b79 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc
@@ -42,7 +42,7 @@ window->Url(), mojom::blink::ScriptType::kModule, global_scope_name, window->UserAgent(), frame->Client()->UserAgentMetadata(), frame->Client()->CreateWorkerFetchContext(), - window->GetContentSecurityPolicy()->GetParsedPolicies(), + mojo::Clone(window->GetContentSecurityPolicy()->GetParsedPolicies()), window->GetReferrerPolicy(), window->GetSecurityOrigin(), window->IsSecureContext(), window->GetHttpsState(), nullptr /* worker_clients */,
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc index f07d5eb7..986808d6 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -819,10 +819,6 @@ grid_item.item_type = node.IsOutOfFlowPositioned() ? ItemType::kOutOfFlow : ItemType::kInGridFlow; - grid_item.has_baseline_alignment = - (item_style.ResolvedAlignSelf(normal_behaviour, &container_style) - .GetPosition() == ItemPosition::kBaseline); - return grid_item; } @@ -1962,7 +1958,7 @@ }; LayoutUnit baseline = fragment.BaselineOrSynthesize() + offset.block_offset; - if (grid_item.has_baseline_alignment) { + if (grid_item.block_axis_alignment == AxisEdge::kBaseline) { if (!alignment_baseline || IsBeforeInGridOrder(grid_item.resolved_position, alignment_baseline->resolved_position)) {
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h index 5db08ed..1a75b48 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -87,8 +87,6 @@ bool is_inline_axis_stretched; bool is_block_axis_stretched; - bool has_baseline_alignment; - TrackSpanProperties column_span_properties; TrackSpanProperties row_span_properties;
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc index 5d026b5f..5c193a7 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -160,9 +160,11 @@ ContentSecurityPolicy* policy = execution_context_->GetContentSecurityPolicy(); policy->DidReceiveHeader("script-src https://foo.test", + *(execution_context_->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); policy->DidReceiveHeader("script-src https://bar.test", + *(execution_context_->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kReport, network::mojom::ContentSecurityPolicySource::kHTTP); @@ -185,9 +187,11 @@ ContentSecurityPolicy* policy = execution_context_->GetContentSecurityPolicy(); policy->DidReceiveHeader("script-src https://foo.test", + *(execution_context_->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); policy->DidReceiveHeader("script-src https://bar.test", + *(execution_context_->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kReport, network::mojom::ContentSecurityPolicySource::kHTTP); @@ -301,6 +305,7 @@ ContentSecurityPolicy* policy = execution_context_->GetContentSecurityPolicy(); policy->DidReceiveHeader("default-src 'self'", + *(execution_context_->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP);
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 53028899..0f513bf 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -136,6 +136,7 @@ namespace { void ApplyOriginPolicy(ContentSecurityPolicy* csp, + const KURL& response_url, const WebOriginPolicy& origin_policy) { // When this function is called. The following lines of code happen // consecutively: @@ -151,16 +152,23 @@ DCHECK(!csp->HasPolicyFromSource( network::mojom::ContentSecurityPolicySource::kOriginPolicy)); + DCHECK(response_url.ProtocolIsInHTTPFamily()); + + scoped_refptr<SecurityOrigin> self_origin = + SecurityOrigin::Create(response_url); + for (const auto& policy : origin_policy.content_security_policies) { csp->DidReceiveHeader( - policy, network::mojom::ContentSecurityPolicyType::kEnforce, + policy, *self_origin, + network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kOriginPolicy); } for (const auto& policy : origin_policy.content_security_policies_report_only) { csp->DidReceiveHeader( - policy, network::mojom::ContentSecurityPolicyType::kReport, + policy, *self_origin, + network::mojom::ContentSecurityPolicyType::kReport, network::mojom::ContentSecurityPolicySource::kOriginPolicy); } } @@ -730,7 +738,7 @@ ->ExperimentalFeaturesEnabled()) { ContentSecurityPolicy* origin_window_csp = origin_window->GetContentSecurityPolicy(); - initiator_csp = origin_window_csp->GetParsedPolicies(); + initiator_csp = mojo::Clone(origin_window_csp->GetParsedPolicies()); NavigationInitiatorImpl::From(*origin_window) .BindReceiver(navigation_initiator.InitWithNewPipeAndPassReceiver()); } @@ -1036,8 +1044,10 @@ DCHECK(content_security_policy); for (auto& csp : navigation_params->forced_content_security_policies) { + scoped_refptr<SecurityOrigin> self_origin = + SecurityOrigin::Create(navigation_params->url); content_security_policy->DidReceiveHeader( - csp, network::mojom::ContentSecurityPolicyType::kEnforce, + csp, *self_origin, network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); } @@ -1802,7 +1812,6 @@ // iframe/popup's script at a fine-grained level. ContentSecurityPolicy* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->SetOverrideURLForSelf(response.CurrentRequestUrl()); if (frame_->GetSettings()->GetBypassCSP()) return csp; // Empty CSP. @@ -1812,7 +1821,7 @@ // Retrieve CSP stored in the OriginPolicy. if (origin_policy) - ApplyOriginPolicy(csp, origin_policy.value()); + ApplyOriginPolicy(csp, url, origin_policy.value()); // Plugin inherits plugin's CSP from their navigation initiator. DocumentInit::Type document_type =
diff --git a/third_party/blink/renderer/core/loader/http_equiv.cc b/third_party/blink/renderer/core/loader/http_equiv.cc index f39ba93..a36a76e 100644 --- a/third_party/blink/renderer/core/loader/http_equiv.cc +++ b/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -101,12 +101,14 @@ return; if (EqualIgnoringASCIICase(equiv, "content-security-policy")) { window->GetContentSecurityPolicy()->DidReceiveHeader( - content, network::mojom::ContentSecurityPolicyType::kEnforce, + content, *(window->GetSecurityOrigin()), + network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kMeta); } else if (EqualIgnoringASCIICase(equiv, "content-security-policy-report-only")) { window->GetContentSecurityPolicy()->DidReceiveHeader( - content, network::mojom::ContentSecurityPolicyType::kReport, + content, *(window->GetSecurityOrigin()), + network::mojom::ContentSecurityPolicyType::kReport, network::mojom::ContentSecurityPolicySource::kMeta); } else { NOTREACHED();
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index 1693ea5b..a335cb8 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -377,9 +377,11 @@ dummy_page_holder_->GetFrame() .DomWindow() ->GetContentSecurityPolicy() - ->DidReceiveHeader(test_case.content_security_policy, - network::mojom::ContentSecurityPolicyType::kEnforce, - network::mojom::ContentSecurityPolicySource::kHTTP); + ->DidReceiveHeader( + test_case.content_security_policy, + *(dummy_page_holder_->GetFrame().DomWindow()->GetSecurityOrigin()), + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP); LinkLoadParameters params( LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, String(), "script", String(), test_case.nonce, String(), String(),
diff --git a/third_party/blink/renderer/core/mojo/BUILD.gn b/third_party/blink/renderer/core/mojo/BUILD.gn deleted file mode 100644 index ecbb304..0000000 --- a/third_party/blink/renderer/core/mojo/BUILD.gn +++ /dev/null
@@ -1,38 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") -import("//third_party/blink/renderer/core/core.gni") - -source_set("unit_tests") { - testonly = true - sources = [ "tests/js_to_cpp_test.cc" ] - - data = [ "tests/JsToCppTest.js" ] - - configs += [ - "//third_party/blink/renderer/core:blink_core_pch", - "//third_party/blink/renderer:config", - "//third_party/blink/renderer:inside_blink", - ] - - deps = [ - ":test_bindings_blink", - "//mojo/public/cpp/bindings", - "//testing/gtest", - "//third_party/blink/renderer/controller:blink_bindings_test_sources", - "//third_party/blink/renderer/core:core", - "//third_party/blink/renderer/core:testing", - "//third_party/blink/renderer/platform:test_support", - ] - - data_deps = [ - ":test_bindings_js_data_deps", - "//mojo/public/js:bindings", - ] -} - -mojom("test_bindings") { - sources = [ "tests/js_to_cpp.mojom" ] -}
diff --git a/third_party/blink/renderer/core/mojo/tests/JsToCppTest.js b/third_party/blink/renderer/core/mojo/tests/JsToCppTest.js deleted file mode 100644 index 139687a..0000000 --- a/third_party/blink/renderer/core/mojo/tests/JsToCppTest.js +++ /dev/null
@@ -1,205 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(function () { - var retainedJsSide; - var sampleData; - var sampleMessage; - var BAD_VALUE = 13; - var DATA_PIPE_PARAMS = { - elementNumBytes: 1, - capacityNumBytes: 64 - }; - - function JsSideConnection() { - this.binding = new mojo.Binding(jsToCpp.JsSide, this); - } - - JsSideConnection.prototype.setCppSide = function(cppSide) { - this.cppSide_ = cppSide; - this.cppSide_.startTest(); - }; - - JsSideConnection.prototype.ping = function (arg) { - this.cppSide_.pingResponse(); - }; - - JsSideConnection.prototype.echo = function (numIterations, arg) { - var dataPipe1; - var dataPipe2; - var i; - var messagePipe1; - var messagePipe2; - var specialArg; - - // Ensure expected negative values are negative. - if (arg.si64 > 0) - arg.si64 = BAD_VALUE; - - if (arg.si32 > 0) - arg.si32 = BAD_VALUE; - - if (arg.si16 > 0) - arg.si16 = BAD_VALUE; - - if (arg.si8 > 0) - arg.si8 = BAD_VALUE; - - for (i = 0; i < numIterations; ++i) { - dataPipe1 = Mojo.createDataPipe(DATA_PIPE_PARAMS); - dataPipe2 = Mojo.createDataPipe(DATA_PIPE_PARAMS); - messagePipe1 = Mojo.createMessagePipe(); - messagePipe2 = Mojo.createMessagePipe(); - - arg.dataHandle = dataPipe1.consumer; - arg.messageHandle = messagePipe1.handle1; - - specialArg = new jsToCpp.EchoArgs(); - specialArg.si64 = -1; - specialArg.si32 = -1; - specialArg.si16 = -1; - specialArg.si8 = -1; - specialArg.name = 'going'; - specialArg.dataHandle = dataPipe2.consumer; - specialArg.messageHandle = messagePipe2.handle1; - - writeDataPipe(dataPipe1, sampleData); - writeDataPipe(dataPipe2, sampleData); - writeMessagePipe(messagePipe1, sampleMessage); - writeMessagePipe(messagePipe2, sampleMessage); - this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg)); - - dataPipe1.producer.close(); - dataPipe2.producer.close(); - messagePipe1.handle0.close(); - messagePipe2.handle0.close(); - } - this.cppSide_.testFinished(); - }; - - JsSideConnection.prototype.bitFlip = function (arg) { - var iteration = 0; - var dataPipe; - var messagePipe; - var proto = mojo.internal.Connector.prototype; - var stopSignalled = false; - - proto.realAccept = proto.accept; - proto.accept = function (message) { - var offset = iteration / 8; - var mask; - var value; - if (offset < message.buffer.arrayBuffer.byteLength) { - mask = 1 << (iteration % 8); - value = message.buffer.getUint8(offset) ^ mask; - message.buffer.setUint8(offset, value); - return this.realAccept(message); - } - stopSignalled = true; - return false; - }; - - while (!stopSignalled) { - messagePipe = Mojo.createMessagePipe(); - writeMessagePipe(messagePipe, sampleMessage); - arg.messageHandle = messagePipe.handle1; - - this.cppSide_.bitFlipResponse(createEchoArgsList(arg), null); - - messagePipe.handle0.close(); - iteration += 1; - } - - proto.accept = proto.realAccept; - proto.realAccept = null; - this.cppSide_.testFinished(); - }; - - JsSideConnection.prototype.backPointer = function (arg) { - var iteration = 0; - var dataPipe; - var messagePipe; - var proto = mojo.internal.Connector.prototype; - var stopSignalled = false; - - proto.realAccept = proto.accept; - proto.accept = function (message) { - var delta = 8 * (1 + iteration % 32); - var offset = 8 * ((iteration / 32) | 0); - if (offset < message.buffer.arrayBuffer.byteLength - 4) { - message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true); - message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true); - return this.realAccept(message); - } - stopSignalled = true; - return false; - }; - - while (!stopSignalled) { - messagePipe = Mojo.createMessagePipe(); - writeMessagePipe(messagePipe, sampleMessage); - arg.messageHandle = messagePipe.handle1; - - this.cppSide_.backPointerResponse(createEchoArgsList(arg)); - - messagePipe.handle0.close(); - iteration += 1; - } - - proto.accept = proto.realAccept; - proto.realAccept = null; - this.cppSide_.testFinished(); - }; - - function writeDataPipe(pipe, data) { - var writeResult = pipe.producer.writeData(data); - - if (writeResult.result != Mojo.RESULT_OK) { - console.log('ERROR: Data pipe write result was ' + writeResult.result); - return false; - } - if (writeResult.numBytes != data.length) { - console.log('ERROR: Data pipe write length was ' + writeResult.numBytes); - return false; - } - return true; - } - - function writeMessagePipe(pipe, arrayBuffer) { - var result = pipe.handle0.writeMessage(arrayBuffer, []); - if (result != Mojo.RESULT_OK) { - console.log('ERROR: Message pipe write result was ' + result); - return false; - } - return true; - } - - function createEchoArgsListElement(item, next) { - var list = new jsToCpp.EchoArgsList(); - list.item = item; - list.next = next; - return list; - } - - function createEchoArgsList() { - var genuineArray = Array.prototype.slice.call(arguments); - return genuineArray.reduceRight(function (previous, current) { - return createEchoArgsListElement(current, previous); - }, null); - } - - return function(jsSideRequestHandle) { - var i; - sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes); - for (i = 0; i < sampleData.length; ++i) { - sampleData[i] = i; - } - sampleMessage = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes); - for (i = 0; i < sampleMessage.length; ++i) { - sampleMessage[i] = 255 - i; - } - retainedJsSide = new JsSideConnection; - retainedJsSide.binding.bind(jsSideRequestHandle); - }; -})();
diff --git a/third_party/blink/renderer/core/mojo/tests/OWNERS b/third_party/blink/renderer/core/mojo/tests/OWNERS deleted file mode 100644 index 08850f4..0000000 --- a/third_party/blink/renderer/core/mojo/tests/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/renderer/core/mojo/tests/js_to_cpp.mojom b/third_party/blink/renderer/core/mojo/tests/js_to_cpp.mojom deleted file mode 100644 index ca63916..0000000 --- a/third_party/blink/renderer/core/mojo/tests/js_to_cpp.mojom +++ /dev/null
@@ -1,61 +0,0 @@ -module js_to_cpp; - -// This struct encompasses all of the basic types, so that they -// may be sent from C++ to JS and back for validation. -struct EchoArgs { - int64 si64; - int32 si32; - int16 si16; - int8 si8; - uint64 ui64; - uint32 ui32; - uint16 ui16; - uint8 ui8; - float float_val; - float float_inf; - float float_nan; - double double_val; - double double_inf; - double double_nan; - string? name; - array<string>? string_array; - handle<message_pipe>? message_handle; - handle<data_pipe_consumer>? data_handle; -}; - -struct EchoArgsList { - EchoArgsList? next; - EchoArgs? item; -}; - -interface ForTesting {}; - -// Note: For messages which control test flow, pick numbers that are unlikely -// to be hit as a result of our deliberate corruption of response messages. -interface CppSide { - // Sent for all tests to notify that the JS side is now ready. - StartTest@88888888(); - - // Indicates end for echo, bit-flip, and back-pointer tests. - TestFinished@99999999(); - - // Responses from specific tests. - PingResponse(); - EchoResponse(EchoArgsList list); - - // Having an associated remote in the message makes sure the message header - // version 2 is tested. - BitFlipResponse(EchoArgsList arg, - pending_associated_remote<ForTesting>? not_used); - - BackPointerResponse(EchoArgsList arg); -}; - -interface JsSide { - SetCppSide(pending_remote<CppSide> cpp); - - Ping(); - Echo(int32 numIterations, EchoArgs arg); - BitFlip(EchoArgs arg); - BackPointer(EchoArgs arg); -};
diff --git a/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc b/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc deleted file mode 100644 index 101c77fa..0000000 --- a/third_party/blink/renderer/core/mojo/tests/js_to_cpp_test.cc +++ /dev/null
@@ -1,437 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/stl_util.h" -#include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/system/wait.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" -#include "third_party/blink/renderer/core/frame/settings.h" -#include "third_party/blink/renderer/core/mojo/mojo_handle.h" -#include "third_party/blink/renderer/core/mojo/tests/js_to_cpp.mojom-blink.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/script/classic_script.h" -#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" -#include "third_party/blink/renderer/platform/wtf/shared_buffer.h" - -namespace blink { -namespace { - -// Global value updated by some checks to prevent compilers from optimizing -// reads out of existence. -uint32_t g_waste_accumulator = 0; - -// Negative numbers with different values in each byte, the last of -// which can survive promotion to double and back. -const int8_t kExpectedInt8Value = -65; -const int16_t kExpectedInt16Value = -16961; -const int32_t kExpectedInt32Value = -1145258561; -const int64_t kExpectedInt64Value = -77263311946305LL; - -// Positive numbers with different values in each byte, the last of -// which can survive promotion to double and back. -const uint8_t kExpectedUInt8Value = 65; -const uint16_t kExpectedUInt16Value = 16961; -const uint32_t kExpectedUInt32Value = 1145258561; -const uint64_t kExpectedUInt64Value = 77263311946305LL; - -// Double/float values, including special case constants. -const double kExpectedDoubleVal = 3.14159265358979323846; -const double kExpectedDoubleInf = std::numeric_limits<double>::infinity(); -const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN(); -const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal); -const float kExpectedFloatInf = std::numeric_limits<float>::infinity(); -const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN(); - -// NaN has the property that it is not equal to itself. -#define EXPECT_NAN(x) EXPECT_NE(x, x) - -String MojoBindingsScriptPath() { - return test::ExecutableDir() + "/gen/mojo/public/js/mojo_bindings.js"; -} - -String TestBindingsScriptPath() { - return test::ExecutableDir() + - "/gen/third_party/blink/renderer/core/mojo/tests/js_to_cpp.mojom.js"; -} - -String TestScriptPath() { - return test::BlinkRootDir() + "/renderer/core/mojo/tests/JsToCppTest.js"; -} - -v8::Local<v8::Value> ExecuteScript(const String& script_path, - LocalDOMWindow& window) { - scoped_refptr<SharedBuffer> script_src = test::ReadFromFile(script_path); - return ClassicScript::CreateUnspecifiedScript( - ScriptSourceCode(String(script_src->Data(), script_src->size()))) - ->RunScriptAndReturnValue(&window); -} - -void CheckDataPipe(mojo::DataPipeConsumerHandle data_pipe_handle) { - MojoResult result = Wait(data_pipe_handle, MOJO_HANDLE_SIGNAL_READABLE); - EXPECT_EQ(MOJO_RESULT_OK, result); - - const void* buffer = nullptr; - unsigned num_bytes = 0; - result = data_pipe_handle.BeginReadData(&buffer, &num_bytes, - MOJO_READ_DATA_FLAG_NONE); - EXPECT_EQ(MOJO_RESULT_OK, result); - EXPECT_EQ(64u, num_bytes); - for (unsigned i = 0; i < num_bytes; ++i) { - EXPECT_EQ(i, static_cast<unsigned>(static_cast<const char*>(buffer)[i])); - } - data_pipe_handle.EndReadData(num_bytes); -} - -void CheckMessagePipe(mojo::MessagePipeHandle message_pipe_handle) { - MojoResult result = Wait(message_pipe_handle, MOJO_HANDLE_SIGNAL_READABLE); - EXPECT_EQ(MOJO_RESULT_OK, result); - - std::vector<uint8_t> bytes; - std::vector<mojo::ScopedHandle> handles; - result = ReadMessageRaw(message_pipe_handle, &bytes, &handles, 0); - EXPECT_EQ(MOJO_RESULT_OK, result); - EXPECT_EQ(64u, bytes.size()); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(255 - i, bytes[i]); - } -} - -js_to_cpp::blink::EchoArgsPtr BuildSampleEchoArgs() { - auto args = js_to_cpp::blink::EchoArgs::New(); - args->si64 = kExpectedInt64Value; - args->si32 = kExpectedInt32Value; - args->si16 = kExpectedInt16Value; - args->si8 = kExpectedInt8Value; - args->ui64 = kExpectedUInt64Value; - args->ui32 = kExpectedUInt32Value; - args->ui16 = kExpectedUInt16Value; - args->ui8 = kExpectedUInt8Value; - args->float_val = kExpectedFloatVal; - args->float_inf = kExpectedFloatInf; - args->float_nan = kExpectedFloatNan; - args->double_val = kExpectedDoubleVal; - args->double_inf = kExpectedDoubleInf; - args->double_nan = kExpectedDoubleNan; - args->name = "coming"; - args->string_array.emplace(3); - (*args->string_array)[0] = "one"; - (*args->string_array)[1] = "two"; - (*args->string_array)[2] = "three"; - return args; -} - -void CheckSampleEchoArgs(const js_to_cpp::blink::EchoArgsPtr& arg) { - EXPECT_EQ(kExpectedInt64Value, arg->si64); - EXPECT_EQ(kExpectedInt32Value, arg->si32); - EXPECT_EQ(kExpectedInt16Value, arg->si16); - EXPECT_EQ(kExpectedInt8Value, arg->si8); - EXPECT_EQ(kExpectedUInt64Value, arg->ui64); - EXPECT_EQ(kExpectedUInt32Value, arg->ui32); - EXPECT_EQ(kExpectedUInt16Value, arg->ui16); - EXPECT_EQ(kExpectedUInt8Value, arg->ui8); - EXPECT_EQ(kExpectedFloatVal, arg->float_val); - EXPECT_EQ(kExpectedFloatInf, arg->float_inf); - EXPECT_NAN(arg->float_nan); - EXPECT_EQ(kExpectedDoubleVal, arg->double_val); - EXPECT_EQ(kExpectedDoubleInf, arg->double_inf); - EXPECT_NAN(arg->double_nan); - EXPECT_EQ(String("coming"), arg->name); - EXPECT_EQ(String("one"), (*arg->string_array)[0]); - EXPECT_EQ(String("two"), (*arg->string_array)[1]); - EXPECT_EQ(String("three"), (*arg->string_array)[2]); - CheckDataPipe(arg->data_handle.get()); - CheckMessagePipe(arg->message_handle.get()); -} - -void CheckSampleEchoArgsList(const js_to_cpp::blink::EchoArgsListPtr& list) { - if (list.is_null()) - return; - CheckSampleEchoArgs(list->item); - CheckSampleEchoArgsList(list->next); -} - -// More forgiving checks are needed in the face of potentially corrupt -// messages. The values don't matter so long as all accesses are within -// bounds. -void CheckCorruptedString(const String& arg) { - for (wtf_size_t i = 0; i < arg.length(); ++i) - g_waste_accumulator += arg[i]; -} - -void CheckCorruptedStringArray( - const base::Optional<Vector<String>>& string_array) { - if (!string_array) - return; - for (const String& element : *string_array) - CheckCorruptedString(element); -} - -void CheckCorruptedDataPipe(mojo::DataPipeConsumerHandle data_pipe_handle) { - unsigned char buffer[100]; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - MojoResult result = - data_pipe_handle.ReadData(buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE); - if (result != MOJO_RESULT_OK) - return; - for (uint32_t i = 0; i < buffer_size; ++i) - g_waste_accumulator += buffer[i]; -} - -void CheckCorruptedMessagePipe(mojo::MessagePipeHandle message_pipe_handle) { - std::vector<uint8_t> bytes; - std::vector<mojo::ScopedHandle> handles; - MojoResult result = ReadMessageRaw(message_pipe_handle, &bytes, &handles, 0); - if (result != MOJO_RESULT_OK) - return; - for (uint32_t i = 0; i < bytes.size(); ++i) - g_waste_accumulator += bytes[i]; -} - -void CheckCorruptedEchoArgs(const js_to_cpp::blink::EchoArgsPtr& arg) { - if (arg.is_null()) - return; - CheckCorruptedString(arg->name); - CheckCorruptedStringArray(arg->string_array); - if (arg->data_handle.is_valid()) - CheckCorruptedDataPipe(arg->data_handle.get()); - if (arg->message_handle.is_valid()) - CheckCorruptedMessagePipe(arg->message_handle.get()); -} - -void CheckCorruptedEchoArgsList(const js_to_cpp::blink::EchoArgsListPtr& list) { - if (list.is_null()) - return; - CheckCorruptedEchoArgs(list->item); - CheckCorruptedEchoArgsList(list->next); -} - -// Base Provider implementation class. It's expected that tests subclass and -// override the appropriate Provider functions. When test is done quit the -// run_loop(). -class CppSideConnection : public js_to_cpp::blink::CppSide { - public: - CppSideConnection() : mishandled_messages_(0) {} - ~CppSideConnection() override = default; - - void set_js_side(mojo::Remote<js_to_cpp::blink::JsSide> js_side) { - js_side_ = std::move(js_side); - } - - void Bind(mojo::PendingReceiver<js_to_cpp::blink::CppSide> receiver) { - receiver_.Bind(std::move(receiver)); - // Keep the pipe open even after validation errors. - receiver_.EnableTestingMode(); - } - - // js_to_cpp::CppSide: - void StartTest() override { NOTREACHED(); } - - void TestFinished() override { NOTREACHED(); } - - void PingResponse() override { mishandled_messages_ += 1; } - - void EchoResponse(js_to_cpp::blink::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - void BitFlipResponse( - js_to_cpp::blink::EchoArgsListPtr list, - mojo::PendingAssociatedRemote<js_to_cpp::blink::ForTesting> not_used) - override { - mishandled_messages_ += 1; - } - - void BackPointerResponse(js_to_cpp::blink::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - protected: - mojo::Remote<js_to_cpp::blink::JsSide> js_side_; - int mishandled_messages_; - mojo::Receiver<js_to_cpp::blink::CppSide> receiver_{this}; -}; - -// Trivial test to verify a message sent from JS is received. -class PingCppSideConnection : public CppSideConnection { - public: - PingCppSideConnection() : got_message_(false) {} - ~PingCppSideConnection() override = default; - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->Ping(); } - - void PingResponse() override { - got_message_ = true; - test::ExitRunLoop(); - } - - bool DidSucceed() { return got_message_ && !mishandled_messages_; } - - private: - bool got_message_; -}; - -// Test that parameters are passed with correct values. -class EchoCppSideConnection : public CppSideConnection { - public: - EchoCppSideConnection() : message_count_(0), termination_seen_(false) {} - ~EchoCppSideConnection() override = default; - - // js_to_cpp::CppSide: - void StartTest() override { - js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs()); - } - - void EchoResponse(js_to_cpp::blink::EchoArgsListPtr list) override { - message_count_ += 1; - - const js_to_cpp::blink::EchoArgsPtr& special_arg = list->item; - EXPECT_EQ(-1, special_arg->si64); - EXPECT_EQ(-1, special_arg->si32); - EXPECT_EQ(-1, special_arg->si16); - EXPECT_EQ(-1, special_arg->si8); - EXPECT_EQ(String("going"), special_arg->name); - CheckDataPipe(special_arg->data_handle.get()); - CheckMessagePipe(special_arg->message_handle.get()); - - CheckSampleEchoArgsList(list->next); - } - - void TestFinished() override { - termination_seen_ = true; - test::ExitRunLoop(); - } - - bool DidSucceed() { - return termination_seen_ && !mishandled_messages_ && - message_count_ == kExpectedMessageCount; - } - - private: - static const int kExpectedMessageCount = 10; - int message_count_; - bool termination_seen_; -}; - -// Test that corrupted messages don't wreak havoc. -class BitFlipCppSideConnection : public CppSideConnection { - public: - BitFlipCppSideConnection() : termination_seen_(false) {} - ~BitFlipCppSideConnection() override = default; - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); } - - void BitFlipResponse( - js_to_cpp::blink::EchoArgsListPtr list, - mojo::PendingAssociatedRemote<js_to_cpp::blink::ForTesting> not_used) - override { - CheckCorruptedEchoArgsList(list); - } - - void TestFinished() override { - termination_seen_ = true; - test::ExitRunLoop(); - } - - bool DidSucceed() { return termination_seen_; } - - private: - bool termination_seen_; -}; - -// Test that severely random messages don't wreak havoc. -class BackPointerCppSideConnection : public CppSideConnection { - public: - BackPointerCppSideConnection() : termination_seen_(false) {} - ~BackPointerCppSideConnection() override = default; - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); } - - void BackPointerResponse(js_to_cpp::blink::EchoArgsListPtr list) override { - CheckCorruptedEchoArgsList(list); - } - - void TestFinished() override { - termination_seen_ = true; - test::ExitRunLoop(); - } - - bool DidSucceed() { return termination_seen_; } - - private: - bool termination_seen_; -}; - -class JsToCppTest : public testing::Test { - public: - void RunTest(CppSideConnection* cpp_side) { - mojo::PendingRemote<js_to_cpp::blink::CppSide> cpp_side_remote; - cpp_side->Bind(cpp_side_remote.InitWithNewPipeAndPassReceiver()); - - mojo::Remote<js_to_cpp::blink::JsSide> js_side_remote; - auto js_side_receiver = js_side_remote.BindNewPipeAndPassReceiver(); - js_side_remote->SetCppSide(std::move(cpp_side_remote)); - cpp_side->set_js_side(std::move(js_side_remote)); - - V8TestingScope scope; - scope.GetPage().GetSettings().SetScriptEnabled(true); - ExecuteScript(MojoBindingsScriptPath(), scope.GetWindow()); - ExecuteScript(TestBindingsScriptPath(), scope.GetWindow()); - - v8::Local<v8::Value> start_fn = - ExecuteScript(TestScriptPath(), scope.GetWindow()); - ASSERT_FALSE(start_fn.IsEmpty()); - ASSERT_TRUE(start_fn->IsFunction()); - v8::Local<v8::Object> global_proxy = scope.GetContext()->Global(); - v8::Local<v8::Value> args[1] = { - ToV8(MakeGarbageCollected<MojoHandle>( - mojo::ScopedHandle::From(js_side_receiver.PassPipe())), - global_proxy, scope.GetIsolate())}; - V8ScriptRunner::CallFunction(start_fn.As<v8::Function>(), - scope.GetExecutionContext(), global_proxy, - base::size(args), args, scope.GetIsolate()); - test::EnterRunLoop(); - } -}; - -TEST_F(JsToCppTest, Ping) { - PingCppSideConnection cpp_side_connection; - RunTest(&cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, Echo) { - EchoCppSideConnection cpp_side_connection; - RunTest(&cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -// Flaky. http://crbug.com/952627 -TEST_F(JsToCppTest, DISABLED_BitFlip) { - // These tests generate a lot of expected validation errors. Suppress logging. - mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; - - BitFlipCppSideConnection cpp_side_connection; - RunTest(&cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, BackPointer) { - // These tests generate a lot of expected validation errors. Suppress logging. - mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; - - BackPointerCppSideConnection cpp_side_connection; - RunTest(&cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -} // namespace -} // namespace blink
diff --git a/third_party/blink/renderer/core/testing/wait_for_event.cc b/third_party/blink/renderer/core/testing/wait_for_event.cc index 405cc58..479a05f 100644 --- a/third_party/blink/renderer/core/testing/wait_for_event.cc +++ b/third_party/blink/renderer/core/testing/wait_for_event.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/testing/wait_for_event.h" -#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -12,7 +12,7 @@ WaitForEvent::WaitForEvent(Element* element, const AtomicString& name) : element_(element), event_name_(name) { element_->addEventListener(event_name_, this); - ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current()); + HeapPointersOnStackScope scan_stack(ThreadState::Current()); run_loop_.Run(); }
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc index 030078e..59af2dab 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc +++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
@@ -30,7 +30,7 @@ EXPECT_FALSE(exception_state.HadException()); window->GetContentSecurityPolicy()->DidReceiveHeader( - "require-trusted-types-for 'script'", + "require-trusted-types-for 'script'", *(window->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kMeta); ASSERT_FALSE(exception_state.HadException()); @@ -50,7 +50,7 @@ EXPECT_FALSE(exception_state.HadException()); window->GetContentSecurityPolicy()->DidReceiveHeader( - "require-trusted-types-for 'script'", + "require-trusted-types-for 'script'", *(window->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kMeta); ASSERT_FALSE(exception_state.HadException()); @@ -70,7 +70,7 @@ EXPECT_FALSE(exception_state.HadException()); window->GetContentSecurityPolicy()->DidReceiveHeader( - "require-trusted-types-for 'script'", + "require-trusted-types-for 'script'", *(window->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kMeta); ASSERT_FALSE(exception_state.HadException());
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc index c565856..39ebcef3 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -448,7 +448,9 @@ GetExecutionContext()->UserAgent(), GetExecutionContext()->GetUserAgentMetadata(), CreateWebWorkerFetchContext(), - GetExecutionContext()->GetContentSecurityPolicy()->GetParsedPolicies(), + mojo::Clone(GetExecutionContext() + ->GetContentSecurityPolicy() + ->GetParsedPolicies()), referrer_policy, GetExecutionContext()->GetSecurityOrigin(), GetExecutionContext()->IsSecureContext(), GetExecutionContext()->GetHttpsState(),
diff --git a/third_party/blink/renderer/core/workers/installed_scripts_manager.cc b/third_party/blink/renderer/core/workers/installed_scripts_manager.cc index c63721e4..0ac82a2 100644 --- a/third_party/blink/renderer/core/workers/installed_scripts_manager.cc +++ b/third_party/blink/renderer/core/workers/installed_scripts_manager.cc
@@ -40,7 +40,7 @@ ContentSecurityPolicyResponseHeaders InstalledScriptsManager::ScriptData::GetContentSecurityPolicyResponseHeaders() { - return ContentSecurityPolicyResponseHeaders(headers_); + return ContentSecurityPolicyResponseHeaders(headers_, script_url_); } String InstalledScriptsManager::ScriptData::GetReferrerPolicy() {
diff --git a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc index aef86c9..6cdd549 100644 --- a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc +++ b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
@@ -46,13 +46,15 @@ } void SetUpScope(const String& csp_header) { PageTestBase::SetUp(IntSize()); - NavigateTo(KURL("https://example.com/")); + KURL url = KURL("https://example.com/"); + NavigateTo(url); LocalDOMWindow* window = GetFrame().DomWindow(); // Set up the CSP for Document before starting MainThreadWorklet because // MainThreadWorklet inherits the owner Document's CSP. auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); - csp->DidReceiveHeader(csp_header, + scoped_refptr<SecurityOrigin> self_origin = SecurityOrigin::Create(url); + csp->DidReceiveHeader(csp_header, *(self_origin), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); window->GetSecurityContext().SetContentSecurityPolicy(csp); @@ -63,7 +65,7 @@ window->Url(), mojom::blink::ScriptType::kModule, "MainThreadWorklet", window->UserAgent(), window->GetFrame()->Loader().UserAgentMetadata(), nullptr /* web_worker_fetch_context */, - window->GetContentSecurityPolicy()->GetParsedPolicies(), + mojo::Clone(window->GetContentSecurityPolicy()->GetParsedPolicies()), window->GetReferrerPolicy(), window->GetSecurityOrigin(), window->IsSecureContext(), window->GetHttpsState(), nullptr /* worker_clients */, nullptr /* content_settings_client */, @@ -166,7 +168,7 @@ // Test that having an invalid CSP does not result in an exception. // See bugs: 844383,844317 TEST_F(MainThreadWorkletInvalidCSPTest, InvalidContentSecurityPolicy) { - Vector<network::mojom::blink::ContentSecurityPolicyPtr> csp = + const Vector<network::mojom::blink::ContentSecurityPolicyPtr>& csp = global_scope_->GetContentSecurityPolicy()->GetParsedPolicies(); // At this point check that the CSP that was set is indeed invalid.
diff --git a/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc b/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc index 61689eab..11103cb 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc
@@ -111,9 +111,9 @@ auto info = mojom::blink::SharedWorkerInfo::New( url, std::move(options), - worker->GetExecutionContext() - ->GetContentSecurityPolicy() - ->GetParsedPolicies(), + mojo::Clone(worker->GetExecutionContext() + ->GetContentSecurityPolicy() + ->GetParsedPolicies()), worker->GetExecutionContext()->AddressSpace(), mojom::blink::FetchClientSettingsObject::New( outside_fetch_client_settings_object->GetReferrerPolicy(),
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc index cfe4d64..361d984 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -258,8 +258,8 @@ Initialize(classic_script_loader->ResponseURL(), response_referrer_policy, classic_script_loader->ResponseAddressSpace(), classic_script_loader->GetContentSecurityPolicy() - ? classic_script_loader->GetContentSecurityPolicy() - ->GetParsedPolicies() + ? mojo::Clone(classic_script_loader->GetContentSecurityPolicy() + ->GetParsedPolicies()) : Vector<network::mojom::blink::ContentSecurityPolicyPtr>(), classic_script_loader->OriginTrialTokens(), classic_script_loader->AppCacheID());
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc index 353aa55..833ba6d 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
@@ -62,7 +62,7 @@ window->UserAgent(), window->GetFrame()->Client()->UserAgentMetadata(), window->GetFrame()->Client()->CreateWorkerFetchContext(), - csp->GetParsedPolicies(), window->GetReferrerPolicy(), + mojo::Clone(csp->GetParsedPolicies()), window->GetReferrerPolicy(), window->GetSecurityOrigin(), window->IsSecureContext(), window->GetHttpsState(), worker_clients, window->GetFrame()->Client()->CreateWorkerContentSettingsClient(),
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc index 4cc4b18..4671d243 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
@@ -98,11 +98,13 @@ void TestContentSecurityPolicy() { EXPECT_TRUE(IsCurrentThread()); ContentSecurityPolicy* csp = GlobalScope()->GetContentSecurityPolicy(); + KURL main_document_url = KURL("https://example.com/script.js"); - // The "script-src 'self'" directive allows this. + // The "script-src 'self'" directive allows |main_document_url| since it is + // same-origin with the main document. EXPECT_TRUE(csp->AllowScriptFromSource( - GlobalScope()->Url(), String(), IntegrityMetadataSet(), kParserInserted, - GlobalScope()->Url(), RedirectStatus::kNoRedirect)); + main_document_url, String(), IntegrityMetadataSet(), kParserInserted, + main_document_url, RedirectStatus::kNoRedirect)); // The "script-src https://allowed.example.com" should allow this. EXPECT_TRUE(csp->AllowScriptFromSource( @@ -125,7 +127,7 @@ EXPECT_TRUE(IsCurrentThread()); // At this point check that the CSP that was set is indeed invalid. - Vector<network::mojom::blink::ContentSecurityPolicyPtr> csp = + const Vector<network::mojom::blink::ContentSecurityPolicyPtr>& csp = GlobalScope()->GetContentSecurityPolicy()->GetParsedPolicies(); EXPECT_EQ(1ul, csp.size()); EXPECT_EQ("invalid-csp", csp[0]->header->header_value); @@ -209,9 +211,9 @@ ->Loader() .UserAgentMetadata(), nullptr /* web_worker_fetch_context */, - GetExecutionContext() - ->GetContentSecurityPolicy() - ->GetParsedPolicies(), + mojo::Clone(GetExecutionContext() + ->GetContentSecurityPolicy() + ->GetParsedPolicies()), GetExecutionContext()->GetReferrerPolicy(), GetExecutionContext()->GetSecurityOrigin(), GetExecutionContext()->IsSecureContext(), @@ -309,6 +311,7 @@ // ThreadedWorklet inherits the owner Document's CSP. auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->DidReceiveHeader("script-src 'self' https://allowed.example.com", + *(GetExecutionContext()->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); GetExecutionContext()->GetSecurityContext().SetContentSecurityPolicy(csp); @@ -326,6 +329,7 @@ TEST_F(ThreadedWorkletTest, InvalidContentSecurityPolicy) { auto* csp = MakeGarbageCollected<ContentSecurityPolicy>(); csp->DidReceiveHeader("invalid-csp", + *(GetExecutionContext()->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); GetExecutionContext()->GetSecurityContext().SetContentSecurityPolicy(csp);
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc index 07e84a8c..870beea1 100644 --- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc +++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -369,8 +369,6 @@ !response.CurrentRequestUrl().ProtocolIs("file") && !response.CurrentRequestUrl().ProtocolIs("filesystem")) { content_security_policy_ = MakeGarbageCollected<ContentSecurityPolicy>(); - content_security_policy_->SetOverrideURLForSelf( - response.CurrentRequestUrl()); content_security_policy_->DidReceiveHeaders( ContentSecurityPolicyResponseHeaders(response)); }
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc index b06919c..224fe05d 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -278,20 +278,6 @@ return KURL(BaseURL(), url); } -void WorkletGlobalScope::BindContentSecurityPolicyToExecutionContext() { - WorkerOrWorkletGlobalScope::BindContentSecurityPolicyToExecutionContext(); - - // CSP checks should resolve self based on the 'fetch client settings object' - // (i.e., the document's origin), not the 'module map settings object' (i.e., - // the opaque origin of this worklet global scope). The current implementation - // doesn't have separate CSP objects for these two contexts. Therefore, - // we initialize the worklet global scope's CSP object (which would naively - // appear to be a CSP object for the 'module map settings object') entirely - // based on state from the document (the origin and CSP headers it passed - // here), and use the document's origin for 'self' CSP checks. - GetContentSecurityPolicy()->SetupSelf(*document_security_origin_); -} - ukm::UkmRecorder* WorkletGlobalScope::UkmRecorder() { if (ukm_recorder_) return ukm_recorder_.get();
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.h b/third_party/blink/renderer/core/workers/worklet_global_scope.h index c6b1c20..459d909 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.h
@@ -159,8 +159,6 @@ EventTarget* ErrorEventTarget() final { return nullptr; } - void BindContentSecurityPolicyToExecutionContext() override; - // The |url_| and |user_agent_| are inherited from the parent Document. const KURL url_; const String user_agent_;
diff --git a/third_party/blink/renderer/core/xml/dom_parser.h b/third_party/blink/renderer/core/xml/dom_parser.h index 1cd7a6b7..d7c8c83 100644 --- a/third_party/blink/renderer/core/xml/dom_parser.h +++ b/third_party/blink/renderer/core/xml/dom_parser.h
@@ -20,6 +20,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_XML_DOM_PARSER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_XML_DOM_PARSER_H_ +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -31,7 +32,7 @@ class LocalDOMWindow; class ScriptState; -class DOMParser final : public ScriptWrappable { +class CORE_EXPORT DOMParser final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public:
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc index 13ee92bde..b22149c 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
@@ -41,7 +41,7 @@ window->Url(), mojom::blink::ScriptType::kModule, global_scope_name, window->UserAgent(), frame->Client()->UserAgentMetadata(), frame->Client()->CreateWorkerFetchContext(), - window->GetContentSecurityPolicy()->GetParsedPolicies(), + mojo::Clone(window->GetContentSecurityPolicy()->GetParsedPolicies()), window->GetReferrerPolicy(), window->GetSecurityOrigin(), window->IsSecureContext(), window->GetHttpsState(), nullptr /* worker_clients */,
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc index 4f20398..e5ba7d6 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" #include "third_party/blink/renderer/core/fileapi/file.h" #include "third_party/blink/renderer/core/testing/null_execution_context.h" -#include "third_party/blink/renderer/platform/heap/impl/heap.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc index c791d0b..253f47e 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
@@ -18,7 +18,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h" -#include "third_party/blink/renderer/platform/heap/impl/heap.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc index ad703c4bd..c9e7862d 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc index 614d16e..3f6d249 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc index 32063676..e5574d4 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
@@ -10,13 +10,20 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_sanitizer_config.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document_fragment.h" +#include "third_party/blink/renderer/core/dom/document_init.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" #include "third_party/blink/renderer/core/editing/serializers/serialization.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/html/custom/custom_element.h" +#include "third_party/blink/renderer/core/html/html_collection.h" +#include "third_party/blink/renderer/core/html/html_head_element.h" +#include "third_party/blink/renderer/core/html/parser/html_document_parser.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h" +#include "third_party/blink/renderer/core/xml/dom_parser.h" +#include "third_party/blink/renderer/core/xml/parse_from_string_options.h" #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" @@ -30,7 +37,8 @@ return MakeGarbageCollected<Sanitizer>(config); } -Sanitizer::Sanitizer(const SanitizerConfig* config) { +Sanitizer::Sanitizer(const SanitizerConfig* config) + : allow_custom_elements_(config->allowCustomElements()) { // Format dropElements to uppercase. drop_elements_ = default_drop_elements_; if (config->hasDropElements()) { @@ -131,16 +139,19 @@ LocalDOMWindow* window = LocalDOMWindow::From(script_state); if (input.IsDocumentFragment()) { fragment = input.GetAsDocumentFragment(); - } else if (window) { - Document* document = window->document(); - if (input.IsString() || input.IsNull()) { - fragment = document->createDocumentFragment(); - DCHECK(document->QuerySelector("body")); - fragment->ParseHTML(input.GetAsString(), document->QuerySelector("body")); - } else { - fragment = document->createDocumentFragment(); - fragment->appendChild(input.GetAsDocument()->documentElement()); - } + } else if (window && (input.IsString() || input.IsNull())) { + Document* document = + DOMParser::Create(script_state) + ->parseFromString("<!DOCTYPE html><body>" + input.GetAsString(), + "text/html", ParseFromStringOptions::Create()); + DCHECK(document->body()); + fragment = document->createDocumentFragment(); + fragment->CloneChildNodesFrom(*(document->body()), + CloneChildrenFlag::kClone); + } else if (input.IsDocument()) { + fragment = input.GetAsDocument()->createDocumentFragment(); + fragment->CloneChildNodesFrom(*(input.GetAsDocument()->body()), + CloneChildrenFlag::kClone); } else { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "Cannot find current DOM window."); @@ -160,7 +171,10 @@ String node_name = node->nodeName().UpperASCII(); // If the current element is dropped, remove current element entirely and // proceed to its next sibling. - if (drop_elements_.Contains(node_name)) { + if (drop_elements_.Contains(node_name) || + (!allow_custom_elements_ && + CustomElement::IsValidName(AtomicString(node_name.LowerASCII()), + false))) { Node* tmp = node; node = NodeTraversal::NextSkippingChildren(*node, fragment); tmp->remove();
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h index f8d98e7..f40ef28 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
@@ -51,6 +51,8 @@ HashMap<String, Vector<String>> allow_attributes_ = {}; HashMap<String, Vector<String>> drop_attributes_ = {}; + bool allow_custom_elements_ = false; + bool has_allow_elements_ = false; bool has_allow_attributes_ = false;
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc index 65d9acb1..f891133 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
@@ -64,6 +64,7 @@ } sanitizer_config->setDropAttributes(drop_attributes); } + sanitizer_config->setAllowCustomElements(proto.allow_custom_elements()); } void TextProtoFuzzer(const SanitizerConfigProto& proto,
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl index fe55d95..ea0cba3 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl
@@ -10,4 +10,5 @@ sequence<DOMString> dropElements; record<DOMString, sequence<DOMString>> allowAttributes; record<DOMString, sequence<DOMString>> dropAttributes; + boolean allowCustomElements = false; };
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto index 6089a320..68fb304 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto
@@ -14,4 +14,5 @@ map<string, Elements> allow_attributes = 5; map<string, Elements> drop_attributes = 6; + optional bool allow_custom_elements = 7; }
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index c3a0f56..29932b7 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -466,8 +466,8 @@ classic_script_loader->ResponseURL(), referrer_policy, classic_script_loader->ResponseAddressSpace(), classic_script_loader->GetContentSecurityPolicy() - ? classic_script_loader->GetContentSecurityPolicy() - ->GetParsedPolicies() + ? mojo::Clone(classic_script_loader->GetContentSecurityPolicy() + ->GetParsedPolicies()) : Vector<network::mojom::blink::ContentSecurityPolicyPtr>(), classic_script_loader->OriginTrialTokens(), classic_script_loader->SourceText(),
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc index ea61663..c086291 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
@@ -18,7 +18,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" -#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -30,7 +30,7 @@ namespace { void RunWithStack(base::RunLoop* run_loop) { - ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current()); + HeapPointersOnStackScope scan_stack(ThreadState::Current()); run_loop->Run(); }
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.cc b/third_party/blink/renderer/modules/webgpu/dawn_object.cc index 093733c..e07088b 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.cc
@@ -27,58 +27,28 @@ return dawn_control_client_->GetProcs(); } -DawnDeviceClientSerializerHolder::DawnDeviceClientSerializerHolder( - scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id) - : dawn_control_client_(std::move(dawn_control_client)), - device_client_id_(device_client_id) {} - -DawnDeviceClientSerializerHolder::~DawnDeviceClientSerializerHolder() { - dawn_control_client_->GetInterface()->RemoveDevice(device_client_id_); -} - -const scoped_refptr<DawnControlClientHolder>& -DeviceTreeObject::GetDawnControlClient() const { - return device_client_serializer_holder_->dawn_control_client_; -} - -gpu::webgpu::WebGPUInterface* DeviceTreeObject::GetInterface() const { - return GetDawnControlClient()->GetInterface(); -} -const DawnProcTable& DeviceTreeObject::GetProcs() const { - return GetDawnControlClient()->GetProcs(); -} - -uint64_t DeviceTreeObject::GetDeviceClientID() const { - return device_client_serializer_holder_->device_client_id_; -} - -void DeviceTreeObject::EnsureFlush() { +void DawnObjectBase::EnsureFlush() { bool needs_flush = false; - GetInterface()->EnsureAwaitingFlush( - device_client_serializer_holder_->device_client_id_, &needs_flush); + GetInterface()->EnsureAwaitingFlush(&needs_flush); if (!needs_flush) { // We've already enqueued a task to flush, or the command buffer // is empty. Do nothing. return; } Microtask::EnqueueMicrotask(WTF::Bind( - [](scoped_refptr<DawnDeviceClientSerializerHolder> holder) { - holder->dawn_control_client_->GetInterface()->FlushAwaitingCommands( - holder->device_client_id_); + [](scoped_refptr<DawnControlClientHolder> dawn_control_client) { + dawn_control_client->GetInterface()->FlushAwaitingCommands(); }, - device_client_serializer_holder_)); + dawn_control_client_)); } // Flush commands up until now on this object's parent device immediately. -void DeviceTreeObject::FlushNow() { - GetInterface()->FlushCommands( - device_client_serializer_holder_->device_client_id_); +void DawnObjectBase::FlushNow() { + GetInterface()->FlushCommands(); } DawnObjectImpl::DawnObjectImpl(GPUDevice* device) - : DeviceTreeObject(device->GetDeviceClientSerializerHolder()), - device_(device) {} + : DawnObjectBase(device->GetDawnControlClient()), device_(device) {} DawnObjectImpl::~DawnObjectImpl() = default;
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.h b/third_party/blink/renderer/modules/webgpu/dawn_object.h index c44571e..188eb835 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.h
@@ -75,54 +75,6 @@ gpu::webgpu::WebGPUInterface* GetInterface() const; const DawnProcTable& GetProcs() const; - private: - scoped_refptr<DawnControlClientHolder> dawn_control_client_; -}; - -// This class allows objects to hold onto a DawnControlClientHolder and a -// device client id. Now one GPUDevice is related to one WebGPUSerializer in -// the client side of WebGPU context. When the GPUDevice and all the other -// WebGPU objects that are created from the GPUDevice are destroyed, this -// object will be destroyed and in the destructor of this object we will -// trigger the clean-ups to the corresponding WebGPUSerailzer and other data -// structures in the GPU process. -class DawnDeviceClientSerializerHolder - : public RefCounted<DawnDeviceClientSerializerHolder> { - public: - DawnDeviceClientSerializerHolder( - scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id); - - private: - friend class RefCounted<DawnDeviceClientSerializerHolder>; - friend class DeviceTreeObject; - ~DawnDeviceClientSerializerHolder(); - - scoped_refptr<DawnControlClientHolder> dawn_control_client_; - uint64_t device_client_id_; -}; - -// This class is the parent of GPUDevice and all the WebGPU objects that are -// created from a GPUDevice, which holds a -// scoped_refptr<DawnDeviceClientSerializerHolder> and provides functions to -// access all the members inside it. When a GPUDevice and all the WebGPU -// objects created from it are destroyed, the refcount of -// DawnDeviceClientSerializerHolder will become 0 and the clean-ups to the -// corresponding WebGPUSerailzer and other data structures in the GPU process -// will be triggered. -class DeviceTreeObject { - public: - explicit DeviceTreeObject(scoped_refptr<DawnDeviceClientSerializerHolder> - device_client_seralizer_holder) - : device_client_serializer_holder_( - std::move(device_client_seralizer_holder)) {} - - const scoped_refptr<DawnControlClientHolder>& GetDawnControlClient() const; - gpu::webgpu::WebGPUInterface* GetInterface() const; - const DawnProcTable& GetProcs() const; - - uint64_t GetDeviceClientID() const; - // Ensure commands up until now on this object's parent device are flushed by // the end of the task. void EnsureFlush(); @@ -130,12 +82,11 @@ // Flush commands up until now on this object's parent device immediately. void FlushNow(); - protected: - scoped_refptr<DawnDeviceClientSerializerHolder> - device_client_serializer_holder_; + private: + scoped_refptr<DawnControlClientHolder> dawn_control_client_; }; -class DawnObjectImpl : public ScriptWrappable, public DeviceTreeObject { +class DawnObjectImpl : public ScriptWrappable, public DawnObjectBase { public: explicit DawnObjectImpl(GPUDevice* device); ~DawnObjectImpl() override; @@ -179,24 +130,15 @@ }; template <> -class DawnObject<WGPUDevice> : public DeviceTreeObject { +class DawnObject<WGPUDevice> : public DawnObjectBase { public: DawnObject(scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id, WGPUDevice handle) - : DeviceTreeObject(base::MakeRefCounted<DawnDeviceClientSerializerHolder>( - std::move(dawn_control_client), - device_client_id)), - handle_(handle) {} + : DawnObjectBase(dawn_control_client), handle_(handle) {} ~DawnObject() { GetProcs().deviceRelease(handle_); } WGPUDevice GetHandle() const { return handle_; } - const scoped_refptr<DawnDeviceClientSerializerHolder>& - GetDeviceClientSerializerHolder() const { - return device_client_serializer_holder_; - } - private: WGPUDevice const handle_; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc index 87e7dc6..2e6226d4 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -203,13 +203,11 @@ power_preference = gpu::webgpu::PowerPreference::kLowPower; } - if (!dawn_control_client_->GetInterface()->RequestAdapterAsync( - power_preference, - WTF::Bind(&GPU::OnRequestAdapterCallback, WrapPersistent(this), - WrapPersistent(script_state), WrapPersistent(options), - WrapPersistent(resolver)))) { - resolver->Resolve(v8::Null(script_state->GetIsolate())); - } + dawn_control_client_->GetInterface()->RequestAdapterAsync( + power_preference, + WTF::Bind(&GPU::OnRequestAdapterCallback, WrapPersistent(this), + WrapPersistent(script_state), WrapPersistent(options), + WrapPersistent(resolver))); return promise; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index e5f75a6..f612ab9 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -61,13 +61,12 @@ void GPUAdapter::OnRequestDeviceCallback(ScriptPromiseResolver* resolver, const GPUDeviceDescriptor* descriptor, - bool is_request_device_success, - uint64_t device_client_id) { - if (is_request_device_success) { + WGPUDevice dawn_device) { + if (dawn_device) { ExecutionContext* execution_context = resolver->GetExecutionContext(); - auto* device = MakeGarbageCollected<GPUDevice>( - execution_context, GetDawnControlClient(), this, device_client_id, - descriptor); + auto* device = MakeGarbageCollected<GPUDevice>(execution_context, + GetDawnControlClient(), this, + dawn_device, descriptor); resolver->Resolve(device); ukm::builders::ClientRenderingAPI(execution_context->UkmSourceID()) .SetGPUDevice(static_cast<int>(true)) @@ -102,13 +101,10 @@ WGPUDeviceProperties requested_device_properties = AsDawnType(descriptor); - if (!GetInterface()->RequestDeviceAsync( - adapter_service_id_, requested_device_properties, - WTF::Bind(&GPUAdapter::OnRequestDeviceCallback, WrapPersistent(this), - WrapPersistent(resolver), WrapPersistent(descriptor)))) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kOperationError, "Unknown error creating GPUDevice")); - } + GetInterface()->RequestDeviceAsync( + adapter_service_id_, requested_device_properties, + WTF::Bind(&GPUAdapter::OnRequestDeviceCallback, WrapPersistent(this), + WrapPersistent(resolver), WrapPersistent(descriptor))); return promise; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.h b/third_party/blink/renderer/modules/webgpu/gpu_adapter.h index 991e911..0ffdca2 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.h
@@ -36,8 +36,7 @@ private: void OnRequestDeviceCallback(ScriptPromiseResolver* resolver, const GPUDeviceDescriptor* descriptor, - bool is_request_device_success, - uint64_t device_client_id); + WGPUDevice dawn_device); void InitializeExtensionNameList(); String name_;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index dc35b63..352b93d 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -56,12 +56,10 @@ GPUDevice::GPUDevice(ExecutionContext* execution_context, scoped_refptr<DawnControlClientHolder> dawn_control_client, GPUAdapter* adapter, - uint64_t client_id, + WGPUDevice dawn_device, const GPUDeviceDescriptor* descriptor) : ExecutionContextClient(execution_context), - DawnObject(dawn_control_client, - client_id, - dawn_control_client->GetInterface()->GetDevice(client_id)), + DawnObject(dawn_control_client, dawn_device), adapter_(adapter), #ifdef USE_BLINK_V8_BINDING_NEW_IDL_DICTIONARY extension_name_list_(ToStringVector(descriptor->extensions())), @@ -76,7 +74,7 @@ WrapWeakPersistent(this))), lost_callback_(BindDawnCallback(&GPUDevice::OnDeviceLostError, WrapWeakPersistent(this))) { - DCHECK(dawn_control_client->GetInterface()->GetDevice(client_id)); + DCHECK(dawn_device); GetProcs().deviceSetUncapturedErrorCallback( GetHandle(), error_callback_->UnboundRepeatingCallback(), error_callback_->AsUserdata());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h index 2aa2162..3a73387 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -58,7 +58,7 @@ explicit GPUDevice(ExecutionContext* execution_context, scoped_refptr<DawnControlClientHolder> dawn_control_client, GPUAdapter* adapter, - uint64_t client_id, + WGPUDevice dawn_device, const GPUDeviceDescriptor* descriptor); void Trace(Visitor* visitor) const override;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index b44fd2a2..938faa3 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -129,7 +129,7 @@ GPUQueue::GPUQueue(GPUDevice* device, WGPUQueue queue) : DawnObject<WGPUQueue>(device, queue) { produce_dawn_texture_handler_ = base::AdoptRef(new DawnTextureFromImageBitmap( - GetDawnControlClient(), GetDeviceClientID())); + GetDawnControlClient(), device->GetHandle())); } void GPUQueue::submit(const HeapVector<Member<GPUCommandBuffer>>& buffers) {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc index 3afa50c..0841ce16 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
@@ -16,14 +16,13 @@ WGPUTextureUsage usage, WGPUTextureFormat format, SkFilterQuality filter_quality) - : DeviceTreeObject(device->GetDeviceClientSerializerHolder()), - device_(device), + : DawnObjectImpl(device), context_(context), usage_(usage), format_(format) { // TODO: Use label from GPUObjectDescriptorBase. swap_buffers_ = base::AdoptRef(new WebGPUSwapBufferProvider( - this, GetDawnControlClient(), GetDeviceClientID(), usage_, format)); + this, GetDawnControlClient(), device->GetHandle(), usage_, format)); swap_buffers_->SetFilterQuality(filter_quality); } @@ -32,10 +31,9 @@ } void GPUSwapChain::Trace(Visitor* visitor) const { - visitor->Trace(device_); visitor->Trace(context_); visitor->Trace(texture_); - ScriptWrappable::Trace(visitor); + DawnObjectImpl::Trace(visitor); } void GPUSwapChain::Neuter() {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h index 42f66b8d..91842e00 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h
@@ -18,8 +18,7 @@ class GPUDevice; class GPUTexture; -class GPUSwapChain : public ScriptWrappable, - public DeviceTreeObject, +class GPUSwapChain : public DawnObjectImpl, public WebGPUSwapBufferProvider::Client { DEFINE_WRAPPERTYPEINFO(); @@ -48,7 +47,6 @@ scoped_refptr<WebGPUSwapBufferProvider> swap_buffers_; - Member<GPUDevice> device_; Member<GPUCanvasContext> context_; WGPUTextureUsage usage_; WGPUTextureFormat format_;
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc index e05a0a3..e99480df 100644 --- a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc +++ b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
@@ -23,7 +23,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/heap/impl/thread_state.h" +#include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc b/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc index a89f553..3b88b596 100644 --- a/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc +++ b/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc
@@ -380,6 +380,7 @@ scope.GetExecutionContext() ->GetContentSecurityPolicyForCurrentWorld() ->DidReceiveHeader("connect-src 'none'", + *(scope.GetExecutionContext()->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); QuicTransport::Create(scope.GetScriptState(), @@ -401,6 +402,7 @@ scope.GetExecutionContext() ->GetContentSecurityPolicyForCurrentWorld() ->DidReceiveHeader("connect-src quic-transport://example.com", + *(scope.GetExecutionContext()->GetSecurityOrigin()), network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); QuicTransport::Create(scope.GetScriptState(),
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index b92727d8..a0755ef4 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -399,6 +399,8 @@ "audio/vector_math.cc", "audio/vector_math.h", "audio/vector_math_scalar.h", + "back_forward_cache_utils.cc", + "back_forward_cache_utils.h", "bindings/active_script_wrappable_base.cc", "bindings/active_script_wrappable_base.h", "bindings/active_script_wrappable_manager.cc", @@ -1254,11 +1256,11 @@ "mojo/heap_mojo_unique_receiver_set.h", "mojo/heap_mojo_wrapper_mode.h", "mojo/kurl_mojom_traits.h", + "mojo/mojo_binding_context.h", "mojo/mojo_helper.h", "mojo/security_origin_mojom_traits.h", "mojo/string16_mojom_traits.cc", "mojo/string16_mojom_traits.h", - "mojo_binding_context.h", "p2p/empty_network_manager.cc", "p2p/empty_network_manager.h", "p2p/filtering_network_manager.cc",
diff --git a/third_party/blink/renderer/platform/back_forward_cache_utils.cc b/third_party/blink/renderer/platform/back_forward_cache_utils.cc new file mode 100644 index 0000000..c4ece9c7 --- /dev/null +++ b/third_party/blink/renderer/platform/back_forward_cache_utils.cc
@@ -0,0 +1,38 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" + +#include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" + +namespace blink { + +bool IsInflightNetworkRequestBackForwardCacheSupportEnabled() { + // Note that the call to RuntimeEnabledFeatures::BackForwardCacheEnabled() + // must be done first to ensure we will never call + // base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable) when + // back-forward cache is not enabled. This is important because IsEnabled() + // might trigger activation of the current user in BackForwardCache's field + // trial group even though it shouldn't (e.g. when BackForwardCache is + // disabled due to low RAM), lowering the back-forward cache hit rate. + // TODO(rakina): Remove BackForwardCache from RuntimeEnabledFeatures and move + // features::kBackForwardCache and BackForwardCacheMemoryControls from + // content/ to blink/public, so that we can combine this check with the checks + // in content/. + return RuntimeEnabledFeatures::BackForwardCacheEnabled() && + base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable); +} + +int GetLoadingTasksUnfreezableParamAsInt(const std::string& param_name, + int default_value) { + if (!IsInflightNetworkRequestBackForwardCacheSupportEnabled()) + return default_value; + return base::GetFieldTrialParamByFeatureAsInt( + blink::features::kLoadingTasksUnfreezable, param_name, default_value); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/back_forward_cache_utils.h b/third_party/blink/renderer/platform/back_forward_cache_utils.h new file mode 100644 index 0000000..fe0273ce --- /dev/null +++ b/third_party/blink/renderer/platform/back_forward_cache_utils.h
@@ -0,0 +1,24 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BACK_FORWARD_CACHE_UTILS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BACK_FORWARD_CACHE_UTILS_H_ + +#include <string> + +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +// Returns true iff back-forward cache and LoadingTasksUnfreezable are enabled. +PLATFORM_EXPORT bool IsInflightNetworkRequestBackForwardCacheSupportEnabled(); +// Returns the param |param_name| of LoadingTasksUnfreezable as int, or +// |default_value| if not set. +PLATFORM_EXPORT int GetLoadingTasksUnfreezableParamAsInt( + const std::string& param_name, + int default_value); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BACK_FORWARD_CACHE_UTILS_H_
diff --git a/third_party/blink/renderer/platform/file_metadata.cc b/third_party/blink/renderer/platform/file_metadata.cc index 306d117b..3dba7ab 100644 --- a/third_party/blink/renderer/platform/file_metadata.cc +++ b/third_party/blink/renderer/platform/file_metadata.cc
@@ -40,7 +40,7 @@ #include "third_party/blink/public/mojom/file/file_utilities.mojom-blink.h" #include "third_party/blink/public/platform/file_path_conversion.h" #include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "url/gurl.h"
diff --git a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc index 493004a99..2c92166 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
@@ -1476,20 +1476,78 @@ HarfBuzzShaper shaper(string); scoped_refptr<ShapeResult> result = shaper.Shape(&font, TextDirection::kRtl); - Vector<unsigned> safe_to_break_positions; - + EXPECT_EQ(0u, result->NextSafeToBreakOffset(0)); + EXPECT_EQ(3u, result->NextSafeToBreakOffset(1)); + EXPECT_EQ(3u, result->NextSafeToBreakOffset(2)); + EXPECT_EQ(3u, result->NextSafeToBreakOffset(3)); + EXPECT_EQ(4u, result->NextSafeToBreakOffset(4)); #if defined(OS_MAC) - safe_to_break_positions = {0, 2, 3, 4, 11}; + EXPECT_EQ(12u, result->NextSafeToBreakOffset(5)); + EXPECT_EQ(12u, result->NextSafeToBreakOffset(6)); + EXPECT_EQ(12u, result->NextSafeToBreakOffset(7)); + EXPECT_EQ(12u, result->NextSafeToBreakOffset(8)); + EXPECT_EQ(12u, result->NextSafeToBreakOffset(9)); + EXPECT_EQ(12u, result->NextSafeToBreakOffset(10)); + EXPECT_EQ(12u, result->NextSafeToBreakOffset(11)); #else - safe_to_break_positions = {0, 3, 4, 5, 7, 11}; + EXPECT_EQ(5u, result->NextSafeToBreakOffset(5)); + EXPECT_EQ(7u, result->NextSafeToBreakOffset(6)); + EXPECT_EQ(7u, result->NextSafeToBreakOffset(7)); + EXPECT_EQ(11u, result->NextSafeToBreakOffset(8)); + EXPECT_EQ(11u, result->NextSafeToBreakOffset(9)); + EXPECT_EQ(11u, result->NextSafeToBreakOffset(10)); + EXPECT_EQ(11u, result->NextSafeToBreakOffset(11)); #endif - unsigned compare_safe_to_break_position = 0; - for (unsigned i = 0; i < string.length() - 1; ++i) { - EXPECT_EQ(safe_to_break_positions[compare_safe_to_break_position], - result->NextSafeToBreakOffset(i)); - if (i == safe_to_break_positions[compare_safe_to_break_position]) - compare_safe_to_break_position++; - } + EXPECT_EQ(12u, result->NextSafeToBreakOffset(12)); + + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(0)); + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(1)); + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(2)); + EXPECT_EQ(3u, result->PreviousSafeToBreakOffset(3)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(4)); +#if defined(OS_MAC) + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(5)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(6)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(7)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(8)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(9)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(10)); + EXPECT_EQ(4u, result->PreviousSafeToBreakOffset(11)); +#else + EXPECT_EQ(5u, result->PreviousSafeToBreakOffset(5)); + EXPECT_EQ(5u, result->PreviousSafeToBreakOffset(6)); + EXPECT_EQ(7u, result->PreviousSafeToBreakOffset(7)); + EXPECT_EQ(7u, result->PreviousSafeToBreakOffset(8)); + EXPECT_EQ(7u, result->PreviousSafeToBreakOffset(9)); + EXPECT_EQ(7u, result->PreviousSafeToBreakOffset(10)); + EXPECT_EQ(11u, result->PreviousSafeToBreakOffset(11)); +#endif + EXPECT_EQ(12u, result->PreviousSafeToBreakOffset(12)); +} + +// http://crbug.com/1170334 +TEST_F(HarfBuzzShaperTest, SafeToBreakU0635) { + FontDescription::VariantLigatures ligatures; + ligatures.common = FontDescription::kEnabledLigaturesState; + + // Five U+0635. This sequence should be rendered once. + String string(u"\u0635\u0635\u0635\u0635\u0635"); + HarfBuzzShaper shaper(string); + scoped_refptr<ShapeResult> result = shaper.Shape(&font, TextDirection::kRtl); + + EXPECT_EQ(0u, result->NextSafeToBreakOffset(0)); + EXPECT_EQ(5u, result->NextSafeToBreakOffset(1)); + EXPECT_EQ(5u, result->NextSafeToBreakOffset(2)); + EXPECT_EQ(5u, result->NextSafeToBreakOffset(3)); + EXPECT_EQ(5u, result->NextSafeToBreakOffset(4)); + EXPECT_EQ(5u, result->NextSafeToBreakOffset(5)); + + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(0)); + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(1)); + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(2)); + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(3)); + EXPECT_EQ(0u, result->PreviousSafeToBreakOffset(4)); + EXPECT_EQ(5u, result->PreviousSafeToBreakOffset(5)); } // TODO(layout-dev): Expand RTL test coverage and add tests for mixed
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc index dfa85157..6fa1ffe 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -942,14 +942,27 @@ // Checks whether it's safe to break without reshaping before the given glyph. bool IsSafeToBreakBefore(const hb_glyph_info_t* glyph_infos, - unsigned i) { - // Before the first glyph is safe to break. - if (!i) - return true; + unsigned i, + unsigned num_glyph, + TextDirection direction) { + if (direction == TextDirection::kLtr) { + // Before the first glyph is safe to break. + if (!i) + return true; - // Not at a cluster boundary. - if (glyph_infos[i].cluster == glyph_infos[i - 1].cluster) - return false; + // Not at a cluster boundary. + if (glyph_infos[i].cluster == glyph_infos[i - 1].cluster) + return false; + } else { + DCHECK_EQ(direction, TextDirection::kRtl); + // Before the first glyph is safe to break. + if (i == num_glyph - 1) + return true; + + // Not at a cluster boundary. + if (glyph_infos[i].cluster == glyph_infos[i + 1].cluster) + return false; + } // The HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag is set for all glyphs in a // given cluster so we only need to check the last one. @@ -1105,7 +1118,8 @@ uint16_t character_index = glyph.cluster - start_cluster; DCHECK_LE(character_index, HarfBuzzRunGlyphData::kMaxCharacterIndex); run->glyph_data_[i] = {glyph.codepoint, character_index, - IsSafeToBreakBefore(glyph_infos + start_glyph, i), + IsSafeToBreakBefore(glyph_infos + start_glyph, i, + num_glyphs, Direction()), advance}; run->glyph_data_.SetOffsetAt(i, offset);
diff --git a/third_party/blink/renderer/platform/graphics/DEPS b/third_party/blink/renderer/platform/graphics/DEPS index d957443..1cff300 100644 --- a/third_party/blink/renderer/platform/graphics/DEPS +++ b/third_party/blink/renderer/platform/graphics/DEPS
@@ -48,7 +48,7 @@ "+third_party/blink/renderer/platform/image-encoders", "+third_party/blink/renderer/platform/instrumentation", "+third_party/blink/renderer/platform/json", - "+third_party/blink/renderer/platform/mojo_binding_context.h", + "+third_party/blink/renderer/platform/mojo/mojo_binding_context.h", "+third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h", "+third_party/blink/renderer/platform/mojo/heap_mojo_remote.h", "+third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h",
diff --git a/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc b/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc index 6aca494a..4d2eb62 100644 --- a/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc +++ b/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
@@ -11,7 +11,7 @@ #include "services/viz/public/mojom/compositing/frame_timing_details.mojom-blink.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "ui/gfx/mojom/presentation_feedback.mojom-blink.h"
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index a4daf652..e7894d37 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -35,15 +35,6 @@ #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/color_space.h" -#if BUILDFLAG(SKIA_USE_DAWN) -namespace { -// TODO(senorblanco): This should be using RequestDeviceAsync(), but -// those callbacks don't seem to work currently. Assume device 1 -// and use it in all the WebGPUInterface calls. http://crbug.com/1078775 -constexpr uint64_t kWebGPUDeviceClientID = 1; -} // namespace -#endif - namespace blink { CanvasResource::CanvasResource(base::WeakPtr<CanvasResourceProvider> provider, @@ -828,8 +819,10 @@ void CanvasResourceSkiaDawnSharedImage::BeginAccess() { auto* webgpu = WebGPUInterface(); + // TODO(senorblanco): create an actual passed-in Device, rather than this + // default hacky one. http://crbug.com/1078775 gpu::webgpu::ReservedTexture reservation = - webgpu->ReserveTexture(kWebGPUDeviceClientID); + webgpu->ReserveTexture(webgpu->DeprecatedEnsureDefaultDeviceSync()); DCHECK(reservation.texture); owning_thread_data().texture = wgpu::Texture(reservation.texture); @@ -837,8 +830,8 @@ owning_thread_data().generation = reservation.generation; webgpu->FlushCommands(); webgpu->AssociateMailbox( - kWebGPUDeviceClientID, 0, owning_thread_data().id, - owning_thread_data().generation, + reservation.deviceId, reservation.deviceGeneration, + owning_thread_data().id, owning_thread_data().generation, WGPUTextureUsage_Sampled | WGPUTextureUsage_OutputAttachment, reinterpret_cast<GLbyte*>(&owning_thread_data().shared_image_mailbox)); } @@ -846,7 +839,7 @@ void CanvasResourceSkiaDawnSharedImage::EndAccess() { auto* webgpu = WebGPUInterface(); webgpu->FlushCommands(); - webgpu->DissociateMailbox(kWebGPUDeviceClientID, owning_thread_data().id, + webgpu->DissociateMailbox(owning_thread_data().id, owning_thread_data().generation); owning_thread_data().texture = nullptr;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc index 8fcd6155..4cb708f 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc
@@ -13,7 +13,8 @@ DawnControlClientHolder::DawnControlClientHolder( std::unique_ptr<WebGraphicsContext3DProvider> context_provider) : context_provider_(std::move(context_provider)), - interface_(context_provider_->WebGPUInterface()) {} + interface_(context_provider_->WebGPUInterface()), + procs_(interface_->GetProcs()) {} void DawnControlClientHolder::SetLostContextCallback() { context_provider_->SetLostContextCallback(WTF::BindRepeating( @@ -35,11 +36,6 @@ return interface_; } -const DawnProcTable& DawnControlClientHolder::GetProcs() const { - DCHECK(interface_); - return interface_->GetProcs(); -} - void DawnControlClientHolder::SetContextLost() { lost_ = true; }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h index d91409e7..0e4527e 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h +++ b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h
@@ -35,7 +35,7 @@ WebGraphicsContext3DProvider* GetContextProvider() const; gpu::webgpu::WebGPUInterface* GetInterface() const; - const DawnProcTable& GetProcs() const; + const DawnProcTable& GetProcs() const { return procs_; } void SetContextLost(); bool IsContextLost() const; void SetLostContextCallback(); @@ -46,6 +46,7 @@ std::unique_ptr<WebGraphicsContext3DProvider> context_provider_; gpu::webgpu::WebGPUInterface* interface_; + DawnProcTable procs_; bool lost_ = false; };
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc index 99cdb5c..a7a60ad 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
@@ -135,9 +135,10 @@ DawnTextureFromImageBitmap::DawnTextureFromImageBitmap( scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id) - : dawn_control_client_(dawn_control_client), - device_client_id_(device_client_id) {} + WGPUDevice device) + : dawn_control_client_(dawn_control_client), device_(device) { + dawn_control_client_->GetProcs().deviceReference(device_); +} DawnTextureFromImageBitmap::~DawnTextureFromImageBitmap() { // Ensure calls to ProduceDawnTextureFromImageBitmap @@ -145,7 +146,8 @@ DCHECK_EQ(wire_texture_id_, 0u); DCHECK_EQ(wire_texture_generation_, 0u); - device_client_id_ = 0; + dawn_control_client_->GetProcs().deviceRelease(device_); + device_ = nullptr; dawn_control_client_.reset(); } @@ -155,8 +157,7 @@ // Produce and inject image to WebGPU texture gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); - gpu::webgpu::ReservedTexture reservation = - webgpu->ReserveTexture(device_client_id_); + gpu::webgpu::ReservedTexture reservation = webgpu->ReserveTexture(device_); DCHECK(reservation.texture); wire_texture_id_ = reservation.id; @@ -164,8 +165,9 @@ // This may fail because gl_backing resource cannot produce dawn // representation. - webgpu->AssociateMailbox(device_client_id_, 0, wire_texture_id_, - wire_texture_generation_, WGPUTextureUsage_CopySrc, + webgpu->AssociateMailbox(reservation.deviceId, reservation.deviceGeneration, + wire_texture_id_, wire_texture_generation_, + WGPUTextureUsage_CopySrc, reinterpret_cast<GLbyte*>(&associated_resource_)); return reservation.texture; @@ -175,8 +177,7 @@ DCHECK_NE(wire_texture_id_, 0u); gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); - webgpu->DissociateMailbox(device_client_id_, wire_texture_id_, - wire_texture_generation_); + webgpu->DissociateMailbox(wire_texture_id_, wire_texture_generation_); wire_texture_id_ = 0; wire_texture_generation_ = 0; associated_resource_.SetZero();
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h index a7b6f74..c5e06f7 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h
@@ -41,7 +41,7 @@ public: DawnTextureFromImageBitmap( scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id); + WGPUDevice device); ~DawnTextureFromImageBitmap(); WGPUTexture ProduceDawnTextureFromImageBitmap( @@ -50,12 +50,12 @@ uint32_t GetTextureIdForTest() { return wire_texture_id_; } uint32_t GetTextureGenerationForTest() { return wire_texture_generation_; } - uint64_t GetDeviceClientIdForTest() { return device_client_id_; } + WGPUDevice GetDeviceForTest() { return device_; } private: scoped_refptr<DawnControlClientHolder> dawn_control_client_; gpu::Mailbox associated_resource_; - uint64_t device_client_id_; + WGPUDevice device_; uint32_t wire_texture_id_ = 0; uint32_t wire_texture_generation_ = 0; };
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc index 3ebea4e7..17c37d2 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
@@ -58,12 +58,21 @@ class MockWebGPUInterface : public gpu::webgpu::WebGPUInterfaceStub { public: + MockWebGPUInterface() { + procs_ = {}; + + // WebGPU functions the tests will call. No-op them since we don't have a + // real WebGPU device. + procs_.deviceReference = [](WGPUDevice) {}; + procs_.deviceRelease = [](WGPUDevice) {}; + } + MOCK_METHOD(gpu::webgpu::ReservedTexture, ReserveTexture, - (uint64_t device_client_id)); + (WGPUDevice device)); MOCK_METHOD(void, AssociateMailbox, - (GLuint64 device_client_id, + (GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, @@ -71,9 +80,12 @@ const GLbyte* mailbox)); MOCK_METHOD(void, DissociateMailbox, - (GLuint64 device_client_id, - GLuint texture_id, - GLuint texture_generation)); + (GLuint texture_id, GLuint texture_generation)); + + const DawnProcTable& GetProcs() const override { return procs_; } + + private: + DawnProcTable procs_; }; // The six reference pixels are: red, green, blue, white, black. @@ -360,7 +372,7 @@ base::MakeRefCounted<DawnControlClientHolder>(std::move(provider)); dawn_texture_provider_ = base::MakeRefCounted<DawnTextureFromImageBitmap>( - dawn_control_client_, 1 /* device_client_id */); + dawn_control_client_, fake_device_); test_context_provider_ = viz::TestContextProvider::Create(); InitializeSharedGpuContext(test_context_provider_.get()); @@ -372,6 +384,7 @@ scoped_refptr<DawnTextureFromImageBitmap> dawn_texture_provider_; scoped_refptr<viz::TestContextProvider> test_context_provider_; base::test::TaskEnvironment task_environment_; + WGPUDevice fake_device_ = reinterpret_cast<WGPUDevice>(this); }; TEST_F(DawnTextureFromImageBitmapTest, VerifyAccessTexture) { @@ -383,17 +396,18 @@ viz::TransferableResource resource; gpu::webgpu::ReservedTexture reservation = { - reinterpret_cast<WGPUTexture>(&resource), 1, 1}; + reinterpret_cast<WGPUTexture>(&resource), 1, 1, /* deviceId */ 2, + /* deviceGeneration */ 3}; // Test that ProduceDawnTextureFromImageBitmap calls ReserveTexture and // AssociateMailbox correctly. const GLbyte* mailbox_bytes = nullptr; - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); - EXPECT_CALL(*webgpu_, AssociateMailbox( - dawn_texture_provider_->GetDeviceClientIdForTest(), - _, reservation.id, reservation.generation, - WGPUTextureUsage_CopySrc, _)) + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation)); + EXPECT_CALL(*webgpu_, + AssociateMailbox(2, 3, reservation.id, reservation.generation, + WGPUTextureUsage_CopySrc, _)) .WillOnce(testing::SaveArg<5>(&mailbox_bytes)); WGPUTexture texture = @@ -410,7 +424,6 @@ // Test that FinishDawnTextureFromImageBitmapAccess calls DissociateMailbox // correctly. EXPECT_CALL(*webgpu_, DissociateMailbox( - dawn_texture_provider_->GetDeviceClientIdForTest(), reservation.id, reservation.generation)); dawn_texture_provider_->FinishDawnTextureFromImageBitmapAccess();
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc index e8dbf40..6f3878a 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -29,12 +29,12 @@ WebGPUSwapBufferProvider::WebGPUSwapBufferProvider( Client* client, scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id, + WGPUDevice device, WGPUTextureUsage usage, WGPUTextureFormat format) : dawn_control_client_(dawn_control_client), client_(client), - device_client_id_(device_client_id), + device_(device), usage_(usage), format_(WGPUFormatToViz(format)) { // Create a layer that will be used by the canvas and will ask for a @@ -50,10 +50,14 @@ // paths to keep the rendering correct in that cases. layer_->SetContentsOpaque(true); layer_->SetPremultipliedAlpha(true); + + dawn_control_client_->GetProcs().deviceReference(device_); } WebGPUSwapBufferProvider::~WebGPUSwapBufferProvider() { Neuter(); + dawn_control_client_->GetProcs().deviceRelease(device_); + device_ = nullptr; } cc::Layer* WebGPUSwapBufferProvider::CcLayer() { @@ -117,14 +121,14 @@ current_swap_buffer_->access_finished_token.GetConstData()); // Associate the mailbox to a dawn_wire client DawnTexture object - gpu::webgpu::ReservedTexture reservation = - webgpu->ReserveTexture(device_client_id_); + gpu::webgpu::ReservedTexture reservation = webgpu->ReserveTexture(device_); DCHECK(reservation.texture); wire_texture_id_ = reservation.id; wire_texture_generation_ = reservation.generation; webgpu->AssociateMailbox( - device_client_id_, 0, reservation.id, reservation.generation, usage_, + reservation.deviceId, reservation.deviceGeneration, reservation.id, + reservation.generation, usage_, reinterpret_cast<GLbyte*>(¤t_swap_buffer_->mailbox)); // When the page request a texture it means we'll need to present it on the @@ -139,7 +143,6 @@ viz::TransferableResource* out_resource, std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) { DCHECK(!neutered_); - if (!current_swap_buffer_ || neutered_) { return false; } @@ -152,8 +155,7 @@ // to the texture are errors. gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); DCHECK_NE(wire_texture_id_, 0u); - webgpu->DissociateMailbox(device_client_id_, wire_texture_id_, - wire_texture_generation_); + webgpu->DissociateMailbox(wire_texture_id_, wire_texture_generation_); // Make the compositor wait on previous Dawn commands. webgpu->GenUnverifiedSyncTokenCHROMIUM(
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h index 4927c03..e30ef00 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
@@ -35,7 +35,7 @@ WebGPUSwapBufferProvider( Client* client, scoped_refptr<DawnControlClientHolder> dawn_control_client, - uint64_t device_client_id, + WGPUDevice device, WGPUTextureUsage usage, WGPUTextureFormat format); ~WebGPUSwapBufferProvider() override; @@ -83,7 +83,7 @@ scoped_refptr<DawnControlClientHolder> dawn_control_client_; Client* client_; - uint64_t device_client_id_; + WGPUDevice device_; scoped_refptr<cc::TextureLayer> layer_; bool neutered_ = false;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc index 19100740..48d46ec5 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
@@ -19,8 +19,16 @@ class MockWebGPUInterface : public gpu::webgpu::WebGPUInterfaceStub { public: - MOCK_METHOD1(ReserveTexture, - gpu::webgpu::ReservedTexture(uint64_t device_client_id)); + MockWebGPUInterface() { + procs_ = {}; + + // WebGPU functions the tests will call. No-op them since we don't have a + // real WebGPU device. + procs_.deviceReference = [](WGPUDevice) {}; + procs_.deviceRelease = [](WGPUDevice) {}; + } + + MOCK_METHOD1(ReserveTexture, gpu::webgpu::ReservedTexture(WGPUDevice device)); // It is hard to use GMock with SyncTokens represented as GLByte*, instead we // remember which were the last sync tokens generated or waited upon. @@ -41,10 +49,14 @@ void WaitSyncTokenCHROMIUM(const GLbyte* sync_token_data) override { memcpy(&most_recent_waited_token, sync_token_data, sizeof(gpu::SyncToken)); } + + const DawnProcTable& GetProcs() const override { return procs_; } + gpu::SyncToken most_recent_generated_token; gpu::SyncToken most_recent_waited_token; private: + DawnProcTable procs_; uint64_t token_id_ = 42; }; @@ -58,13 +70,13 @@ WebGPUSwapBufferProviderForTests( bool* alive, Client* client, - uint64_t client_device_id_, + WGPUDevice device, scoped_refptr<DawnControlClientHolder> dawn_control_client, WGPUTextureUsage usage, WGPUTextureFormat format) : WebGPUSwapBufferProvider(client, dawn_control_client, - client_device_id_, + device, usage, format), alive_(alive) {} @@ -89,9 +101,8 @@ dawn_control_client_ = base::MakeRefCounted<DawnControlClientHolder>(std::move(provider)); - static const uint64_t kDeviceClientID = 1; provider_ = base::MakeRefCounted<WebGPUSwapBufferProviderForTests>( - &provider_alive_, &client_, kDeviceClientID, dawn_control_client_, + &provider_alive_, &client_, fake_device_, dawn_control_client_, WGPUTextureUsage_OutputAttachment, WGPUTextureFormat_RGBA8Unorm); } @@ -101,6 +112,7 @@ FakeProviderClient client_; scoped_refptr<WebGPUSwapBufferProviderForTests> provider_; bool provider_alive_ = true; + WGPUDevice fake_device_ = reinterpret_cast<WGPUDevice>(this); }; TEST_F(WebGPUSwapBufferProviderTest, @@ -123,17 +135,20 @@ std::unique_ptr<viz::SingleReleaseCallback> release_callback3; // Produce resources. - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation1)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation1)); provider_->GetNewTexture(kSize); EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource1, &release_callback1)); - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation2)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation2)); provider_->GetNewTexture(kSize); EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource2, &release_callback2)); - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation3)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation3)); provider_->GetNewTexture(kSize); EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource3, &release_callback3)); @@ -161,7 +176,8 @@ std::unique_ptr<viz::SingleReleaseCallback> release_callback; // Produce one resource of size kSize. - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation)); provider_->GetNewTexture(static_cast<IntSize>(kSize)); EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, &release_callback)); @@ -169,7 +185,8 @@ release_callback->Run(gpu::SyncToken(), false /* lostResource */); // Produce one resource of size kOtherSize. - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation)); provider_->GetNewTexture(static_cast<IntSize>(kOtherSize)); EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, &release_callback)); @@ -177,7 +194,8 @@ release_callback->Run(gpu::SyncToken(), false /* lostResource */); // Produce one resource of size kSize again. - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation)); provider_->GetNewTexture(static_cast<IntSize>(kSize)); EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, &release_callback)); @@ -195,7 +213,8 @@ // Produce the first resource, check that WebGPU will wait for the creation of // the shared image - EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + EXPECT_CALL(*webgpu_, ReserveTexture(fake_device_)) + .WillOnce(Return(reservation)); provider_->GetNewTexture(static_cast<IntSize>(kSize)); EXPECT_EQ(sii_->MostRecentGeneratedToken(), webgpu_->most_recent_waited_token);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc index e5e7c26d..389f524e 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/graphics/gpu_memory_buffer_image_copy.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "ui/gfx/gpu_fence.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index 1e21395..ab87c77 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -220,6 +220,11 @@ "//third_party/blink/renderer/platform:platform", "//third_party/blink/renderer/platform/wtf:buildflags", ] + + if (enable_blink_heap_use_v8_oilpan) { + deps += [ "//v8:v8_for_testing" ] + } + public_deps = [ "//base/test:test_support" ] }
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h b/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h index 92540bf..c376d67 100644 --- a/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h +++ b/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h
@@ -19,6 +19,23 @@ namespace blink { +class HeapPointersOnStackScope final { + STACK_ALLOCATED(); + + public: + explicit HeapPointersOnStackScope(ThreadState* state) : state_(state) { + DCHECK(!state_->heap_pointers_on_stack_forced_); + state_->heap_pointers_on_stack_forced_ = true; + } + ~HeapPointersOnStackScope() { + DCHECK(state_->heap_pointers_on_stack_forced_); + state_->heap_pointers_on_stack_forced_ = false; + } + + private: + ThreadState* const state_; +}; + class TestSupportingGC : public testing::Test { public: // Performs a precise garbage collection with eager sweeping.
diff --git a/third_party/blink/renderer/platform/heap/impl/member.h b/third_party/blink/renderer/platform/heap/impl/member.h index 7ab36a8..b3991ea 100644 --- a/third_party/blink/renderer/platform/heap/impl/member.h +++ b/third_party/blink/renderer/platform/heap/impl/member.h
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/construct_traits.h" #include "third_party/blink/renderer/platform/wtf/hash_functions.h" +#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h" namespace WTF { @@ -489,6 +490,8 @@ return m.IsHashTableDeletedValue(); } +constexpr auto kMemberDeletedValue = WTF::kHashTableDeletedValue; + } // namespace blink namespace WTF {
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state.h b/third_party/blink/renderer/platform/heap/impl/thread_state.h index ecb91be..9e15128 100644 --- a/third_party/blink/renderer/platform/heap/impl/thread_state.h +++ b/third_party/blink/renderer/platform/heap/impl/thread_state.h
@@ -192,7 +192,6 @@ class StatisticsCollector; struct Statistics; class SweepForbiddenScope; - class HeapPointersOnStackScope; using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*, v8::EmbedderGraph*, @@ -667,6 +666,7 @@ friend class BlinkGCObserver; friend class incremental_marking_test::IncrementalMarkingScope; + friend class HeapPointersOnStackScope; friend class IncrementalMarkingTestDriver; friend class HeapAllocator; template <typename T>
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h b/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h index 1c5be448..57a4748b 100644 --- a/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h +++ b/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h
@@ -77,23 +77,6 @@ GCForbiddenScope gc_forbidden_scope; }; -class ThreadState::HeapPointersOnStackScope final { - STACK_ALLOCATED(); - - public: - explicit HeapPointersOnStackScope(ThreadState* state) : state_(state) { - DCHECK(!state_->heap_pointers_on_stack_forced_); - state_->heap_pointers_on_stack_forced_ = true; - } - ~HeapPointersOnStackScope() { - DCHECK(state_->heap_pointers_on_stack_forced_); - state_->heap_pointers_on_stack_forced_ = false; - } - - private: - ThreadState* const state_; -}; - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_SCOPES_H_
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/heap_test_utilities.h b/third_party/blink/renderer/platform/heap/v8_wrapper/heap_test_utilities.h index 4867908..cce9cb8e 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/heap_test_utilities.h +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/heap_test_utilities.h
@@ -5,6 +5,50 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_TEST_UTILITIES_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_TEST_UTILITIES_H_ -// TODO(chromium:1056170): Implement wrapper. +#include "base/test/task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "v8/include/cppgc/testing.h" + +namespace blink { + +// Allows for overriding the stack state for the purpose of testing. Any garbage +// collection calls scoped with `HeapPointersOnStackScope` will perform +// conservative stack scanning, even if other (more local) hints indicate that +// there's no need for it. +class HeapPointersOnStackScope final { + STACK_ALLOCATED(); + + public: + explicit HeapPointersOnStackScope(const ThreadState* state) + : embedder_stack_state_( + state->cpp_heap().GetHeapHandle(), + cppgc::EmbedderStackState::kMayContainHeapPointers) {} + + HeapPointersOnStackScope(const HeapPointersOnStackScope&) = delete; + HeapPointersOnStackScope& operator=(const HeapPointersOnStackScope&) = delete; + + private: + cppgc::testing::OverrideEmbedderStackStateScope embedder_stack_state_; +}; + +class TestSupportingGC : public testing::Test { + public: + // Performs a precise garbage collection with eager sweeping. + static void PreciselyCollectGarbage() { + // TODO(1056170): Implement. + } + + // Performs a conservative garbage collection with eager sweeping. + static void ConservativelyCollectGarbage() { + // TODO(1056170): Implement. + } + + protected: + base::test::TaskEnvironment task_environment_; +}; + +} // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_TEST_UTILITIES_H_
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/member.h b/third_party/blink/renderer/platform/heap/v8_wrapper/member.h index 8ff02bd..54bbce3 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/member.h +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/member.h
@@ -23,6 +23,8 @@ return m == cppgc::kSentinelPointer; } +constexpr auto kMemberDeletedValue = cppgc::kSentinelPointer; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_MEMBER_H_
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h b/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h index 6b413f3..01f2416 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h
@@ -81,7 +81,6 @@ class PLATFORM_EXPORT ThreadState final { public: - class HeapPointersOnStackScope; class NoAllocationScope; static ALWAYS_INLINE ThreadState* Current() {
diff --git a/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h b/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h index f4caf77c..bec9605 100644 --- a/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h +++ b/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h
@@ -26,17 +26,6 @@ const cppgc::subtle::DisallowGarbageCollectionScope disallow_gc_; }; -// TODO(1056170): Implement, if necessary for testing. -class ThreadState::HeapPointersOnStackScope final { - STACK_ALLOCATED(); - - public: - explicit HeapPointersOnStackScope(ThreadState* state) {} - - HeapPointersOnStackScope(const HeapPointersOnStackScope&) = delete; - HeapPointersOnStackScope& operator=(const HeapPointersOnStackScope&) = delete; -}; - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_SCOPES_H_
diff --git a/third_party/blink/renderer/platform/loader/DEPS b/third_party/blink/renderer/platform/loader/DEPS index a648884..4d149b6 100644 --- a/third_party/blink/renderer/platform/loader/DEPS +++ b/third_party/blink/renderer/platform/loader/DEPS
@@ -15,6 +15,7 @@ "+net/url_request/redirect_info.h", "+services/metrics/public", # for UKM API "+services/network/public", # for Fetch API and CORS + "+third_party/blink/renderer/platform/back_forward_cache_utils.h", "+third_party/blink/renderer/platform/bindings/dom_wrapper_world.h", "+third_party/blink/renderer/platform/bindings/parkable_string.h", "+third_party/blink/renderer/platform/bindings/script_forbidden_scope.h", @@ -30,7 +31,7 @@ "+third_party/blink/renderer/platform/loader/fetch/cross_origin_attribute_value.h", "+third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h", "+third_party/blink/renderer/platform/mhtml", - "+third_party/blink/renderer/platform/mojo_binding_context.h", + "+third_party/blink/renderer/platform/mojo/mojo_binding_context.h", "+third_party/blink/renderer/platform/network", "+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/platform_probe_sink.h",
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 7ec622f..fa7f3e8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -75,7 +75,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h" #include "third_party/blink/renderer/platform/mhtml/archive_resource.h" #include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "third_party/blink/renderer/platform/network/network_utils.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index 78e3181..1190b90 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -43,7 +43,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h"
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 00e4628..6e4b4e6c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -55,6 +55,7 @@ #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_response.h" +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" @@ -441,7 +442,7 @@ // Only when this feature is turned on and the loading tasks keep being // processed and the data is queued up on the renderer, a page can stay in // BackForwardCache with network requests. - if (!base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable)) { + if (!IsInflightNetworkRequestBackForwardCacheSupportEnabled()) { feature_handle_for_scheduler_ = frame_or_worker_scheduler->RegisterFeature( GetFeatureFromRequestContextType(request_context),
diff --git a/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc b/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc index cda4325..09aa25e4 100644 --- a/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
@@ -9,6 +9,7 @@ #include "base/auto_reset.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom-blink.h" +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h" @@ -286,8 +287,7 @@ public: explicit Buffer(ResponseBodyLoader* owner) : owner_(owner), - max_bytes_to_read_(base::GetFieldTrialParamByFeatureAsInt( - blink::features::kLoadingTasksUnfreezable, + max_bytes_to_read_(GetLoadingTasksUnfreezableParamAsInt( "max_buffered_bytes", kDefaultMaxBufferedBodyBytesPerRequest)) {} @@ -482,7 +482,7 @@ suspended_state_ = suspended_state; if (IsSuspendedForBackForwardCache()) { - DCHECK(base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable)); + DCHECK(IsInflightNetworkRequestBackForwardCacheSupportEnabled()); // If we're already suspended (but not for back-forward cache), we might've // ignored some OnStateChange calls. if (was_suspended) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc index bd9ff844..058b166 100644 --- a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
@@ -10,6 +10,7 @@ #include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h" #include "third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h" @@ -447,6 +448,8 @@ scoped_feature_list_.InitAndEnableFeature( features::kLoadingTasksUnfreezable); } + WebRuntimeFeatures::EnableBackForwardCache( + DeferWithBackForwardCacheEnabled()); } bool DeferWithBackForwardCacheEnabled() { return GetParam(); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_mojo_url_loader_client.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_mojo_url_loader_client.cc index ca4baaa..9654c35 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_mojo_url_loader_client.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_mojo_url_loader_client.cc
@@ -19,6 +19,7 @@ #include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_mojo_url_loader_client_observer.h" +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" namespace blink { namespace { @@ -160,8 +161,7 @@ writable_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, std::move(task_runner)), - max_bytes_drained_(base::GetFieldTrialParamByFeatureAsInt( - blink::features::kLoadingTasksUnfreezable, + max_bytes_drained_(GetLoadingTasksUnfreezableParamAsInt( "max_buffered_bytes", kDefaultMaxBufferedBodyBytesPerRequest)) { pipe_drainer_ = @@ -284,17 +284,16 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner, bool bypass_redirect_checks, const GURL& request_url) - : url_loader_client_observer_(url_loader_client_observer), + : back_forward_cache_timeout_( + base::TimeDelta::FromSeconds(GetLoadingTasksUnfreezableParamAsInt( + "grace_period_to_finish_loading_in_seconds", + static_cast<int>( + kGracePeriodToFinishLoadingWhileInBackForwardCache + .InSeconds())))), + url_loader_client_observer_(url_loader_client_observer), task_runner_(std::move(task_runner)), bypass_redirect_checks_(bypass_redirect_checks), - last_loaded_url_(request_url) { - back_forward_cache_timeout_ = - base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt( - blink::features::kLoadingTasksUnfreezable, - "grace_period_to_finish_loading_in_seconds", - static_cast<int>( - kGracePeriodToFinishLoadingWhileInBackForwardCache.InSeconds()))); -} + last_loaded_url_(request_url) {} WebMojoURLLoaderClient::~WebMojoURLLoaderClient() = default; @@ -449,8 +448,7 @@ return; } - DCHECK( - base::FeatureList::IsEnabled(blink::features::kLoadingTasksUnfreezable)); + DCHECK(IsInflightNetworkRequestBackForwardCacheSupportEnabled()); // We want to run loading tasks while deferred (but without dispatching the // messages). Drain the original pipe containing the response body into a // new pipe so that we won't block the network service if we're deferred for
diff --git a/third_party/blink/renderer/platform/loader/web_mojo_url_loader_client_unittest.cc b/third_party/blink/renderer/platform/loader/web_mojo_url_loader_client_unittest.cc index 91753c4..9e7808d 100644 --- a/third_party/blink/renderer/platform/loader/web_mojo_url_loader_client_unittest.cc +++ b/third_party/blink/renderer/platform/loader/web_mojo_url_loader_client_unittest.cc
@@ -23,6 +23,7 @@ #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_mojo_url_loader_client_observer.h" +#include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" namespace blink { @@ -188,6 +189,9 @@ blink::features::kLoadingTasksUnfreezable); } + WebRuntimeFeatures::EnableBackForwardCache( + DeferWithBackForwardCacheEnabled()); + auto url_loader_factory = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(this); auto request = std::make_unique<network::ResourceRequest>();
diff --git a/third_party/blink/renderer/platform/mojo/DEPS b/third_party/blink/renderer/platform/mojo/DEPS index 188a723c..f9176306 100644 --- a/third_party/blink/renderer/platform/mojo/DEPS +++ b/third_party/blink/renderer/platform/mojo/DEPS
@@ -24,7 +24,6 @@ "+third_party/blink/renderer/platform/context_lifecycle_notifier.h", "+third_party/blink/renderer/platform/heap_observer_set.h", "+third_party/blink/renderer/platform/heap", - "+third_party/blink/renderer/platform/mojo_binding_context.h", "+third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h", ]
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h index 2b83de2..0fd2f4a 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h index 2335080..2bf75f1f 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc index 824a8ac..643a46d 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
@@ -17,7 +17,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc index 46f8a0c..3e1aa06 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h index 921add5..ed70fb9 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc index 84374fe..3baa8098 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h index e2775e189..58978f28 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h index b5a9bab..385192f 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc index ad7b5c1..2683da5 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
@@ -17,7 +17,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc index 7098c84..64ad258 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
@@ -14,7 +14,7 @@ #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h b/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h index 0c87f1d..cae3ed99 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set.h b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set.h index aeb682a..41894b49 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set.h
@@ -15,7 +15,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc index ec28b7d..8628a94 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_set_test.cc
@@ -17,7 +17,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc index 8ad6807..ac3bc72 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
@@ -14,7 +14,7 @@ #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h index aa48084..ae6158a8 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc index 9b4780b..6267e5e3 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" -#include "third_party/blink/renderer/platform/mojo_binding_context.h" +#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/mojo_binding_context.h b/third_party/blink/renderer/platform/mojo/mojo_binding_context.h similarity index 80% rename from third_party/blink/renderer/platform/mojo_binding_context.h rename to third_party/blink/renderer/platform/mojo/mojo_binding_context.h index f8c48a29..8911f0b 100644 --- a/third_party/blink/renderer/platform/mojo_binding_context.h +++ b/third_party/blink/renderer/platform/mojo/mojo_binding_context.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BINDING_CONTEXT_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BINDING_CONTEXT_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_BINDING_CONTEXT_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_BINDING_CONTEXT_H_ #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/platform/task_type.h" @@ -31,4 +31,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BINDING_CONTEXT_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_BINDING_CONTEXT_H_
diff --git a/third_party/blink/renderer/platform/network/BUILD.gn b/third_party/blink/renderer/platform/network/BUILD.gn index 3b500f1..7e1970a 100644 --- a/third_party/blink/renderer/platform/network/BUILD.gn +++ b/third_party/blink/renderer/platform/network/BUILD.gn
@@ -78,6 +78,7 @@ testonly = true sources = [ + "content_security_policy_parsers_test.cc", "encoded_form_data_test.cc", "http_parsers_test.cc", "mime/mime_type_registry_test.cc",
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc b/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc index 212c2b9..4148687d 100644 --- a/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc +++ b/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
@@ -7,6 +7,8 @@ #include "services/network/public/mojom/content_security_policy.mojom-blink.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" +#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h" +#include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" namespace blink { @@ -16,7 +18,7 @@ } bool IsCSPDirectiveValueCharacter(UChar c) { - return IsASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR + return IsASCIISpace(c) || (IsASCIIPrintable(c) && c != ',' && c != ';'); } // Only checks for general Base64(url) encoded chars, not '=' chars since '=' is @@ -57,4 +59,51 @@ return !IsASCIISpace(c) && c != '/'; } +bool MatchesTheSerializedCSPGrammar(const String& value) { + return WTF::VisitCharacters(value, [](const auto* chars, unsigned len) { + const auto* it = chars; + const auto* end = chars + len; + + while (it < end) { + // Consume any whitespaces. + while (it < end && IsASCIISpace(*it)) + it++; + + // Consume a directive name. + bool directive_name_found = false; + while (it < end && IsCSPDirectiveNameCharacter(*it)) { + it++; + directive_name_found = true; + } + + // Consume the directive value (if any), but only if there is a directive + // name followed by at least one whitespace. + if (directive_name_found) { + bool space_found = false; + while (it < end && IsASCIISpace(*it)) { + it++; + space_found = true; + } + if (space_found) { + while (it < end && IsCSPDirectiveValueCharacter(*it)) + it++; + } + } + + if (it == end) + return true; + + // There should be at least one ';'. + bool semicolon_found = false; + while (it < end && *it == ';') { + it++; + semicolon_found = true; + } + if (!semicolon_found) + return false; + } + return true; + }); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_parsers.h b/third_party/blink/renderer/platform/network/content_security_policy_parsers.h index 248f54f..957b557 100644 --- a/third_party/blink/renderer/platform/network/content_security_policy_parsers.h +++ b/third_party/blink/renderer/platform/network/content_security_policy_parsers.h
@@ -35,6 +35,12 @@ // positional and may only appear at the end of a Base64 encoded string. PLATFORM_EXPORT bool IsBase64EncodedCharacter(UChar); +// Check if value matches +// https://w3c.github.io/webappsec-csp/#grammardef-serialized-policy. We also +// allow a trailing ';', repeated ';'s, and a trailing ';' followed by spaces. +PLATFORM_EXPORT +bool MatchesTheSerializedCSPGrammar(const String& value); + } // namespace blink #endif
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_parsers_test.cc b/third_party/blink/renderer/platform/network/content_security_policy_parsers_test.cc new file mode 100644 index 0000000..adbc99d --- /dev/null +++ b/third_party/blink/renderer/platform/network/content_security_policy_parsers_test.cc
@@ -0,0 +1,30 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(ContentSecurityPolicyParsers, MatchesTheSerializedCSPGrammar) { + struct { + String value; + bool expected; + } testCases[]{ + {"script-src 'none'; invalid-directive ", true}, + {"script-src 'none'; invalid-directive;", true}, + {" script-src 'none' https://www.example.org ; ;invalid-directive; ;", + true}, + {"script-src 'none', media-src 'none'", false}, + {"script-src 'none'; /invalid-directive-name", false}, + }; + + for (const auto& testCase : testCases) { + EXPECT_EQ(MatchesTheSerializedCSPGrammar(testCase.value), + testCase.expected); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_response_headers.cc b/third_party/blink/renderer/platform/network/content_security_policy_response_headers.cc index bea1c2b..e9b29f2 100644 --- a/third_party/blink/renderer/platform/network/content_security_policy_response_headers.cc +++ b/third_party/blink/renderer/platform/network/content_security_policy_response_headers.cc
@@ -36,23 +36,17 @@ const ResourceResponse& response) : ContentSecurityPolicyResponseHeaders( response.HttpHeaderFields(), + response.CurrentRequestUrl(), SchemeRegistry::SchemeSupportsWasmEvalCSP( response.CurrentRequestUrl().Protocol())) {} ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders( const HTTPHeaderMap& headers, + const KURL& response_url, bool should_parse_wasm_eval) : content_security_policy_(headers.Get(http_names::kContentSecurityPolicy)), content_security_policy_report_only_( headers.Get(http_names::kContentSecurityPolicyReportOnly)), + response_url_(response_url), should_parse_wasm_eval_(should_parse_wasm_eval) {} - -ContentSecurityPolicyResponseHeaders -ContentSecurityPolicyResponseHeaders::IsolatedCopy() const { - ContentSecurityPolicyResponseHeaders headers; - headers.content_security_policy_ = content_security_policy_.IsolatedCopy(); - headers.content_security_policy_report_only_ = - content_security_policy_report_only_.IsolatedCopy(); - return headers; -} }
diff --git a/third_party/blink/renderer/platform/network/content_security_policy_response_headers.h b/third_party/blink/renderer/platform/network/content_security_policy_response_headers.h index 71d4639..0373a70 100644 --- a/third_party/blink/renderer/platform/network/content_security_policy_response_headers.h +++ b/third_party/blink/renderer/platform/network/content_security_policy_response_headers.h
@@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_CONTENT_SECURITY_POLICY_RESPONSE_HEADERS_H_ #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -44,6 +45,7 @@ explicit ContentSecurityPolicyResponseHeaders(const ResourceResponse&); explicit ContentSecurityPolicyResponseHeaders( const HTTPHeaderMap&, + const KURL& response_url, bool should_parse_wasm_eval = false); const String& ContentSecurityPolicy() const { @@ -52,32 +54,18 @@ const String& ContentSecurityPolicyReportOnly() const { return content_security_policy_report_only_; } - - ContentSecurityPolicyResponseHeaders IsolatedCopy() const; + const KURL& ResponseUrl() const { return response_url_; } bool ShouldParseWasmEval() const { return should_parse_wasm_eval_; } private: String content_security_policy_; String content_security_policy_report_only_; + KURL response_url_; const bool should_parse_wasm_eval_ = false; }; } // namespace blink -namespace WTF { - -template <> -struct CrossThreadCopier<blink::ContentSecurityPolicyResponseHeaders> { - STATIC_ONLY(CrossThreadCopier); - using Type = blink::ContentSecurityPolicyResponseHeaders; - PLATFORM_EXPORT static Type Copy( - const blink::ContentSecurityPolicyResponseHeaders& headers) { - return headers.IsolatedCopy(); - } -}; - -} // namespace WTF - #endif
diff --git a/third_party/blink/renderer/platform/scheduler/DEPS b/third_party/blink/renderer/platform/scheduler/DEPS index b6650d8..94505c5f 100644 --- a/third_party/blink/renderer/platform/scheduler/DEPS +++ b/third_party/blink/renderer/platform/scheduler/DEPS
@@ -53,6 +53,7 @@ "+components/scheduling_metrics", "+services/metrics", + "+third_party/blink/renderer/platform/back_forward_cache_utils.h", "+third_party/blink/renderer/platform/bindings/parkable_string_manager.h", "+third_party/blink/renderer/platform/instrumentation", "+third_party/blink/renderer/platform/platform_export.h",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index f2d2927..1ac5f4fd 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -18,6 +18,7 @@ #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/common/features.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" @@ -393,7 +394,7 @@ case TaskType::kNetworkingWithURLLoaderAnnotation: return LoadingTaskQueueTraits(); case TaskType::kNetworkingUnfreezable: - return base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable) + return IsInflightNetworkRequestBackForwardCacheSupportEnabled() ? UnfreezableLoadingTaskQueueTraits() : LoadingTaskQueueTraits(); case TaskType::kNetworkingControl:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index fa6bc7f..9651483 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h" +#include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/renderer/platform/scheduler/common/features.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" @@ -1044,7 +1045,9 @@ public: FrameSchedulerImplTestWithUnfreezableLoading() : FrameSchedulerImplTest({blink::features::kLoadingTasksUnfreezable}, - {}) {} + {}) { + WebRuntimeFeatures::EnableBackForwardCache(true); + } }; TEST_F(FrameSchedulerImplTestWithUnfreezableLoading,
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index b945303..a765454 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -1051,7 +1051,8 @@ return any_thread_; } - // Don't access compositor_thread_only_, instead use CompositorThreadOnly(). + // Don't access compositor_thread_only_, instead use + // |GetCompositorThreadOnly()|. CompositorThreadOnly compositor_thread_only_; CompositorThreadOnly& GetCompositorThreadOnly() { compositor_thread_only_.CheckOnValidThread();
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc index 3ad29aa..1e28f35 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/renderer/platform/back_forward_cache_utils.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h" @@ -192,7 +193,7 @@ // Get(LocalFrame). (https://crbug.com/670534) return unpausable_task_queue_->CreateTaskRunner(type); case TaskType::kNetworkingUnfreezable: - return base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable) + return IsInflightNetworkRequestBackForwardCacheSupportEnabled() ? unpausable_task_queue_->CreateTaskRunner(type) : pausable_task_queue_->CreateTaskRunner(type); case TaskType::kMainThreadTaskQueueV8:
diff --git a/third_party/blink/renderer/platform/testing/DEPS b/third_party/blink/renderer/platform/testing/DEPS index 8abd368..70871e2f 100644 --- a/third_party/blink/renderer/platform/testing/DEPS +++ b/third_party/blink/renderer/platform/testing/DEPS
@@ -35,7 +35,7 @@ "+third_party/blink/renderer/platform/instrumentation/histogram.h", "+third_party/blink/renderer/platform/language.h", "+third_party/blink/renderer/platform/loader", - "+third_party/blink/renderer/platform/mojo_binding_context.h", + "+third_party/blink/renderer/platform/mojo/mojo_binding_context.h", "+third_party/blink/renderer/platform/network", "+third_party/blink/renderer/platform/peerconnection", "+third_party/blink/renderer/platform/platform_export.h",
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support.cc b/third_party/blink/renderer/platform/testing/testing_platform_support.cc index 71a457c4..57508ee9 100644 --- a/third_party/blink/renderer/platform/testing/testing_platform_support.cc +++ b/third_party/blink/renderer/platform/testing/testing_platform_support.cc
@@ -43,6 +43,7 @@ #include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/renderer/platform/font_family_names.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/language.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" #include "third_party/blink/renderer/platform/network/http_names.h" @@ -124,7 +125,7 @@ } void TestingPlatformSupport::RunUntilIdle() { - ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current()); + HeapPointersOnStackScope scan_stack(ThreadState::Current()); base::RunLoop().RunUntilIdle(); }
diff --git a/third_party/blink/renderer/platform/testing/unit_test_helpers.cc b/third_party/blink/renderer/platform/testing/unit_test_helpers.cc index 89d87490..156a07b 100644 --- a/third_party/blink/renderer/platform/testing/unit_test_helpers.cc +++ b/third_party/blink/renderer/platform/testing/unit_test_helpers.cc
@@ -34,6 +34,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" @@ -66,7 +67,7 @@ // The following runloop can execute non-nested tasks with heap pointers // living on stack, so we force both Oilpan and Unified GC to visit the stack. - ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current()); + HeapPointersOnStackScope scan_stack(ThreadState::Current()); EnterRunLoop(); }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 0f3831d..9528eab 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3332,7 +3332,7 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/grid-positioned-items-gaps-001.html [ Crash Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/grid-positioned-items-gaps-rtl-001.html [ Crash Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/grid-positioned-items-implicit-grid-001.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/grid-positioned-items-padding-001.html [ Crash ] +crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/grid-positioned-items-padding-001.html [ Crash Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/grid-positioned-items-within-grid-implicit-track-001.html [ Crash Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-002.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/orthogonal-positioned-grid-descendants-003.html [ Failure ] @@ -3378,7 +3378,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-alignment-style-changes-006.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-alignment-style-changes-007.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-alignment-style-changes-008.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-baseline-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-baseline-004.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-baseline-align-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-baseline-align-cycles-001.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index e823b332..6558bd7 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -382480,6 +382480,13 @@ {} ] ], + "display-change-with-transform.html": [ + "36aa438b6e81f0ec7cfc10aa09d7fd9ac4b8645c", + [ + null, + {} + ] + ], "fixed-position-move.html": [ "877c2ba4b34615c41a5b21dbf114df69eef04352", [ @@ -392903,7 +392910,7 @@ ] ], "pointerevent_mouse_capture_change_hover.html": [ - "10b19f8474a95126302f824390302007a4f63fea", + "ef824dafd963bc97f59283d833d0e0cb4fe97fc8", [ null, {
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required-csp-header-cascade.html b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required-csp-header-cascade.html index f130b17..92fe2dd 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required-csp-header-cascade.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required-csp-header-cascade.html
@@ -34,8 +34,8 @@ "csp2": "script-src 'unsafe-inline'; style-src 'self';", "expected1": null, "expected2": "script-src 'unsafe-inline'; style-src 'self';"}, - { "name": "Test invalid policy on first iframe (bad directive)", - "csp1": "default-src http://example.com; invalid-policy-name http://example.com", + { "name": "Test invalid policy on first iframe (bad directive name)", + "csp1": "default-src http://example.com; i//nvalid-policy-name http://example.com", "csp2": "script-src 'unsafe-inline'; style-src 'self';", "expected1": null, "expected2": "script-src 'unsafe-inline'; style-src 'self';"}, @@ -44,9 +44,9 @@ "csp2": "script-src 'unsafe-inline'; style-src 'self';", "expected1": null, "expected2": "script-src 'unsafe-inline'; style-src 'self';"}, - { "name": "Test invalid policy on second iframe (bad directive)", + { "name": "Test invalid policy on second iframe (bad directive name)", "csp1": "script-src 'unsafe-inline'; style-src 'self';", - "csp2": "default-src http://example.com; invalid-policy-name http://example.com", + "csp2": "default-src http://example.com; i//nvalid-policy-name http://example.com", "expected1": "script-src 'unsafe-inline'; style-src 'self';", "expected2": "script-src 'unsafe-inline'; style-src 'self';"}, { "name": "Test invalid policy on second iframe (report directive)",
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html index ae121899..414f9b7 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html
@@ -16,126 +16,64 @@ var tests = [ // CRLF characters { "name": "\\r\\n character after directive name", - "csp": "script-src\r\n'unsafe-inline'", + "csp": "style-src\r\n'unsafe-inline'", "expected": null }, { "name": "\\r\\n character in directive value", - "csp": "script-src 'unsafe-inline'\r\n'unsafe-eval'", + "csp": "style-src 'unsafe-inline'\r\n'unsafe-eval'", "expected": null }, { "name": "\\n character after directive name", - "csp": "script-src\n'unsafe-inline'", + "csp": "style-src\n'unsafe-inline'", "expected": null }, { "name": "\\n character in directive value", - "csp": "script-src 'unsafe-inline'\n'unsafe-eval'", + "csp": "style-src 'unsafe-inline'\n'unsafe-eval'", "expected": null }, { "name": "\\r character after directive name", - "csp": "script-src\r'unsafe-inline'", + "csp": "style-src\r'unsafe-inline'", "expected": null }, { "name": "\\r character in directive value", - "csp": "script-src 'unsafe-inline'\r'unsafe-eval'", - "expected": null }, - - // HTML encoded CRLF characters - { "name": "%0D%0A character after directive name", - "csp": "script-src%0D%0A'unsafe-inline'", - "expected": null }, - { "name": "%0D%0A character in directive value", - "csp": "script-src 'unsafe-inline'%0D%0A'unsafe-eval'", - "expected": null }, - { "name": "%0A character after directive name", - "csp": "script-src%0A'unsafe-inline'", - "expected": null }, - { "name": "%0A character in directive value", - "csp": "script-src 'unsafe-inline'%0A'unsafe-eval'", - "expected": null }, - { "name": "%0D character after directive name", - "csp": "script-src%0D'unsafe-inline'", - "expected": null }, - { "name": "%0D character in directive value", - "csp": "script-src 'unsafe-inline'%0D'unsafe-eval'", + "csp": "style-src 'unsafe-inline'\r'unsafe-eval'", "expected": null }, // Attempt HTTP Header injection { "name": "Attempt injecting after directive name using \\r\\n", - "csp": "script-src\r\nTest-Header-Injection: dummy", + "csp": "style-src\r\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after directive name using \\r", - "csp": "script-src\rTest-Header-Injection: dummy", + "csp": "style-src\rTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after directive name using \\n", - "csp": "script-src\nTest-Header-Injection: dummy", + "csp": "style-src\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after directive value using \\r\\n", - "csp": "script-src example.com\r\nTest-Header-Injection: dummy", + "csp": "style-src example.com\r\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after directive value using \\r", - "csp": "script-src example.com\rTest-Header-Injection: dummy", + "csp": "style-src example.com\rTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after directive value using \\n", - "csp": "script-src example.com\nTest-Header-Injection: dummy", + "csp": "style-src example.com\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after semicolon using \\r\\n", - "csp": "script-src example.com;\r\nTest-Header-Injection: dummy", + "csp": "style-src example.com;\r\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after semicolon using \\r", - "csp": "script-src example.com;\rTest-Header-Injection: dummy", + "csp": "style-src example.com;\rTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after semicolon using \\n", - "csp": "script-src example.com;\nTest-Header-Injection: dummy", + "csp": "style-src example.com;\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after space between name and value using \\r\\n", - "csp": "script-src \r\nTest-Header-Injection: dummy", + "csp": "style-src \r\nTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after space between name and value using \\r", - "csp": "script-src \rTest-Header-Injection: dummy", + "csp": "style-src \rTest-Header-Injection: dummy", "expected": null }, { "name": "Attempt injecting after space between name and value using \\n", - "csp": "script-src \nTest-Header-Injection: dummy", + "csp": "style-src \nTest-Header-Injection: dummy", "expected": null }, - - // Attempt HTTP Header injection using URL encoded characters - { "name": "Attempt injecting after directive name using %0D%0A", - "csp": "script-src%0D%0ATest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after directive name using %0D", - "csp": "script-src%0DTest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after directive name using %0A", - "csp": "script-src%0ATest-Header-Injection: dummy", - "expected": null }, - - { "name": "Attempt injecting after directive value using %0D%0A", - "csp": "script-src example.com%0D%0ATest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after directive value using %0D", - "csp": "script-src example.com%0DTest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after directive value using %0A", - "csp": "script-src example.com%0ATest-Header-Injection: dummy", - "expected": null }, - - { "name": "Attempt injecting after semicolon using %0D%0A", - "csp": "script-src example.com;%0D%0ATest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after semicolon using %0D", - "csp": "script-src example.com;%0DTest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after semicolon using %0A", - "csp": "script-src example.com;%0ATest-Header-Injection: dummy", - "expected": null }, - - { "name": "Attempt injecting after space between name and value using %0D%0A", - "csp": "script-src %0D%0ATest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after space between name and value using %0D", - "csp": "script-src %0DTest-Header-Injection: dummy", - "expected": null }, - { "name": "Attempt injecting after space between name and value using %0A", - "csp": "script-src %0ATest-Header-Injection: dummy", - "expected": null }, - ]; tests.forEach(test => {
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html index fbaa42d..a9ad787 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html
@@ -24,39 +24,39 @@ { "name": "Send Sec-Required-CSP Header on change of `src` attribute on iframe.", "csp": "script-src 'unsafe-inline'", "expected": "script-src 'unsafe-inline'" }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - gibberish csp", + { "name": "Wrong but allowed value of `csp` should still trigger sending Sec-Required-CSP Header - gibberish csp", "csp": "completely wrong csp", - "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - unknown policy name", + "expected": "completely wrong csp" }, + { "name": "Wrong but allowed value of `csp` should still trigger sending Sec-Required-CSP Header - unknown policy name", "csp": "invalid-policy-name http://example.com", + "expected": "invalid-policy-name http://example.com" }, + { "name": "Wrong but allowed value of `csp` should still trigger sending Sec-Required-CSP Header - unknown policy name in multiple directives", + "csp": "media-src http://example.com; invalid-policy-name http://example.com", + "expected": "media-src http://example.com; invalid-policy-name http://example.com" }, + { "name": "Wrong but allowed value of `csp` should still trigger sending Sec-Required-CSP Header - misspeled 'none'", + "csp": "media-src 'non'", + "expected": "media-src 'non'" }, + { "name": "Wrong but allowed value of `csp` should still trigger sending Sec-Required-CSP Header - query values in path", + "csp": "script-src 'unsafe-inline' 127.0.0.1:8000/path?query=string", + "expected": "script-src 'unsafe-inline' 127.0.0.1:8000/path?query=string" }, + { "name": "Wrong but allowed value of `csp` should still trigger sending Sec-Required-CSP Header - missing semicolon", + "csp": "script-src 'unsafe-inline' 'self' object-src 'self' style-src *", + "expected": "script-src 'unsafe-inline' 'self' object-src 'self' style-src *" }, + { "name": "Wrong and dangerous value of `csp` should not trigger sending Sec-Required-CSP Header - comma separated", + "csp": "script-src 'unsafe-inline' 'self', object-src 'none'", "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - unknown policy name in multiple directives", - "csp": "default-src http://example.com; invalid-policy-name http://example.com", - "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - misspeled 'none'", - "csp": "default-src 'non'", - "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - query values in path", - "csp": "script-src 127.0.0.1:8000/path?query=string", - "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - missing semicolon", - "csp": "script-src 'self' object-src 'self' style-src *", - "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - comma separated", - "csp": "script-src 'none', object-src 'none'", - "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - html encoded string", + { "name": "Wrong and dangerous value of `csp` should not trigger sending Sec-Required-CSP Header - invalid characters in directive names", // script-src 127.0.0.1:8000 - "csp": "script-src 127.0.0.1:8000", + "csp": "script-src 'unsafe-inline' 127.0.0.1:8000", "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - url encoded string", + { "name": "Wrong and dangerous value of `csp` should not trigger sending Sec-Required-CSP Header - invalid character in directive name", // script-src 127.0.0.1:8000 - "csp": "script-src%20127.0.0.1%3A8000", + "csp": "media-src%20127.0.0.1%3A8000", "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - report-uri present", + { "name": "Wrong and dangerous value of `csp` should not trigger sending Sec-Required-CSP Header - report-uri present", "csp": "script-src 'unsafe-inline'; report-uri resources/dummy-report.php", "expected": null }, - { "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - report-to present", + { "name": "Wrong and dangerous value of `csp` should not trigger sending Sec-Required-CSP Header - report-to present", "csp": "script-src 'unsafe-inline'; report-to resources/dummy-report.php", "expected": null }, ];
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py index 90fc1d11..b704dfe 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py
@@ -11,9 +11,6 @@ header = request.headers.get(b"Sec-Required-CSP"); message[u'required_csp'] = isomorphic_decode(header) if header else None - header = request.headers.get(b"Sec-Required-CSP"); - message[u'required_csp'] = isomorphic_decode(header) if header else None - second_level_iframe_code = u"" if b"include_second_level_iframe" in request.GET: if b"second_level_iframe_csp" in request.GET and request.GET[b"second_level_iframe_csp"] != b"":
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/storage-buckets.tentative.idl b/third_party/blink/web_tests/external/wpt/interfaces/storage-buckets.tentative.idl new file mode 100644 index 0000000..f44595c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/interfaces/storage-buckets.tentative.idl
@@ -0,0 +1,37 @@ +[ + Exposed=(Window,Worker), + SecureContext +] interface BucketManager { + Promise<StorageBucket> open(DOMString name, + optional StorageBucketOptions options = {}); + Promise<sequence<DOMString>> keys(); + Promise<undefined> delete(DOMString name); +}; + +dictionary StorageBucketOptions { + DOMString? title = null; + boolean persisted = false; + StorageBucketDurability durability = "relaxed"; + unsigned long long? quota = null; + DOMTimeStamp? expires = null; +}; + +enum StorageBucketDurability { + "strict", + "relaxed" +}; + +[ + Exposed=(Window,Worker), + SecureContext +] interface StorageBucket { + [Exposed=Window] Promise<boolean> persist(); + Promise<boolean> persisted(); + + Promise<StorageEstimate> estimate(); + + Promise<StorageBucketDurability> durability(); + + Promise<undefined> setExpires(DOMTimeStamp expires); + Promise<DOMTimeStamp> expires(); +};
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_capture_change_hover.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_capture_change_hover.html index 10b19f8..ef824da 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_capture_change_hover.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_mouse_capture_change_hover.html
@@ -69,6 +69,7 @@ document.addEventListener("pointerdown", setCaptureGreen); await new test_driver.Actions() + .addPointer("mouse") .pointerMove(25, 25, {origin: green}) .pointerDown() .pointerMove(30, 30, {origin: green}) @@ -88,22 +89,23 @@ assert_equals(getComputedStyle(blue).backgroundColor, "rgb(0, 0, 255)", "blue should be blue."); document.removeEventListener("pointerdown", setCaptureGreen); // Release mouse button. - await new test_driver.Actions().pointerUp().send(); + await new test_driver.Actions().addPointer("mouse").pointerUp().send(); }, "Mouse down and capture to green."); promise_test (async() => { // Move to (0, 0) to reset hovering. - await new test_driver.Actions().pointerMove(0, 0).send(); + await new test_driver.Actions().addPointer("mouse").pointerMove(0, 0).send(); receivedEventList = []; // pointerdown at green -> set capture to blue -> blue receive the following moves. document.addEventListener("pointerdown", setCaptureBlue); await new test_driver.Actions() + .addPointer("mouse") .pointerMove(25, 25, {origin: green}) .pointerDown() .pointerMove(30, 30, {origin: green}) - .pointerMove(30, 30, {origin: green}) + .pointerMove(31, 31, {origin: green}) .send(); expectedEventList = ["green received pointerover", @@ -123,12 +125,12 @@ assert_equals(getComputedStyle(blue).backgroundColor, "rgb(255, 0, 0)", "blue should be red (hover)."); document.removeEventListener("pointerdown", setCaptureBlue); // Release mouse button. - await new test_driver.Actions().pointerUp().send(); + await new test_driver.Actions().addPointer("mouse").pointerUp().send(); }, "Mouse down at green and capture to blue."); promise_test (async() => { // Move to (0, 0) to reset hovering. - await new test_driver.Actions().pointerMove(0, 0).send(); + await new test_driver.Actions().addPointer("mouse").pointerMove(0, 0).send(); receivedEventList = []; // pointerdown at green -> set capture to green -> green receive first move -> release capture -> blue receive the next move @@ -136,6 +138,7 @@ green.addEventListener("pointermove", releaseCapture); await new test_driver.Actions() + .addPointer("mouse") .pointerMove(25, 25, {origin: green}) .pointerDown() .pointerMove(30, 30, {origin: blue}) @@ -161,7 +164,7 @@ green.removeEventListener("pointerdown", setCaptureBlue); green.removeEventListener("pointermove", releaseCapture); // Release mouse button. - await new test_driver.Actions().pointerUp().send(); + await new test_driver.Actions().addPointer("mouse").pointerUp().send(); }, "Mouse down and capture to green, move to blue and release capture"); } </script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt new file mode 100644 index 0000000..3c7cad8 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt
@@ -0,0 +1,7 @@ +Tests that raw response headers are correctly reported after navigation. + +Fetching resource: +Response status: 200 +Fetching same resource again: +Response status: 304 +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js new file mode 100644 index 0000000..c89c2c4 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js
@@ -0,0 +1,23 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank( + `Tests that raw response headers are correctly reported after navigation.\n` + ); + + async function fetchAndLogResponseStatus() { + session.evaluate(`fetch('http://devtools.test:8000/devtools/network/resources/resource.php?cached=1')`); + const response = (await dp.Network.onceResponseReceived()).params.response; + testRunner.log('Response status: ' + response.status); + } + + await dp.Page.enable(); + await dp.Network.enable(); + await dp.Page.navigate({url: 'http://devtools.test:8000/inspector-protocol/network/resources/hello-world.html'}); + + testRunner.log('Fetching resource:'); + await fetchAndLogResponseStatus(); + + testRunner.log('Fetching same resource again:'); + await fetchAndLogResponseStatus(); + + testRunner.completeTest(); +}) \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/mojo/bindings-lite-tests.js b/third_party/blink/web_tests/http/tests/mojo/bindings-lite-tests.js index ed4b646..056d174e 100644 --- a/third_party/blink/web_tests/http/tests/mojo/bindings-lite-tests.js +++ b/third_party/blink/web_tests/http/tests/mojo/bindings-lite-tests.js
@@ -214,6 +214,24 @@ }); }, 'can use generated flushForTesting API for synchronization in tests'); +promise_test(async () => { + let clientRouter = new liteJsTest.mojom.SubinterfaceClientCallbackRouter; + let clientRemote = clientRouter.$.bindNewPipeAndPassRemote(); + + let actualDidFlushes = 0; + clientRouter.didFlush.addListener(values => { + actualDidFlushes++; + }); + + const kExpectedDidFlushes = 10000; + for (let i = 0; i < kExpectedDidFlushes; i++) { + clientRemote.didFlush([]); + } + + await clientRouter.$.flush(); + assert_equals(actualDidFlushes, kExpectedDidFlushes); +}, 'can use generated flush API of callbackrouter/receiver for synchronization'); + promise_test(async(t) => { const impl = new TargetImpl; const remote = impl.target.$.bindNewPipeAndPassRemote();
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-config.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-config.tentative.html index 511e2bc..54318c3 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-config.tentative.html +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-config.tentative.html
@@ -37,10 +37,10 @@ let s = new Sanitizer(options); assert_true(s instanceof Sanitizer); - assert_equals(s.sanitizeToString("<div>balabala</div><test>test</test>"), "<div>balabala</div>test"); + assert_equals(s.sanitizeToString("<div>balabala</div><p>test</p>"), "<div>balabala</div>test"); - options.allowElements.push("test"); - assert_equals(s.sanitizeToString("<div>balabala</div><test>test</test>"), "<div>balabala</div>test"); + options.allowElements.push("p"); + assert_equals(s.sanitizeToString("<div>balabala</div><p>test</p>"), "<div>balabala</div>test"); }, "SanitizerAPI config allowElements is not editable."); test(t => { @@ -48,10 +48,10 @@ let s = new Sanitizer(options); assert_true(s instanceof Sanitizer); - assert_equals(s.sanitizeToString("<div>balabala</div><test>test</test>"), "balabala<test>test</test>"); + assert_equals(s.sanitizeToString("<div>balabala</div><p>test</p>"), "balabala<p>test</p>"); - options.blockElements.push("test"); - assert_equals(s.sanitizeToString("<div>balabala</div><test>test</test>"), "balabala<test>test</test>"); + options.blockElements.push("p"); + assert_equals(s.sanitizeToString("<div>balabala</div><p>test</p>"), "balabala<p>test</p>"); }, "SanitizerAPI config blockElements is not editable."); test(t => { @@ -59,10 +59,10 @@ let s = new Sanitizer(options); assert_true(s instanceof Sanitizer); - assert_equals(s.sanitizeToString("<div>balabala</div><test>test</test>"), "<test>test</test>"); + assert_equals(s.sanitizeToString("<div>balabala</div><p>test</p>"), "<p>test</p>"); - options.dropElements.push("test"); - assert_equals(s.sanitizeToString("<div>balabala</div><test>test</test>"), "<test>test</test>"); + options.dropElements.push("p"); + assert_equals(s.sanitizeToString("<div>balabala</div><p>test</p>"), "<p>test</p>"); }, "SanitizerAPI config dropElements is not editable."); test(t => {
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative-expected.txt b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative-expected.txt new file mode 100644 index 0000000..dd80112 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative-expected.txt
@@ -0,0 +1,135 @@ +This is a testharness.js-based test. +Found 131 tests; 130 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS SanitizerAPI sanitize function without argument should throw an error. +PASS SanitizerAPI sanitize function for null. +PASS SanitizerAPI with config: string, sanitize from string function for string +PASS SanitizerAPI with config: html fragment, sanitize from string function for html fragment +PASS SanitizerAPI with config: broken html, sanitize from string function for broken html +PASS SanitizerAPI with config: empty object, sanitize from string function for empty object +PASS SanitizerAPI with config: number, sanitize from string function for number +PASS SanitizerAPI with config: zeros, sanitize from string function for zeros +PASS SanitizerAPI with config: arithmetic, sanitize from string function for arithmetic +PASS SanitizerAPI with config: empty string, sanitize from string function for empty string +PASS SanitizerAPI with config: undefined, sanitize from string function for undefined +PASS SanitizerAPI with config: document, sanitize from string function for document +PASS SanitizerAPI with config: html without close tag, sanitize from string function for html without close tag +PASS SanitizerAPI with config: scripts for default configs, sanitize from string function for scripts for default configs +PASS SanitizerAPI with config: onclick scripts, sanitize from string function for onclick scripts +PASS SanitizerAPI with config: plaintext, sanitize from string function for plaintext +PASS SanitizerAPI with config: xmp, sanitize from string function for xmp +PASS SanitizerAPI with config: malformed HTML, sanitize from string function for malformed HTML +PASS SanitizerAPI with config: invalid config_input, sanitize from string function for invalid config_input +PASS SanitizerAPI with config: empty dropElements list, sanitize from string function for empty dropElements list +PASS SanitizerAPI with config: test html without close tag with dropElements list ['div'], sanitize from string function for test html without close tag with dropElements list ['div'] +PASS SanitizerAPI with config: default behavior for custom elements, sanitize from string function for default behavior for custom elements +PASS SanitizerAPI with config: allow custom elements, sanitize from string function for allow custom elements +PASS SanitizerAPI with config: disallow custom elements, sanitize from string function for disallow custom elements +PASS SanitizerAPI with config: allow custom elements with drop list contains ["custom-element"], sanitize from string function for allow custom elements with drop list contains ["custom-element"] +PASS SanitizerAPI with config: test script with ["script"] as dropElements list, sanitize from string function for test script with ["script"] as dropElements list +PASS SanitizerAPI with config: dropElements list ["test-element", "i"]}, sanitize from string function for dropElements list ["test-element", "i"]} +PASS SanitizerAPI with config: dropElements list ["I", "DL"]}, sanitize from string function for dropElements list ["I", "DL"]} +PASS SanitizerAPI with config: dropElements list ["dl", "p"]}, sanitize from string function for dropElements list ["dl", "p"]} +PASS SanitizerAPI with config: dropElements list with invalid values, sanitize from string function for dropElements list with invalid values +PASS SanitizerAPI with config: blockElements list with invalid values, sanitize from string function for blockElements list with invalid values +PASS SanitizerAPI with config: allowElements list ["p"], sanitize from string function for allowElements list ["p"] +PASS SanitizerAPI with config: allowElements list ["p", "test"], sanitize from string function for allowElements list ["p", "test"] +PASS SanitizerAPI with config: allowElements list has no influence to dropElements, sanitize from string function for allowElements list has no influence to dropElements +PASS SanitizerAPI with config: dropAttributes list {"style": ["p"]} with style attribute, sanitize from string function for dropAttributes list {"style": ["p"]} with style attribute +PASS SanitizerAPI with config: dropAttributes list {"*": ["a"]} with style attribute, sanitize from string function for dropAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: empty dropAttributes list with id attribute, sanitize from string function for empty dropAttributes list with id attribute +PASS SanitizerAPI with config: dropAttributes list {"id": ["*"]} with id attribute, sanitize from string function for dropAttributes list {"id": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"ID": ["*"]} with id attribute, sanitize from string function for dropAttributes list {"ID": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access, sanitize from string function for dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access +PASS SanitizerAPI with config: allowAttributes list {"id": ["div"]} with id attribute, sanitize from string function for allowAttributes list {"id": ["div"]} with id attribute +PASS SanitizerAPI with config: allowAttributes list {"id": ["*"]} with id attribute and onclick scripts, sanitize from string function for allowAttributes list {"id": ["*"]} with id attribute and onclick scripts +PASS SanitizerAPI with config: allowAttributes list {"*": ["a"]} with style attribute, sanitize from string function for allowAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: allowAttributes list has no influence to dropAttributes, sanitize from string function for allowAttributes list has no influence to dropAttributes +PASS SanitizerAPI sanitize function shouldn't load the image. +PASS SanitizerAPI with config: string, sanitize from document function for string +PASS SanitizerAPI with config: html fragment, sanitize from document function for html fragment +PASS SanitizerAPI with config: broken html, sanitize from document function for broken html +PASS SanitizerAPI with config: empty object, sanitize from document function for empty object +PASS SanitizerAPI with config: number, sanitize from document function for number +PASS SanitizerAPI with config: zeros, sanitize from document function for zeros +PASS SanitizerAPI with config: arithmetic, sanitize from document function for arithmetic +PASS SanitizerAPI with config: empty string, sanitize from document function for empty string +PASS SanitizerAPI with config: undefined, sanitize from document function for undefined +PASS SanitizerAPI with config: document, sanitize from document function for document +PASS SanitizerAPI with config: html without close tag, sanitize from document function for html without close tag +PASS SanitizerAPI with config: scripts for default configs, sanitize from document function for scripts for default configs +PASS SanitizerAPI with config: onclick scripts, sanitize from document function for onclick scripts +PASS SanitizerAPI with config: plaintext, sanitize from document function for plaintext +PASS SanitizerAPI with config: xmp, sanitize from document function for xmp +PASS SanitizerAPI with config: malformed HTML, sanitize from document function for malformed HTML +PASS SanitizerAPI with config: invalid config_input, sanitize from document function for invalid config_input +PASS SanitizerAPI with config: empty dropElements list, sanitize from document function for empty dropElements list +PASS SanitizerAPI with config: test html without close tag with dropElements list ['div'], sanitize from document function for test html without close tag with dropElements list ['div'] +PASS SanitizerAPI with config: default behavior for custom elements, sanitize from document function for default behavior for custom elements +PASS SanitizerAPI with config: allow custom elements, sanitize from document function for allow custom elements +PASS SanitizerAPI with config: disallow custom elements, sanitize from document function for disallow custom elements +PASS SanitizerAPI with config: allow custom elements with drop list contains ["custom-element"], sanitize from document function for allow custom elements with drop list contains ["custom-element"] +PASS SanitizerAPI with config: test script with ["script"] as dropElements list, sanitize from document function for test script with ["script"] as dropElements list +PASS SanitizerAPI with config: dropElements list ["test-element", "i"]}, sanitize from document function for dropElements list ["test-element", "i"]} +PASS SanitizerAPI with config: dropElements list ["I", "DL"]}, sanitize from document function for dropElements list ["I", "DL"]} +PASS SanitizerAPI with config: dropElements list ["dl", "p"]}, sanitize from document function for dropElements list ["dl", "p"]} +PASS SanitizerAPI with config: dropElements list with invalid values, sanitize from document function for dropElements list with invalid values +PASS SanitizerAPI with config: blockElements list with invalid values, sanitize from document function for blockElements list with invalid values +PASS SanitizerAPI with config: allowElements list ["p"], sanitize from document function for allowElements list ["p"] +PASS SanitizerAPI with config: allowElements list ["p", "test"], sanitize from document function for allowElements list ["p", "test"] +PASS SanitizerAPI with config: allowElements list has no influence to dropElements, sanitize from document function for allowElements list has no influence to dropElements +PASS SanitizerAPI with config: dropAttributes list {"style": ["p"]} with style attribute, sanitize from document function for dropAttributes list {"style": ["p"]} with style attribute +PASS SanitizerAPI with config: dropAttributes list {"*": ["a"]} with style attribute, sanitize from document function for dropAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: empty dropAttributes list with id attribute, sanitize from document function for empty dropAttributes list with id attribute +PASS SanitizerAPI with config: dropAttributes list {"id": ["*"]} with id attribute, sanitize from document function for dropAttributes list {"id": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"ID": ["*"]} with id attribute, sanitize from document function for dropAttributes list {"ID": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access, sanitize from document function for dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access +PASS SanitizerAPI with config: allowAttributes list {"id": ["div"]} with id attribute, sanitize from document function for allowAttributes list {"id": ["div"]} with id attribute +PASS SanitizerAPI with config: allowAttributes list {"id": ["*"]} with id attribute and onclick scripts, sanitize from document function for allowAttributes list {"id": ["*"]} with id attribute and onclick scripts +PASS SanitizerAPI with config: allowAttributes list {"*": ["a"]} with style attribute, sanitize from document function for allowAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: allowAttributes list has no influence to dropAttributes, sanitize from document function for allowAttributes list has no influence to dropAttributes +PASS SanitizerAPI with config: string, sanitize from document fragment function for string +PASS SanitizerAPI with config: html fragment, sanitize from document fragment function for html fragment +PASS SanitizerAPI with config: broken html, sanitize from document fragment function for broken html +PASS SanitizerAPI with config: empty object, sanitize from document fragment function for empty object +PASS SanitizerAPI with config: number, sanitize from document fragment function for number +PASS SanitizerAPI with config: zeros, sanitize from document fragment function for zeros +PASS SanitizerAPI with config: arithmetic, sanitize from document fragment function for arithmetic +PASS SanitizerAPI with config: empty string, sanitize from document fragment function for empty string +PASS SanitizerAPI with config: undefined, sanitize from document fragment function for undefined +PASS SanitizerAPI with config: document, sanitize from document fragment function for document +PASS SanitizerAPI with config: html without close tag, sanitize from document fragment function for html without close tag +PASS SanitizerAPI with config: scripts for default configs, sanitize from document fragment function for scripts for default configs +PASS SanitizerAPI with config: onclick scripts, sanitize from document fragment function for onclick scripts +PASS SanitizerAPI with config: plaintext, sanitize from document fragment function for plaintext +PASS SanitizerAPI with config: xmp, sanitize from document fragment function for xmp +FAIL SanitizerAPI with config: malformed HTML, sanitize from document fragment function for malformed HTML assert_equals: expected "<p>Some text</p><p>Some more text</p>" but got "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>" +PASS SanitizerAPI with config: invalid config_input, sanitize from document fragment function for invalid config_input +PASS SanitizerAPI with config: empty dropElements list, sanitize from document fragment function for empty dropElements list +PASS SanitizerAPI with config: test html without close tag with dropElements list ['div'], sanitize from document fragment function for test html without close tag with dropElements list ['div'] +PASS SanitizerAPI with config: default behavior for custom elements, sanitize from document fragment function for default behavior for custom elements +PASS SanitizerAPI with config: allow custom elements, sanitize from document fragment function for allow custom elements +PASS SanitizerAPI with config: disallow custom elements, sanitize from document fragment function for disallow custom elements +PASS SanitizerAPI with config: allow custom elements with drop list contains ["custom-element"], sanitize from document fragment function for allow custom elements with drop list contains ["custom-element"] +PASS SanitizerAPI with config: test script with ["script"] as dropElements list, sanitize from document fragment function for test script with ["script"] as dropElements list +PASS SanitizerAPI with config: dropElements list ["test-element", "i"]}, sanitize from document fragment function for dropElements list ["test-element", "i"]} +PASS SanitizerAPI with config: dropElements list ["I", "DL"]}, sanitize from document fragment function for dropElements list ["I", "DL"]} +PASS SanitizerAPI with config: dropElements list ["dl", "p"]}, sanitize from document fragment function for dropElements list ["dl", "p"]} +PASS SanitizerAPI with config: dropElements list with invalid values, sanitize from document fragment function for dropElements list with invalid values +PASS SanitizerAPI with config: blockElements list with invalid values, sanitize from document fragment function for blockElements list with invalid values +PASS SanitizerAPI with config: allowElements list ["p"], sanitize from document fragment function for allowElements list ["p"] +PASS SanitizerAPI with config: allowElements list ["p", "test"], sanitize from document fragment function for allowElements list ["p", "test"] +PASS SanitizerAPI with config: allowElements list has no influence to dropElements, sanitize from document fragment function for allowElements list has no influence to dropElements +PASS SanitizerAPI with config: dropAttributes list {"style": ["p"]} with style attribute, sanitize from document fragment function for dropAttributes list {"style": ["p"]} with style attribute +PASS SanitizerAPI with config: dropAttributes list {"*": ["a"]} with style attribute, sanitize from document fragment function for dropAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: empty dropAttributes list with id attribute, sanitize from document fragment function for empty dropAttributes list with id attribute +PASS SanitizerAPI with config: dropAttributes list {"id": ["*"]} with id attribute, sanitize from document fragment function for dropAttributes list {"id": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"ID": ["*"]} with id attribute, sanitize from document fragment function for dropAttributes list {"ID": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access, sanitize from document fragment function for dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access +PASS SanitizerAPI with config: allowAttributes list {"id": ["div"]} with id attribute, sanitize from document fragment function for allowAttributes list {"id": ["div"]} with id attribute +PASS SanitizerAPI with config: allowAttributes list {"id": ["*"]} with id attribute and onclick scripts, sanitize from document fragment function for allowAttributes list {"id": ["*"]} with id attribute and onclick scripts +PASS SanitizerAPI with config: allowAttributes list {"*": ["a"]} with style attribute, sanitize from document fragment function for allowAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: allowAttributes list has no influence to dropAttributes, sanitize from document fragment function for allowAttributes list has no influence to dropAttributes +PASS SanitizerAPI sanitize from TrustedHTML. +PASS SanitizerAPI sanitize from string with default policy. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative.html index d540e25..20c2075 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative.html +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.tentative.html
@@ -33,22 +33,23 @@ assert_equals(getString(fragment), c.result); }, "SanitizerAPI with config: " + c.message + ", sanitize from string function for " + c.message)); + async_test(t => { + let s = new Sanitizer(); + fragment = s.sanitize("<img src='http://bla/'>"); + t.step_timeout(_ => { + assert_equals(performance.getEntriesByName("http://bla/").length, 0); + t.done(); + }, 1000); + }, "SanitizerAPI sanitize function shouldn't load the image."); + testcases.forEach(c => test(t => { let s = new Sanitizer(c.config_input); - var dom = document.implementation.createHTMLDocument(); - dom.documentElement.innerHTML = c.value; + var dom = new DOMParser().parseFromString("<!DOCTYPE html><body>" + c.value, "text/html"); fragment = s.sanitize(dom); assert_true(fragment instanceof DocumentFragment); let result = getString(fragment); - // Remove <html> and </html> - if (c.message != "document" && result.slice(0,12) == "<html><body>" && result.slice(result.length-14, result.length) == "</body></html>") - result = result.substr(12, result.length - 26); - if (c.message == "document") { - assert_equals(result, "<html><body>test</body></html>"); - } else { - assert_equals(result, c.result); - } + assert_equals(result, c.result); }, "SanitizerAPI with config: " + c.message + ", sanitize from document function for " + c.message)); testcases.forEach(c => test(t => {
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative-expected.txt b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative-expected.txt new file mode 100644 index 0000000..f977b82 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative-expected.txt
@@ -0,0 +1,132 @@ +This is a testharness.js-based test. +Found 128 tests; 127 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS SanitizerAPI sanitize function without argument should throw an error. +PASS SanitizerAPI sanitizeToString function for null. +PASS SanitizerAPI config: string, sanitizeToString from string function for string +PASS SanitizerAPI config: html fragment, sanitizeToString from string function for html fragment +PASS SanitizerAPI config: broken html, sanitizeToString from string function for broken html +PASS SanitizerAPI config: empty object, sanitizeToString from string function for empty object +PASS SanitizerAPI config: number, sanitizeToString from string function for number +PASS SanitizerAPI config: zeros, sanitizeToString from string function for zeros +PASS SanitizerAPI config: arithmetic, sanitizeToString from string function for arithmetic +PASS SanitizerAPI config: empty string, sanitizeToString from string function for empty string +PASS SanitizerAPI config: undefined, sanitizeToString from string function for undefined +PASS SanitizerAPI config: document, sanitizeToString from string function for document +PASS SanitizerAPI config: html without close tag, sanitizeToString from string function for html without close tag +PASS SanitizerAPI config: scripts for default configs, sanitizeToString from string function for scripts for default configs +PASS SanitizerAPI config: onclick scripts, sanitizeToString from string function for onclick scripts +PASS SanitizerAPI config: plaintext, sanitizeToString from string function for plaintext +PASS SanitizerAPI config: xmp, sanitizeToString from string function for xmp +PASS SanitizerAPI config: malformed HTML, sanitizeToString from string function for malformed HTML +PASS SanitizerAPI config: invalid config_input, sanitizeToString from string function for invalid config_input +PASS SanitizerAPI config: empty dropElements list, sanitizeToString from string function for empty dropElements list +PASS SanitizerAPI config: test html without close tag with dropElements list ['div'], sanitizeToString from string function for test html without close tag with dropElements list ['div'] +PASS SanitizerAPI config: default behavior for custom elements, sanitizeToString from string function for default behavior for custom elements +PASS SanitizerAPI config: allow custom elements, sanitizeToString from string function for allow custom elements +PASS SanitizerAPI config: disallow custom elements, sanitizeToString from string function for disallow custom elements +PASS SanitizerAPI config: allow custom elements with drop list contains ["custom-element"], sanitizeToString from string function for allow custom elements with drop list contains ["custom-element"] +PASS SanitizerAPI config: test script with ["script"] as dropElements list, sanitizeToString from string function for test script with ["script"] as dropElements list +PASS SanitizerAPI config: dropElements list ["test-element", "i"]}, sanitizeToString from string function for dropElements list ["test-element", "i"]} +PASS SanitizerAPI config: dropElements list ["I", "DL"]}, sanitizeToString from string function for dropElements list ["I", "DL"]} +PASS SanitizerAPI config: dropElements list ["dl", "p"]}, sanitizeToString from string function for dropElements list ["dl", "p"]} +PASS SanitizerAPI config: dropElements list with invalid values, sanitizeToString from string function for dropElements list with invalid values +PASS SanitizerAPI config: blockElements list with invalid values, sanitizeToString from string function for blockElements list with invalid values +PASS SanitizerAPI config: allowElements list ["p"], sanitizeToString from string function for allowElements list ["p"] +PASS SanitizerAPI config: allowElements list ["p", "test"], sanitizeToString from string function for allowElements list ["p", "test"] +PASS SanitizerAPI config: allowElements list has no influence to dropElements, sanitizeToString from string function for allowElements list has no influence to dropElements +PASS SanitizerAPI config: dropAttributes list {"style": ["p"]} with style attribute, sanitizeToString from string function for dropAttributes list {"style": ["p"]} with style attribute +PASS SanitizerAPI config: dropAttributes list {"*": ["a"]} with style attribute, sanitizeToString from string function for dropAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI config: empty dropAttributes list with id attribute, sanitizeToString from string function for empty dropAttributes list with id attribute +PASS SanitizerAPI config: dropAttributes list {"id": ["*"]} with id attribute, sanitizeToString from string function for dropAttributes list {"id": ["*"]} with id attribute +PASS SanitizerAPI config: dropAttributes list {"ID": ["*"]} with id attribute, sanitizeToString from string function for dropAttributes list {"ID": ["*"]} with id attribute +PASS SanitizerAPI config: dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access, sanitizeToString from string function for dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access +PASS SanitizerAPI config: allowAttributes list {"id": ["div"]} with id attribute, sanitizeToString from string function for allowAttributes list {"id": ["div"]} with id attribute +PASS SanitizerAPI config: allowAttributes list {"id": ["*"]} with id attribute and onclick scripts, sanitizeToString from string function for allowAttributes list {"id": ["*"]} with id attribute and onclick scripts +PASS SanitizerAPI config: allowAttributes list {"*": ["a"]} with style attribute, sanitizeToString from string function for allowAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI config: allowAttributes list has no influence to dropAttributes, sanitizeToString from string function for allowAttributes list has no influence to dropAttributes +PASS SanitizerAPI with config: string, sanitizeToString from document function for string +PASS SanitizerAPI with config: html fragment, sanitizeToString from document function for html fragment +PASS SanitizerAPI with config: broken html, sanitizeToString from document function for broken html +PASS SanitizerAPI with config: empty object, sanitizeToString from document function for empty object +PASS SanitizerAPI with config: number, sanitizeToString from document function for number +PASS SanitizerAPI with config: zeros, sanitizeToString from document function for zeros +PASS SanitizerAPI with config: arithmetic, sanitizeToString from document function for arithmetic +PASS SanitizerAPI with config: empty string, sanitizeToString from document function for empty string +PASS SanitizerAPI with config: undefined, sanitizeToString from document function for undefined +PASS SanitizerAPI with config: document, sanitizeToString from document function for document +PASS SanitizerAPI with config: html without close tag, sanitizeToString from document function for html without close tag +PASS SanitizerAPI with config: scripts for default configs, sanitizeToString from document function for scripts for default configs +PASS SanitizerAPI with config: onclick scripts, sanitizeToString from document function for onclick scripts +PASS SanitizerAPI with config: plaintext, sanitizeToString from document function for plaintext +PASS SanitizerAPI with config: xmp, sanitizeToString from document function for xmp +PASS SanitizerAPI with config: malformed HTML, sanitizeToString from document function for malformed HTML +PASS SanitizerAPI with config: invalid config_input, sanitizeToString from document function for invalid config_input +PASS SanitizerAPI with config: empty dropElements list, sanitizeToString from document function for empty dropElements list +PASS SanitizerAPI with config: test html without close tag with dropElements list ['div'], sanitizeToString from document function for test html without close tag with dropElements list ['div'] +PASS SanitizerAPI with config: default behavior for custom elements, sanitizeToString from document function for default behavior for custom elements +PASS SanitizerAPI with config: allow custom elements, sanitizeToString from document function for allow custom elements +PASS SanitizerAPI with config: disallow custom elements, sanitizeToString from document function for disallow custom elements +PASS SanitizerAPI with config: allow custom elements with drop list contains ["custom-element"], sanitizeToString from document function for allow custom elements with drop list contains ["custom-element"] +PASS SanitizerAPI with config: test script with ["script"] as dropElements list, sanitizeToString from document function for test script with ["script"] as dropElements list +PASS SanitizerAPI with config: dropElements list ["test-element", "i"]}, sanitizeToString from document function for dropElements list ["test-element", "i"]} +PASS SanitizerAPI with config: dropElements list ["I", "DL"]}, sanitizeToString from document function for dropElements list ["I", "DL"]} +PASS SanitizerAPI with config: dropElements list ["dl", "p"]}, sanitizeToString from document function for dropElements list ["dl", "p"]} +PASS SanitizerAPI with config: dropElements list with invalid values, sanitizeToString from document function for dropElements list with invalid values +PASS SanitizerAPI with config: blockElements list with invalid values, sanitizeToString from document function for blockElements list with invalid values +PASS SanitizerAPI with config: allowElements list ["p"], sanitizeToString from document function for allowElements list ["p"] +PASS SanitizerAPI with config: allowElements list ["p", "test"], sanitizeToString from document function for allowElements list ["p", "test"] +PASS SanitizerAPI with config: allowElements list has no influence to dropElements, sanitizeToString from document function for allowElements list has no influence to dropElements +PASS SanitizerAPI with config: dropAttributes list {"style": ["p"]} with style attribute, sanitizeToString from document function for dropAttributes list {"style": ["p"]} with style attribute +PASS SanitizerAPI with config: dropAttributes list {"*": ["a"]} with style attribute, sanitizeToString from document function for dropAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: empty dropAttributes list with id attribute, sanitizeToString from document function for empty dropAttributes list with id attribute +PASS SanitizerAPI with config: dropAttributes list {"id": ["*"]} with id attribute, sanitizeToString from document function for dropAttributes list {"id": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"ID": ["*"]} with id attribute, sanitizeToString from document function for dropAttributes list {"ID": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access, sanitizeToString from document function for dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access +PASS SanitizerAPI with config: allowAttributes list {"id": ["div"]} with id attribute, sanitizeToString from document function for allowAttributes list {"id": ["div"]} with id attribute +PASS SanitizerAPI with config: allowAttributes list {"id": ["*"]} with id attribute and onclick scripts, sanitizeToString from document function for allowAttributes list {"id": ["*"]} with id attribute and onclick scripts +PASS SanitizerAPI with config: allowAttributes list {"*": ["a"]} with style attribute, sanitizeToString from document function for allowAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: allowAttributes list has no influence to dropAttributes, sanitizeToString from document function for allowAttributes list has no influence to dropAttributes +PASS SanitizerAPI with config: string, sanitizeToString from document fragment function for string +PASS SanitizerAPI with config: html fragment, sanitizeToString from document fragment function for html fragment +PASS SanitizerAPI with config: broken html, sanitizeToString from document fragment function for broken html +PASS SanitizerAPI with config: empty object, sanitizeToString from document fragment function for empty object +PASS SanitizerAPI with config: number, sanitizeToString from document fragment function for number +PASS SanitizerAPI with config: zeros, sanitizeToString from document fragment function for zeros +PASS SanitizerAPI with config: arithmetic, sanitizeToString from document fragment function for arithmetic +PASS SanitizerAPI with config: empty string, sanitizeToString from document fragment function for empty string +PASS SanitizerAPI with config: undefined, sanitizeToString from document fragment function for undefined +PASS SanitizerAPI with config: document, sanitizeToString from document fragment function for document +PASS SanitizerAPI with config: html without close tag, sanitizeToString from document fragment function for html without close tag +PASS SanitizerAPI with config: scripts for default configs, sanitizeToString from document fragment function for scripts for default configs +PASS SanitizerAPI with config: onclick scripts, sanitizeToString from document fragment function for onclick scripts +PASS SanitizerAPI with config: plaintext, sanitizeToString from document fragment function for plaintext +PASS SanitizerAPI with config: xmp, sanitizeToString from document fragment function for xmp +FAIL SanitizerAPI with config: malformed HTML, sanitizeToString from document fragment function for malformed HTML assert_equals: expected "<p>Some text</p><p>Some more text</p>" but got "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>" +PASS SanitizerAPI with config: invalid config_input, sanitizeToString from document fragment function for invalid config_input +PASS SanitizerAPI with config: empty dropElements list, sanitizeToString from document fragment function for empty dropElements list +PASS SanitizerAPI with config: test html without close tag with dropElements list ['div'], sanitizeToString from document fragment function for test html without close tag with dropElements list ['div'] +PASS SanitizerAPI with config: default behavior for custom elements, sanitizeToString from document fragment function for default behavior for custom elements +PASS SanitizerAPI with config: allow custom elements, sanitizeToString from document fragment function for allow custom elements +PASS SanitizerAPI with config: disallow custom elements, sanitizeToString from document fragment function for disallow custom elements +PASS SanitizerAPI with config: allow custom elements with drop list contains ["custom-element"], sanitizeToString from document fragment function for allow custom elements with drop list contains ["custom-element"] +PASS SanitizerAPI with config: test script with ["script"] as dropElements list, sanitizeToString from document fragment function for test script with ["script"] as dropElements list +PASS SanitizerAPI with config: dropElements list ["test-element", "i"]}, sanitizeToString from document fragment function for dropElements list ["test-element", "i"]} +PASS SanitizerAPI with config: dropElements list ["I", "DL"]}, sanitizeToString from document fragment function for dropElements list ["I", "DL"]} +PASS SanitizerAPI with config: dropElements list ["dl", "p"]}, sanitizeToString from document fragment function for dropElements list ["dl", "p"]} +PASS SanitizerAPI with config: dropElements list with invalid values, sanitizeToString from document fragment function for dropElements list with invalid values +PASS SanitizerAPI with config: blockElements list with invalid values, sanitizeToString from document fragment function for blockElements list with invalid values +PASS SanitizerAPI with config: allowElements list ["p"], sanitizeToString from document fragment function for allowElements list ["p"] +PASS SanitizerAPI with config: allowElements list ["p", "test"], sanitizeToString from document fragment function for allowElements list ["p", "test"] +PASS SanitizerAPI with config: allowElements list has no influence to dropElements, sanitizeToString from document fragment function for allowElements list has no influence to dropElements +PASS SanitizerAPI with config: dropAttributes list {"style": ["p"]} with style attribute, sanitizeToString from document fragment function for dropAttributes list {"style": ["p"]} with style attribute +PASS SanitizerAPI with config: dropAttributes list {"*": ["a"]} with style attribute, sanitizeToString from document fragment function for dropAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: empty dropAttributes list with id attribute, sanitizeToString from document fragment function for empty dropAttributes list with id attribute +PASS SanitizerAPI with config: dropAttributes list {"id": ["*"]} with id attribute, sanitizeToString from document fragment function for dropAttributes list {"id": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"ID": ["*"]} with id attribute, sanitizeToString from document fragment function for dropAttributes list {"ID": ["*"]} with id attribute +PASS SanitizerAPI with config: dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access, sanitizeToString from document fragment function for dropAttributes list {"data-attribute-with-dashes": ["*"]} with dom dataset js access +PASS SanitizerAPI with config: allowAttributes list {"id": ["div"]} with id attribute, sanitizeToString from document fragment function for allowAttributes list {"id": ["div"]} with id attribute +PASS SanitizerAPI with config: allowAttributes list {"id": ["*"]} with id attribute and onclick scripts, sanitizeToString from document fragment function for allowAttributes list {"id": ["*"]} with id attribute and onclick scripts +PASS SanitizerAPI with config: allowAttributes list {"*": ["a"]} with style attribute, sanitizeToString from document fragment function for allowAttributes list {"*": ["a"]} with style attribute +PASS SanitizerAPI with config: allowAttributes list has no influence to dropAttributes, sanitizeToString from document fragment function for allowAttributes list has no influence to dropAttributes +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative.html index 78d8d994..f76560d4 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative.html +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeToString.tentative.html
@@ -26,17 +26,10 @@ testcases.forEach(c => test(t => { let s = new Sanitizer(c.config_input); - var dom = document.implementation.createHTMLDocument(); - dom.documentElement.innerHTML = c.value; + var dom = new DOMParser().parseFromString("<!DOCTYPE html><body>" + c.value, "text/html"); let result = s.sanitizeToString(dom); - // Remove <html> and </html> - if (c.message != "document" && result.slice(0,12) == "<html><body>" && result.slice(result.length-14, result.length) == "</body></html>") - result = result.substr(12, result.length - 26); - if (c.message == "document") { - assert_equals(result, "<html><body>test</body></html>"); - } else { - assert_equals(result, c.result); - } + + assert_equals(result, c.result); }, "SanitizerAPI with config: " + c.message + ", sanitizeToString from document function for " + c.message)); testcases.forEach(c => test(t => {
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js b/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js index 5315cf3a..806560e78 100644 --- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js +++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/support/testcases.sub.js
@@ -12,24 +12,31 @@ {config_input: {}, value: "<div>test", result: "<div>test</div>", message: "html without close tag"}, {config_input: {}, value: "<script>alert('i am a test')<\/script>", result: "", message: "scripts for default configs"}, {config_input: {}, value: "<p onclick='a= 123'>Click.</p>", result: "<p>Click.</p>", message: "onclick scripts"}, + {config_input: {}, value: "<plaintext><p>text</p>", result: "", message: "plaintext"}, + {config_input: {}, value: "<xmp>TEXT</xmp>", result: "", message: "xmp"}, + {config_input: {}, value: "<p>Some text</p></body><!-- 1 --></html><!-- 2 --><p>Some more text</p>", result: "<p>Some text</p><p>Some more text</p>", message: "malformed HTML"}, {config_input: {test: 123}, value: "test", result: "test", message: "invalid config_input"}, {config_input: {dropElements: []}, value: "test", result: "test", message: "empty dropElements list"}, - {config_input: {dropElements: ["div"]}, value: "<div>test</div><c>bla", result: "<c>bla</c>", message: "test html without close tag with dropElements list ['div']"}, - {config_input: {dropElements: ["customElement"]}, value: "<customElement>test</customElement>bla", result: "bla", message: "test custom element with dropElements list ['div']"}, + {config_input: {dropElements: ["div"]}, value: "<div>test</div><p>bla", result: "<p>bla</p>", message: "test html without close tag with dropElements list ['div']"}, + {config_input: {}, value: "<custom-element>test</custom-element>bla", result: "bla", message: "default behavior for custom elements"}, + {config_input: {allowCustomElements: true}, value: "<custom-element>test</custom-element>bla", result: "<custom-element>test</custom-element>bla", message: "allow custom elements"}, + {config_input: {allowCustomElements: false}, value: "<custom-element>test</custom-element>bla", result: "bla", message: "disallow custom elements"}, + {config_input: {dropElements: ["custom-element"], allowCustomElements: true}, value: "<custom-element>test</custom-element>bla", result: "bla", message: "allow custom elements with drop list contains [\"custom-element\"]"}, {config_input: {dropElements: ["script"]}, value: "<script>alert('i am a test')<\/script>", result: "", message: "test script with [\"script\"] as dropElements list"}, - {config_input: {dropElements: ["test", "i"]}, value: "<div>balabala<i>test</i></div><test>t</test>", result: "<div>balabala</div>", message: "dropElements list [\"test\", \"i\"]}"}, - {config_input: {dropElements: ["I", "AM"]}, value: "<div>balabala<am>test</am></div>", result: "<div>balabala</div>", message: "dropElements list [\"I\", \"AM\"]}"}, - {config_input: {dropElements: ["am", "p"]}, value: "<div>balabala<i>i</i><p>t</p><test>a</test></div>", result: "<div>balabala<i>i</i><test>a</test></div>", message: "dropElements list [\"am\", \"p\"]}"}, - {config_input: {dropElements: [123, [], "test", "i"]}, value: "<div>balabala<i>test</i></div><test>t</test>", result: "<div>balabala</div>", message: "dropElements list with invalid values}"}, - {config_input: {blockElements: [123, [], "test", "i"]}, value: "<div>balabala<i>test</i></div><test>t</test>", result: "<div>balabalatest</div>t", message: "blockElements list with invalid values}"}, - {config_input: {allowElements: ["p"]}, value: "<div>test<div>p</div>tt<p>div</p></div>", result: "testptt<p>div</p>", message: "allowElements list [\"p\"]."}, - {config_input: {dropElements: ["div"], allowElements: ["div"]}, value: "<div>test</div><c>bla", result: "bla", message: "allowElements list has no influence to dropElements."}, + {config_input: {dropElements: ["test-element", "i"]}, value: "<div>balabala<i>test</i></div><test-element>t</test-element>", result: "<div>balabala</div>", message: "dropElements list [\"test-element\", \"i\"]}"}, + {config_input: {dropElements: ["I", "DL"]}, value: "<div>balabala<dl>test</dl></div>", result: "<div>balabala</div>", message: "dropElements list [\"I\", \"DL\"]}"}, + {config_input: {dropElements: ["dl", "p"]}, value: "<div>balabala<i>i</i><p>t</p></div>", result: "<div>balabala<i>i</i></div>", message: "dropElements list [\"dl\", \"p\"]}"}, + {config_input: {dropElements: [123, [], "test", "i", "custom-element"]}, value: "<div>balabala<i>test</i></div><test>t</test><custom-element>custom-element</custom-element>", result: "<div>balabala</div>", message: "dropElements list with invalid values"}, + {config_input: {blockElements: [123, [], "test", "i", "custom-element"]}, value: "<div>balabala<i>test</i></div><test>t</test><custom-element>custom-element</custom-element>", result: "<div>balabalatest</div>t", message: "blockElements list with invalid values"}, + {config_input: {allowElements: ["p"]}, value: "<div>test<div>p</div>tt<p>div</p></div>", result: "testptt<p>div</p>", message: "allowElements list [\"p\"]"}, + {config_input: {allowElements: ["p", "test"]}, value: "<div>test<div>p</div>tt<p>div</p><test>test</test></div>", result: "testptt<p>div</p><test>test</test>", message: "allowElements list [\"p\", \"test\"]"}, + {config_input: {dropElements: ["div"], allowElements: ["div"]}, value: "<div>test</div><p>bla", result: "bla", message: "allowElements list has no influence to dropElements"}, {config_input: {dropAttributes: {"style": ["p"]}}, value: "<p style='color: black'>Click.</p><div style='color: white'>div</div>", result: "<p>Click.</p><div style=\"color: white\">div</div>", message: "dropAttributes list {\"style\": [\"p\"]} with style attribute"}, {config_input: {dropAttributes: {"*": ["a"]}}, value: "<a id='a' style='color: black'>Click.</a><div style='color: white'>div</div>", result: "<a>Click.</a><div style=\"color: white\">div</div>", message: "dropAttributes list {\"*\": [\"a\"]} with style attribute"}, {config_input: {dropAttributes: {}}, value: "<p id='test'>Click.</p>", result: "<p id=\"test\">Click.</p>", message: "empty dropAttributes list with id attribute"}, {config_input: {dropAttributes: {"id": ["*"]}}, value: "<p id='test'>Click.</p>", result: "<p>Click.</p>", message: "dropAttributes list {\"id\": [\"*\"]} with id attribute"}, {config_input: {dropAttributes: {"ID": ["*"]}}, value: "<p id='test'>Click.</p>", result: "<p>Click.</p>", message: "dropAttributes list {\"ID\": [\"*\"]} with id attribute"}, - {config_input: {dropAttributes: {"data-attribute-with-dashes": ["*"]}}, value: "<p id='p' data-attribute-with-dashes='123'>Click.</p><script>document.getElementById('p').dataset.attributeWithDashes=123;</script>", result: "<p id=\"p\">Click.</p>", message: "dropAttributes list {\"data-attribute-with-dashes\": [\"*\"]} with dom dataset js access."}, + {config_input: {dropAttributes: {"data-attribute-with-dashes": ["*"]}}, value: "<p id='p' data-attribute-with-dashes='123'>Click.</p><script>document.getElementById('p').dataset.attributeWithDashes=123;</script>", result: "<p id=\"p\">Click.</p>", message: "dropAttributes list {\"data-attribute-with-dashes\": [\"*\"]} with dom dataset js access"}, {config_input: {allowAttributes: {"id": ["div"]}}, value: "<p id='p'>P</p><div id='div'>DIV</div>", result: "<p>P</p><div id=\"div\">DIV</div>", message: "allowAttributes list {\"id\": [\"div\"]} with id attribute"}, {config_input: {allowAttributes: {"id": ["*"]}}, value: "<p id='test' onclick='a= 123'>Click.</p>", result: "<p id=\"test\">Click.</p>", message: "allowAttributes list {\"id\": [\"*\"]} with id attribute and onclick scripts"}, {config_input: {allowAttributes: {"*": ["a"]}}, value: "<a id='a' style='color: black'>Click.</a><div style='color: white'>div</div>", result: "<a id=\"a\" style=\"color: black\">Click.</a><div>div</div>", message: "allowAttributes list {\"*\": [\"a\"]} with style attribute"},
diff --git a/third_party/blink/web_tests/wpt_internal/storage/buckets/idlharness-worker.https.any.js b/third_party/blink/web_tests/wpt_internal/storage/buckets/idlharness-worker.https.any.js new file mode 100644 index 0000000..97fbe9aa --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/storage/buckets/idlharness-worker.https.any.js
@@ -0,0 +1,22 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +idl_test( + ['storage-buckets.tentative'], + ['html'], + async (idl_array, t) => { + idl_array.add_objects({ + BucketManager: ['navigator.storageBuckets'], + StorageBucket: [] + }); + + if (self.Window) { + idl_array.add_objects({ Navigator: ['navigator'] }); + } else { + idl_array.add_objects({ WorkerNavigator: ['navigator'] }); + } + } +);
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn index 5df448e9..59898f97 100644 --- a/third_party/harfbuzz-ng/BUILD.gn +++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -28,9 +28,15 @@ } config("harfbuzz_warnings") { + cflags = [] if (is_win) { # Result of 32-bit shift implicitly converted to 64 bits. - cflags = [ "/wd4334" ] + cflags += [ "/wd4334" ] + } + + if (is_clang) { + # Has a false positive in hb-icu.cc, see crbug.com/1174192#c5 + cflags += [ "-Wno-array-bounds" ] } }
diff --git a/third_party/libaom/cmake_update.sh b/third_party/libaom/cmake_update.sh index 7490a01..6f850e6 100755 --- a/third_party/libaom/cmake_update.sh +++ b/third_party/libaom/cmake_update.sh
@@ -133,6 +133,7 @@ all_platforms+=" -DCONFIG_AV1_HIGHBITDEPTH=0" # Use real-time only build. all_platforms+=" -DCONFIG_REALTIME_ONLY=1" +all_platforms+=" -DCONFIG_AV1_TEMPORAL_DENOISING=1" # avx2 optimizations account for ~0.3mb of the decoder. #all_platforms+=" -DENABLE_AVX2=0" toolchain="-DCMAKE_TOOLCHAIN_FILE=${SRC}/build/cmake/toolchains"
diff --git a/third_party/libaom/libaom_srcs.gni b/third_party/libaom/libaom_srcs.gni index 99922bd..e1c93a30 100644 --- a/third_party/libaom/libaom_srcs.gni +++ b/third_party/libaom/libaom_srcs.gni
@@ -203,6 +203,7 @@ "//third_party/libaom/source/libaom/av1/encoder/arm/neon/hybrid_fwd_txfm_neon.c", "//third_party/libaom/source/libaom/av1/encoder/arm/neon/av1_fwd_txfm2d_neon.c", "//third_party/libaom/source/libaom/av1/encoder/arm/neon/highbd_fwd_txfm_neon.c", + "//third_party/libaom/source/libaom/av1/encoder/arm/neon/av1_temporal_denoiser_neon.c", ] aom_av1_encoder_intrin_sse2 = [ @@ -212,6 +213,7 @@ "//third_party/libaom/source/libaom/av1/encoder/x86/encodetxb_sse2.c", "//third_party/libaom/source/libaom/av1/encoder/x86/temporal_filter_sse2.c", "//third_party/libaom/source/libaom/av1/encoder/x86/wedge_utils_sse2.c", + "//third_party/libaom/source/libaom/av1/encoder/x86/av1_temporal_denoiser_sse2.c", ] aom_av1_encoder_intrin_sse3 = @@ -246,6 +248,8 @@ "//third_party/libaom/source/libaom/av1/encoder/av1_noise_estimate.h", "//third_party/libaom/source/libaom/av1/encoder/av1_quantize.c", "//third_party/libaom/source/libaom/av1/encoder/av1_quantize.h", + "//third_party/libaom/source/libaom/av1/encoder/av1_temporal_denoiser.c", + "//third_party/libaom/source/libaom/av1/encoder/av1_temporal_denoiser.h", "//third_party/libaom/source/libaom/av1/encoder/bitstream.c", "//third_party/libaom/source/libaom/av1/encoder/bitstream.h", "//third_party/libaom/source/libaom/av1/encoder/block.h",
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm index a6811f5..8d04b4a 100644 --- a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm +++ b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.c b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.c index 03c5cc2..b1084c5 100644 --- a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.c +++ b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-ios.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-ios.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h index e0e191d..1424475 100644 --- a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h +++ b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h b/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h index c07b2fb..5ac080b 100644 --- a/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h +++ b/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h
@@ -289,6 +289,26 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_neon +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_neon(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_neon + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/ios/arm64/config/aom_config.asm b/third_party/libaom/source/config/ios/arm64/config/aom_config.asm index a6811f5..8d04b4a 100644 --- a/third_party/libaom/source/config/ios/arm64/config/aom_config.asm +++ b/third_party/libaom/source/config/ios/arm64/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/ios/arm64/config/aom_config.c b/third_party/libaom/source/config/ios/arm64/config/aom_config.c index 1f325ae..cd0a632 100644 --- a/third_party/libaom/source/config/ios/arm64/config/aom_config.c +++ b/third_party/libaom/source/config/ios/arm64/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-ios.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-ios.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/ios/arm64/config/aom_config.h b/third_party/libaom/source/config/ios/arm64/config/aom_config.h index e0e191d..1424475 100644 --- a/third_party/libaom/source/config/ios/arm64/config/aom_config.h +++ b/third_party/libaom/source/config/ios/arm64/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h index c07b2fb..5ac080b 100644 --- a/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h +++ b/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h
@@ -289,6 +289,26 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_neon +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_neon(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_neon + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm index 5d2c2a8..7d7821c 100644 --- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.c b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.c index a796dee..c20c00b 100644 --- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.c +++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h index 9d110c6..2feb2f8 100644 --- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h +++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h index 649f86d..bf31686 100644 --- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
@@ -343,6 +343,34 @@ const InterpFilterParams* filter_params_y, const int subpel_y_qn); +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_neon(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +RTCD_EXTERN int (*av1_denoiser_filter)(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst, @@ -1871,6 +1899,9 @@ av1_convolve_y_sr = av1_convolve_y_sr_c; if (flags & HAS_NEON) av1_convolve_y_sr = av1_convolve_y_sr_neon; + av1_denoiser_filter = av1_denoiser_filter_c; + if (flags & HAS_NEON) + av1_denoiser_filter = av1_denoiser_filter_neon; av1_dist_wtd_convolve_2d = av1_dist_wtd_convolve_2d_c; if (flags & HAS_NEON) av1_dist_wtd_convolve_2d = av1_dist_wtd_convolve_2d_neon;
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm index a6811f5..8d04b4a 100644 --- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.c b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.c index a796dee..c20c00b 100644 --- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.c +++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h index e0e191d..1424475 100644 --- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h +++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h index c07b2fb..5ac080b 100644 --- a/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
@@ -289,6 +289,26 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_neon +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_neon(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_neon + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.asm b/third_party/libaom/source/config/linux/arm/config/aom_config.asm index fb3b6bd1..cb30733e 100644 --- a/third_party/libaom/source/config/linux/arm/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/arm/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.c b/third_party/libaom/source/config/linux/arm/config/aom_config.c index 2542180b..c6697d95 100644 --- a/third_party/libaom/source/config/linux/arm/config/aom_config.c +++ b/third_party/libaom/source/config/linux/arm/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384 -DENABLE_NEON=0"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/armv7-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384 -DENABLE_NEON=0"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.h b/third_party/libaom/source/config/linux/arm/config/aom_config.h index a742639..fbe8084 100644 --- a/third_party/libaom/source/config/linux/arm/config/aom_config.h +++ b/third_party/libaom/source/config/linux/arm/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h index a8e88f8..7376f46 100644 --- a/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h
@@ -229,6 +229,17 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_c +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_c + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm b/third_party/libaom/source/config/linux/arm64/config/aom_config.asm index a6811f5..8d04b4a 100644 --- a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.c b/third_party/libaom/source/config/linux/arm64/config/aom_config.c index 86e3f3194..7c8f15b 100644 --- a/third_party/libaom/source/config/linux/arm64/config/aom_config.c +++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.h b/third_party/libaom/source/config/linux/arm64/config/aom_config.h index e0e191d..1424475 100644 --- a/third_party/libaom/source/config/linux/arm64/config/aom_config.h +++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h index c07b2fb..5ac080b 100644 --- a/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h
@@ -289,6 +289,26 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_neon +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_neon(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_neon + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.asm b/third_party/libaom/source/config/linux/generic/config/aom_config.asm index 70f3183..56c2d5f 100644 --- a/third_party/libaom/source/config/linux/generic/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/generic/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.c b/third_party/libaom/source/config/linux/generic/config/aom_config.c index b68be2f46..d4d7e87a 100644 --- a/third_party/libaom/source/config/linux/generic/config/aom_config.c +++ b/third_party/libaom/source/config/linux/generic/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DAOM_TARGET_CPU=generic -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DAOM_TARGET_CPU=generic -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.h b/third_party/libaom/source/config/linux/generic/config/aom_config.h index 64a33fa4d..e4c6dfd 100644 --- a/third_party/libaom/source/config/linux/generic/config/aom_config.h +++ b/third_party/libaom/source/config/linux/generic/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h b/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h index 2f7ce5b..ab207e4 100644 --- a/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h
@@ -229,6 +229,17 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_c +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_c + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/linux/ia32/config/aom_config.asm b/third_party/libaom/source/config/linux/ia32/config/aom_config.asm index 6a7fff6..06de5793 100644 --- a/third_party/libaom/source/config/linux/ia32/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/ia32/config/aom_config.asm
@@ -8,7 +8,7 @@ %define CONFIG_AV1_DECODER 1 %define CONFIG_AV1_ENCODER 1 %define CONFIG_AV1_HIGHBITDEPTH 0 -%define CONFIG_AV1_TEMPORAL_DENOISING 0 +%define CONFIG_AV1_TEMPORAL_DENOISING 1 %define CONFIG_BIG_ENDIAN 0 %define CONFIG_BITSTREAM_DEBUG 0 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/ia32/config/aom_config.c b/third_party/libaom/source/config/linux/ia32/config/aom_config.c index 13e1bd00..aaa8142b 100644 --- a/third_party/libaom/source/config/linux/ia32/config/aom_config.c +++ b/third_party/libaom/source/config/linux/ia32/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/x86-linux.cmake\" -DAOM_RTCD_FLAGS=--require-mmx;--require-sse;--require-sse2 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_PIC=1 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/x86-linux.cmake\" -DAOM_RTCD_FLAGS=--require-mmx;--require-sse;--require-sse2 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_PIC=1 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/ia32/config/aom_config.h b/third_party/libaom/source/config/linux/ia32/config/aom_config.h index 0092a4c..31f29a9c 100644 --- a/third_party/libaom/source/config/linux/ia32/config/aom_config.h +++ b/third_party/libaom/source/config/linux/ia32/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h b/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h index 02b5a66..341e028 100644 --- a/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h
@@ -489,6 +489,26 @@ const InterpFilterParams* filter_params_y, const int subpel_y_qn); +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_sse2(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_sse2 + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.asm b/third_party/libaom/source/config/linux/x64/config/aom_config.asm index 7199a6b..ead5c811 100644 --- a/third_party/libaom/source/config/linux/x64/config/aom_config.asm +++ b/third_party/libaom/source/config/linux/x64/config/aom_config.asm
@@ -8,7 +8,7 @@ %define CONFIG_AV1_DECODER 1 %define CONFIG_AV1_ENCODER 1 %define CONFIG_AV1_HIGHBITDEPTH 0 -%define CONFIG_AV1_TEMPORAL_DENOISING 0 +%define CONFIG_AV1_TEMPORAL_DENOISING 1 %define CONFIG_BIG_ENDIAN 0 %define CONFIG_BITSTREAM_DEBUG 0 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.c b/third_party/libaom/source/config/linux/x64/config/aom_config.c index bfe976c..8786cc6 100644 --- a/third_party/libaom/source/config/linux/x64/config/aom_config.c +++ b/third_party/libaom/source/config/linux/x64/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DAOM_TARGET_CPU=x86_64 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DAOM_TARGET_CPU=x86_64 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.h b/third_party/libaom/source/config/linux/x64/config/aom_config.h index e0ed6a5a..555f645 100644 --- a/third_party/libaom/source/config/linux/x64/config/aom_config.h +++ b/third_party/libaom/source/config/linux/x64/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h b/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h index 316f26a..6a0806c 100644 --- a/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h +++ b/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h
@@ -489,6 +489,26 @@ const InterpFilterParams* filter_params_y, const int subpel_y_qn); +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_sse2(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_sse2 + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.asm b/third_party/libaom/source/config/win/arm64/config/aom_config.asm index a6811f5..8d04b4a 100644 --- a/third_party/libaom/source/config/win/arm64/config/aom_config.asm +++ b/third_party/libaom/source/config/win/arm64/config/aom_config.asm
@@ -18,7 +18,7 @@ CONFIG_AV1_DECODER equ 1 CONFIG_AV1_ENCODER equ 1 CONFIG_AV1_HIGHBITDEPTH equ 0 -CONFIG_AV1_TEMPORAL_DENOISING equ 0 +CONFIG_AV1_TEMPORAL_DENOISING equ 1 CONFIG_BIG_ENDIAN equ 0 CONFIG_BITSTREAM_DEBUG equ 0 CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.c b/third_party/libaom/source/config/win/arm64/config/aom_config.c index 86e3f3194..7c8f15b 100644 --- a/third_party/libaom/source/config/win/arm64/config/aom_config.c +++ b/third_party/libaom/source/config/win/arm64/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.h b/third_party/libaom/source/config/win/arm64/config/aom_config.h index 6765acfc..908dd68e 100644 --- a/third_party/libaom/source/config/win/arm64/config/aom_config.h +++ b/third_party/libaom/source/config/win/arm64/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h index c07b2fb..5ac080b 100644 --- a/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h +++ b/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h
@@ -289,6 +289,26 @@ const int subpel_y_qn); #define av1_convolve_y_sr av1_convolve_y_sr_neon +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_neon(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_neon + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/win/ia32/config/aom_config.asm b/third_party/libaom/source/config/win/ia32/config/aom_config.asm index b5f9fc6..ff77a60 100644 --- a/third_party/libaom/source/config/win/ia32/config/aom_config.asm +++ b/third_party/libaom/source/config/win/ia32/config/aom_config.asm
@@ -8,7 +8,7 @@ %define CONFIG_AV1_DECODER 1 %define CONFIG_AV1_ENCODER 1 %define CONFIG_AV1_HIGHBITDEPTH 0 -%define CONFIG_AV1_TEMPORAL_DENOISING 0 +%define CONFIG_AV1_TEMPORAL_DENOISING 1 %define CONFIG_BIG_ENDIAN 0 %define CONFIG_BITSTREAM_DEBUG 0 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/win/ia32/config/aom_config.c b/third_party/libaom/source/config/win/ia32/config/aom_config.c index 13e1bd00..aaa8142b 100644 --- a/third_party/libaom/source/config/win/ia32/config/aom_config.c +++ b/third_party/libaom/source/config/win/ia32/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/x86-linux.cmake\" -DAOM_RTCD_FLAGS=--require-mmx;--require-sse;--require-sse2 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_PIC=1 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/x86-linux.cmake\" -DAOM_RTCD_FLAGS=--require-mmx;--require-sse;--require-sse2 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_PIC=1 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/win/ia32/config/aom_config.h b/third_party/libaom/source/config/win/ia32/config/aom_config.h index a2fb0330..06c4c16 100644 --- a/third_party/libaom/source/config/win/ia32/config/aom_config.h +++ b/third_party/libaom/source/config/win/ia32/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h b/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h index 02b5a66..341e028 100644 --- a/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h +++ b/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h
@@ -489,6 +489,26 @@ const InterpFilterParams* filter_params_y, const int subpel_y_qn); +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_sse2(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_sse2 + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libaom/source/config/win/x64/config/aom_config.asm b/third_party/libaom/source/config/win/x64/config/aom_config.asm index dc6a3091..43d8111 100644 --- a/third_party/libaom/source/config/win/x64/config/aom_config.asm +++ b/third_party/libaom/source/config/win/x64/config/aom_config.asm
@@ -8,7 +8,7 @@ %define CONFIG_AV1_DECODER 1 %define CONFIG_AV1_ENCODER 1 %define CONFIG_AV1_HIGHBITDEPTH 0 -%define CONFIG_AV1_TEMPORAL_DENOISING 0 +%define CONFIG_AV1_TEMPORAL_DENOISING 1 %define CONFIG_BIG_ENDIAN 0 %define CONFIG_BITSTREAM_DEBUG 0 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/win/x64/config/aom_config.c b/third_party/libaom/source/config/win/x64/config/aom_config.c index bfe976c..8786cc6 100644 --- a/third_party/libaom/source/config/win/x64/config/aom_config.c +++ b/third_party/libaom/source/config/win/x64/config/aom_config.c
@@ -9,5 +9,5 @@ * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "aom/aom_codec.h" -static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DAOM_TARGET_CPU=x86_64 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; +static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DAOM_TARGET_CPU=x86_64 -DCONFIG_AV1_ENCODER=1 -DCONFIG_LIBYUV=0 -DCONFIG_REALTIME_ONLY=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_AV1_TEMPORAL_DENOISING=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384"; const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/win/x64/config/aom_config.h b/third_party/libaom/source/config/win/x64/config/aom_config.h index 21f96a0..054422a6 100644 --- a/third_party/libaom/source/config/win/x64/config/aom_config.h +++ b/third_party/libaom/source/config/win/x64/config/aom_config.h
@@ -20,7 +20,7 @@ #define CONFIG_AV1_DECODER 1 #define CONFIG_AV1_ENCODER 1 #define CONFIG_AV1_HIGHBITDEPTH 0 -#define CONFIG_AV1_TEMPORAL_DENOISING 0 +#define CONFIG_AV1_TEMPORAL_DENOISING 1 #define CONFIG_BIG_ENDIAN 0 #define CONFIG_BITSTREAM_DEBUG 0 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
diff --git a/third_party/libaom/source/config/win/x64/config/av1_rtcd.h b/third_party/libaom/source/config/win/x64/config/av1_rtcd.h index 316f26a..6a0806c 100644 --- a/third_party/libaom/source/config/win/x64/config/av1_rtcd.h +++ b/third_party/libaom/source/config/win/x64/config/av1_rtcd.h
@@ -489,6 +489,26 @@ const InterpFilterParams* filter_params_y, const int subpel_y_qn); +int av1_denoiser_filter_c(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +int av1_denoiser_filter_sse2(const uint8_t* sig, + int sig_stride, + const uint8_t* mc_avg, + int mc_avg_stride, + uint8_t* avg, + int avg_stride, + int increase_denoising, + BLOCK_SIZE bs, + int motion_magnitude); +#define av1_denoiser_filter av1_denoiser_filter_sse2 + void av1_dist_wtd_convolve_2d_c(const uint8_t* src, int src_stride, uint8_t* dst,
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index a482f06b..c4a76aa 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -6,9 +6,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Wednesday January 13 2021 +Date: Friday January 29 2021 Branch: master -Commit: 576e0801f9281fd54e2c69ad5be5fef7af656011 +Commit: 61edec1efbea1c02d71857e2aff9426d9cd2df4e Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index d27498a..d2bda5a 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 9 #define VERSION_PATCH 0 -#define VERSION_EXTRA "129-g576e0801f" +#define VERSION_EXTRA "147-g61edec1ef" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.9.0-129-g576e0801f" -#define VERSION_STRING " v1.9.0-129-g576e0801f" +#define VERSION_STRING_NOSP "v1.9.0-147-g61edec1ef" +#define VERSION_STRING " v1.9.0-147-g61edec1ef"
diff --git a/third_party/mako/LICENSE b/third_party/mako/LICENSE index ec32acf..1f835e9 100644 --- a/third_party/mako/LICENSE +++ b/third_party/mako/LICENSE
@@ -1,4 +1,4 @@ -Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file>. +Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file>. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
diff --git a/third_party/mako/Mako.egg-info/PKG-INFO b/third_party/mako/Mako.egg-info/PKG-INFO index 1456b6d..f69071c 100644 --- a/third_party/mako/Mako.egg-info/PKG-INFO +++ b/third_party/mako/Mako.egg-info/PKG-INFO
@@ -1,6 +1,6 @@ -Metadata-Version: 1.2 +Metadata-Version: 2.1 Name: Mako -Version: 1.0.14 +Version: 1.1.4 Summary: A super-fast templating language that borrows the best ideas from the existing templating languages. Home-page: https://www.makotemplates.org/ Author: Mike Bayer @@ -69,7 +69,12 @@ Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Requires-Python: >=2.6 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Provides-Extra: babel +Provides-Extra: lingua
diff --git a/third_party/mako/Mako.egg-info/SOURCES.txt b/third_party/mako/Mako.egg-info/SOURCES.txt index 4e411595..f8d4f9ec5 100644 --- a/third_party/mako/Mako.egg-info/SOURCES.txt +++ b/third_party/mako/Mako.egg-info/SOURCES.txt
@@ -33,7 +33,7 @@ doc/_static/doctools.js doc/_static/documentation_options.js doc/_static/file.png -doc/_static/jquery-3.2.1.js +doc/_static/jquery-3.5.1.js doc/_static/jquery.js doc/_static/language_data.js doc/_static/minus.png
diff --git a/third_party/mako/Mako.egg-info/entry_points.txt b/third_party/mako/Mako.egg-info/entry_points.txt index 3b15006..8e033c00 100644 --- a/third_party/mako/Mako.egg-info/entry_points.txt +++ b/third_party/mako/Mako.egg-info/entry_points.txt
@@ -10,10 +10,10 @@ css+mako = mako.ext.pygmentplugin:MakoCssLexer [babel.extractors] - mako = mako.ext.babelplugin:extract + mako = mako.ext.babelplugin:extract [babel] [lingua.extractors] - mako = mako.ext.linguaplugin:LinguaMakoExtractor + mako = mako.ext.linguaplugin:LinguaMakoExtractor [lingua] [console_scripts] mako-render = mako.cmd:cmdline
diff --git a/third_party/mako/Mako.egg-info/requires.txt b/third_party/mako/Mako.egg-info/requires.txt index 4083f59..191643fa 100644 --- a/third_party/mako/Mako.egg-info/requires.txt +++ b/third_party/mako/Mako.egg-info/requires.txt
@@ -1 +1,7 @@ MarkupSafe>=0.9.2 + +[babel] +Babel + +[lingua] +lingua
diff --git a/third_party/mako/PKG-INFO b/third_party/mako/PKG-INFO index 1456b6d..f69071c 100644 --- a/third_party/mako/PKG-INFO +++ b/third_party/mako/PKG-INFO
@@ -1,6 +1,6 @@ -Metadata-Version: 1.2 +Metadata-Version: 2.1 Name: Mako -Version: 1.0.14 +Version: 1.1.4 Summary: A super-fast templating language that borrows the best ideas from the existing templating languages. Home-page: https://www.makotemplates.org/ Author: Mike Bayer @@ -69,7 +69,12 @@ Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Requires-Python: >=2.6 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Provides-Extra: babel +Provides-Extra: lingua
diff --git a/third_party/mako/README.chromium b/third_party/mako/README.chromium index f666f67d..359ccba 100644 --- a/third_party/mako/README.chromium +++ b/third_party/mako/README.chromium
@@ -1,8 +1,8 @@ Name: Mako Templates for Python Short Name: python-mako URL: https://www.makotemplates.org -Version: 1.0.14 -Date: July 21, 2019 +Version: 1.1.4 +Date: Junuary 15, 2021 License: MIT License File: NOT_SHIPPED Security Critical: no @@ -10,9 +10,9 @@ Description: Template engine in Python, used for code generation in Blink. -Source: https://files.pythonhosted.org/packages/1b/a5/023aba3d69aacef6bfc13797bdc3dd03c6fb4ae2dcd2fde7dffc37233924/Mako-1.0.14.tar.gz -SHA-512: e9a4840f4dddd77d55ad6d3b8724f0326937c04aa9c8c578ec385c70f897419b13ffc234cc673a316de2fa8cd7060fc837cf12f2317658181f8d2eb7dd4ac88f -SHA-256: f5a642d8c5699269ab62a68b296ff990767eb120f51e2e8f3d6afb16bdb57f4b +Source: https://files.pythonhosted.org/packages/5c/db/2d2d88b924aa4674a080aae83b59ea19d593250bfe5ed789947c21736785/Mako-1.1.4.tar.gz +SHA-512: 4844c1d6c8d0d474b4ca4e1b31d3557747fc7e30f70a1976163a26b46b1b45c4c96ca6101fbef252b4e3bb4a61635d2a2c6d1c2933fde5b82bb1a1306f31ff84 +SHA-256: 17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab Local Modifications: -There is no modification except for adding OWNERS, README.chromium, and .gitattributes files. +There is no modification except for adding DIR_METADATA, OWNERS, README.chromium, and .gitattributes files.
diff --git a/third_party/mako/doc/_static/basic.css b/third_party/mako/doc/_static/basic.css index c41d718..be19270 100644 --- a/third_party/mako/doc/_static/basic.css +++ b/third_party/mako/doc/_static/basic.css
@@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -15,6 +15,12 @@ clear: both; } +div.section::after { + display: block; + content: ''; + clear: left; +} + /* -- relbar ---------------------------------------------------------------- */ div.related { @@ -316,21 +322,27 @@ div.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; - padding: 7px 7px 0 7px; + padding: 7px; background-color: #ffe; width: 40%; float: right; + clear: right; + overflow-x: auto; } p.sidebar-title { font-weight: bold; } +div.admonition, div.topic, blockquote { + clear: left; +} + /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; - padding: 7px 7px 0 7px; + padding: 7px; margin: 10px 0 10px 0; } @@ -352,10 +364,6 @@ font-weight: bold; } -div.admonition dl { - margin-bottom: 0; -} - p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; @@ -366,9 +374,28 @@ margin-top: 25px; } +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + /* -- tables ---------------------------------------------------------------- */ table.docutils { + margin-top: 10px; + margin-bottom: 10px; border: 0; border-collapse: collapse; } @@ -416,13 +443,13 @@ border-bottom: none; } -th > p:first-child, -td > p:first-child { +th > :first-child, +td > :first-child { margin-top: 0px; } -th > p:last-child, -td > p:last-child { +th > :last-child, +td > :last-child { margin-bottom: 0px; } @@ -468,6 +495,10 @@ /* -- hlist styles ---------------------------------------------------------- */ +table.hlist { + margin: 1em 0; +} + table.hlist td { vertical-align: top; } @@ -495,17 +526,37 @@ list-style: upper-roman; } -li > p:first-child { +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { margin-top: 0px; } -li > p:last-child { +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { margin-bottom: 0px; } +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + dl.footnote > dt, dl.citation > dt { float: left; + margin-right: 0.5em; } dl.footnote > dd, @@ -520,14 +571,15 @@ } dl.field-list { - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: fit-content(30%) auto; } dl.field-list > dt { - flex-basis: 20%; font-weight: bold; word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; } dl.field-list > dt:after { @@ -535,8 +587,8 @@ } dl.field-list > dd { - flex-basis: 70%; - padding-left: 1em; + padding-left: 0.5em; + margin-top: 0em; margin-left: 0em; margin-bottom: 0em; } @@ -545,7 +597,7 @@ margin-bottom: 15px; } -dd > p:first-child { +dd > :first-child { margin-top: 0px; } @@ -559,6 +611,11 @@ margin-left: 30px; } +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + dt:target, span.highlighted { background-color: #fbe54e; } @@ -636,6 +693,10 @@ overflow-y: hidden; /* fixes display issues on Chrome browsers */ } +pre, div[class*="highlight-"] { + clear: both; +} + span.pre { -moz-hyphens: none; -ms-hyphens: none; @@ -643,22 +704,57 @@ hyphens: none; } +div[class*="highlight-"] { + margin: 1em 0; +} + td.linenos pre { - padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { - margin-left: 0.5em; + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; } table.highlighttable td { - padding: 0 0.5em 0 0.5em; + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; } div.code-block-caption { + margin-top: 1em; padding: 2px 5px; font-size: small; } @@ -667,8 +763,10 @@ background-color: transparent; } -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; +table.highlighttable td.linenos, +span.linenos, +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; } div.code-block-caption span.caption-number { @@ -680,11 +778,7 @@ } div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; + margin: 1em 0; } code.descname { @@ -735,8 +829,7 @@ } span.eqno a.headerlink { - position: relative; - left: 0px; + position: absolute; z-index: 1; }
diff --git a/third_party/mako/doc/_static/changelog.css b/third_party/mako/doc/_static/changelog.css index d708ff8..4ea1203 100644 --- a/third_party/mako/doc/_static/changelog.css +++ b/third_party/mako/doc/_static/changelog.css
@@ -1,7 +1,7 @@ -a.changeset-link { +a.changelog-reference { visibility: hidden; } -li:hover a.changeset-link { +li:hover a.changelog-reference { visibility: visible; }
diff --git a/third_party/mako/doc/_static/doctools.js b/third_party/mako/doc/_static/doctools.js index b33f87f..144884e 100644 --- a/third_party/mako/doc/_static/doctools.js +++ b/third_party/mako/doc/_static/doctools.js
@@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -283,10 +283,12 @@ }, initOnKeyListeners: function() { - $(document).keyup(function(event) { + $(document).keydown(function(event) { var activeElementType = document.activeElement.tagName; - // don't navigate when in search box or textarea - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { switch (event.keyCode) { case 37: // left var prevHref = $('link[rel="prev"]').prop('href');
diff --git a/third_party/mako/doc/_static/documentation_options.js b/third_party/mako/doc/_static/documentation_options.js index e26f70f..f0c0f89 100644 --- a/third_party/mako/doc/_static/documentation_options.js +++ b/third_party/mako/doc/_static/documentation_options.js
@@ -1,9 +1,11 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '1.0.14', + VERSION: '1.1.4', LANGUAGE: 'None', COLLAPSE_INDEX: false, + BUILDER: 'html', FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', HAS_SOURCE: false, SOURCELINK_SUFFIX: '.txt', NAVIGATION_WITH_KEYS: false
diff --git a/third_party/mako/doc/_static/jquery-3.2.1.js b/third_party/mako/doc/_static/jquery-3.5.1.js similarity index 81% rename from third_party/mako/doc/_static/jquery-3.2.1.js rename to third_party/mako/doc/_static/jquery-3.5.1.js index d2d8ca4..5093733 100644 --- a/third_party/mako/doc/_static/jquery-3.2.1.js +++ b/third_party/mako/doc/_static/jquery-3.5.1.js
@@ -1,5 +1,5 @@ /*! - * jQuery JavaScript Library v3.2.1 + * jQuery JavaScript Library v3.5.1 * https://jquery.com/ * * Includes Sizzle.js @@ -9,7 +9,7 @@ * Released under the MIT license * https://jquery.org/license * - * Date: 2017-03-20T18:59Z + * Date: 2020-05-04T22:49Z */ ( function( global, factory ) { @@ -47,13 +47,16 @@ var arr = []; -var document = window.document; - var getProto = Object.getPrototypeOf; var slice = arr.slice; -var concat = arr.concat; +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + var push = arr.push; @@ -71,16 +74,72 @@ var support = {}; +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML <object> elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; - function DOMEval( code, doc ) { +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { doc = doc || document; - var script = doc.createElement( "script" ); + var i, val, + script = doc.createElement( "script" ); script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } doc.head.appendChild( script ).parentNode.removeChild( script ); } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module @@ -88,7 +147,7 @@ var - version = "3.2.1", + version = "3.5.1", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -96,19 +155,6 @@ // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); }; jQuery.fn = jQuery.prototype = { @@ -175,6 +221,18 @@ return this.eq( -1 ); }, + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); @@ -209,7 +267,7 @@ } // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + if ( typeof target !== "object" && !isFunction( target ) ) { target = {}; } @@ -226,25 +284,28 @@ // Extend the base object for ( name in options ) { - src = target[ name ]; copy = options[ name ]; + // Prevent Object.prototype pollution // Prevent never-ending loop - if ( target === copy ) { + if ( name === "__proto__" || target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; - if ( copyIsArray ) { - copyIsArray = false; - clone = src && Array.isArray( src ) ? src : []; - + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; } else { - clone = src && jQuery.isPlainObject( src ) ? src : {}; + clone = src; } + copyIsArray = false; // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); @@ -275,28 +336,6 @@ noop: function() {}, - isFunction: function( obj ) { - return jQuery.type( obj ) === "function"; - }, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - - // As of jQuery 3.0, isNumeric is limited to - // strings and numbers (primitives or objects) - // that can be coerced to finite numbers (gh-2662) - var type = jQuery.type( obj ); - return ( type === "number" || type === "string" ) && - - // parseFloat NaNs numeric-cast false positives ("") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - !isNaN( obj - parseFloat( obj ) ); - }, - isPlainObject: function( obj ) { var proto, Ctor; @@ -319,9 +358,6 @@ }, isEmptyObject: function( obj ) { - - /* eslint-disable no-unused-vars */ - // See https://github.com/eslint/eslint/issues/6125 var name; for ( name in obj ) { @@ -330,27 +366,10 @@ return true; }, - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - DOMEval( code ); - }, - - // Convert dashed to camelCase; used by the css and data modules - // Support: IE <=9 - 11, Edge 12 - 13 - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); }, each: function( obj, callback ) { @@ -374,13 +393,6 @@ return obj; }, - // Support: Android <=4.0 only - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; @@ -467,43 +479,12 @@ } // Flatten any nested arrays - return concat.apply( [], ret ); + return flat( ret ); }, // A global GUID counter for objects guid: 1, - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support @@ -515,7 +496,7 @@ // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( i, name ) { +function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); @@ -526,9 +507,9 @@ // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, - type = jQuery.type( obj ); + type = toType( obj ); - if ( type === "function" || jQuery.isWindow( obj ) ) { + if ( isFunction( obj ) || isWindow( obj ) ) { return false; } @@ -537,17 +518,16 @@ } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.3.3 + * Sizzle CSS Selector Engine v2.3.5 * https://sizzlejs.com/ * - * Copyright jQuery Foundation and other contributors + * Copyright JS Foundation and other contributors * Released under the MIT license - * http://jquery.org/license + * https://js.foundation/ * - * Date: 2016-08-08 + * Date: 2020-03-14 */ -(function( window ) { - +( function( window ) { var i, support, Expr, @@ -578,6 +558,7 @@ classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), + nonnativeSelectorCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; @@ -586,61 +567,71 @@ }, // Instance methods - hasOwn = ({}).hasOwnProperty, + hasOwn = ( {} ).hasOwnProperty, arr = [], pop = arr.pop, - push_native = arr.push, + pushNative = arr.push, push = arr.push, slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { - if ( list[i] === elem ) { + if ( list[ i ] === elem ) { return i; } } return -1; }, - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), @@ -651,16 +642,19 @@ "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, + rhtml = /HTML$/i, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, @@ -673,18 +667,21 @@ // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair high < 0 ? - // BMP codepoint String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, @@ -700,7 +697,8 @@ } // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped @@ -715,9 +713,9 @@ setDocument(); }, - disabledAncestor = addCombinator( + inDisabledFieldset = addCombinator( function( elem ) { - return elem.disabled === true && ("form" in elem || "label" in elem); + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; }, { dir: "parentNode", next: "legend" } ); @@ -725,18 +723,20 @@ // Optimize for push.apply( _, NodeList ) try { push.apply( - (arr = slice.call( preferredDoc.childNodes )), + ( arr = slice.call( preferredDoc.childNodes ) ), preferredDoc.childNodes ); + // Support: Android<4.0 // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { - push_native.apply( target, slice.call(els) ); + pushNative.apply( target, slice.call( els ) ); } : // Support: IE<9 @@ -744,8 +744,9 @@ function( target, els ) { var j = target.length, i = 0; + // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} + while ( ( target[ j++ ] = els[ i++ ] ) ) {} target.length = j - 1; } }; @@ -769,24 +770,21 @@ // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } + setDocument( context ); context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { // ID selector - if ( (m = match[1]) ) { + if ( ( m = match[ 1 ] ) ) { // Document context if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { + if ( ( elem = context.getElementById( m ) ) ) { // Support: IE, Opera, Webkit // TODO: identify versions @@ -805,7 +803,7 @@ // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID - if ( newContext && (elem = newContext.getElementById( m )) && + if ( newContext && ( elem = newContext.getElementById( m ) ) && contains( context, elem ) && elem.id === m ) { @@ -815,12 +813,12 @@ } // Type selector - } else if ( match[2] ) { + } else if ( match[ 2 ] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector - } else if ( (m = match[3]) && support.getElementsByClassName && + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); @@ -830,50 +828,62 @@ // Take advantage of querySelectorAll if ( support.qsa && - !compilerCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && - if ( nodeType !== 1 ) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 + // Support: IE 8 only // Exclude object elements - } else if ( context.nodeName.toLowerCase() !== "object" ) { + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { - // Capture the context ID, setting it first if necessary - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", (nid = expando) ); + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { - groups[i] = "#" + nid + " " + toSelector( groups[i] ); + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); } newSelector = groups.join( "," ); - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; } - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); } } } @@ -894,12 +904,14 @@ var keys = []; function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries delete cache[ keys.shift() ]; } - return (cache[ key + " " ] = value); + return ( cache[ key + " " ] = value ); } return cache; } @@ -918,17 +930,19 @@ * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { - var el = document.createElement("fieldset"); + var el = document.createElement( "fieldset" ); try { return !!fn( el ); - } catch (e) { + } catch ( e ) { return false; } finally { + // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } + // release memory in IE el = null; } @@ -940,11 +954,11 @@ * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { - var arr = attrs.split("|"), + var arr = attrs.split( "|" ), i = arr.length; while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; + Expr.attrHandle[ arr[ i ] ] = handler; } } @@ -966,7 +980,7 @@ // Check if b follows a if ( cur ) { - while ( (cur = cur.nextSibling) ) { + while ( ( cur = cur.nextSibling ) ) { if ( cur === b ) { return -1; } @@ -994,7 +1008,7 @@ function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; + return ( name === "input" || name === "button" ) && elem.type === type; }; } @@ -1037,7 +1051,7 @@ // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && - disabledAncestor( elem ) === disabled; + inDisabledFieldset( elem ) === disabled; } return elem.disabled === disabled; @@ -1059,21 +1073,21 @@ * @param {Function} fn */ function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { + return markFunction( function( argument ) { argument = +argument; - return markFunction(function( seed, matches ) { + return markFunction( function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); } } - }); - }); + } ); + } ); } /** @@ -1094,10 +1108,13 @@ * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); }; /** @@ -1110,7 +1127,11 @@ doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } @@ -1119,10 +1140,14 @@ docElem = document.documentElement; documentIsHTML = !isXML( document ); - // Support: IE 9-11, Edge + // Support: IE 9 - 11+, Edge 12 - 18+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if ( preferredDoc !== document && - (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { @@ -1134,25 +1159,36 @@ } } + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) - support.attributes = assert(function( el ) { + support.attributes = assert( function( el ) { el.className = "i"; - return !el.getAttribute("className"); - }); + return !el.getAttribute( "className" ); + } ); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( el ) { - el.appendChild( document.createComment("") ); - return !el.getElementsByTagName("*").length; - }); + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); @@ -1161,38 +1197,38 @@ // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test - support.getById = assert(function( el ) { + support.getById = assert( function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; - }); + } ); // ID filter and find if ( support.getById ) { - Expr.filter["ID"] = function( id ) { + Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { - return elem.getAttribute("id") === attrId; + return elem.getAttribute( "id" ) === attrId; }; }; - Expr.find["ID"] = function( id, context ) { + Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { - Expr.filter["ID"] = function( id ) { + Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); + elem.getAttributeNode( "id" ); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut - Expr.find["ID"] = function( id, context ) { + Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); @@ -1200,7 +1236,7 @@ if ( elem ) { // Verify the id attribute - node = elem.getAttributeNode("id"); + node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } @@ -1208,8 +1244,8 @@ // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; - while ( (elem = elems[i++]) ) { - node = elem.getAttributeNode("id"); + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } @@ -1222,7 +1258,7 @@ } // Tag - Expr.find["TAG"] = support.getElementsByTagName ? + Expr.find[ "TAG" ] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); @@ -1237,12 +1273,13 @@ var elem, tmp = [], i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { - while ( (elem = results[i++]) ) { + while ( ( elem = results[ i++ ] ) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } @@ -1254,7 +1291,7 @@ }; // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } @@ -1275,10 +1312,14 @@ // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; - if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + // Build QSA regex // Regex strategy adopted from Diego Perini - assert(function( el ) { + assert( function( el ) { + + var input; + // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, @@ -1292,78 +1333,98 @@ // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll("[msallowcapture^='']").length ) { + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll("[selected]").length ) { + if ( !el.querySelectorAll( "[selected]" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); + rbuggyQSA.push( ".#.+[+~]" ); } - }); - assert(function( el ) { + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { el.innerHTML = "<a href='' disabled='disabled'></a>" + "<select disabled='disabled'><option/></select>"; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); + var input = document.createElement( "input" ); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll("[name=d]").length ) { + if ( el.querySelectorAll( "[name=d]" ).length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests - if ( el.querySelectorAll(":enabled").length !== 2 ) { + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll(":disabled").length !== 2 ) { + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } + // Support: Opera 10 - 11 only // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); } - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { + docElem.msMatchesSelector ) ) ) ) { - assert(function( el ) { + assert( function( el ) { + // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); @@ -1372,11 +1433,11 @@ // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); - }); + } ); } - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); /* Contains ---------------------------------------------------------------------- */ @@ -1393,11 +1454,11 @@ adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); + ) ); } : function( a, b ) { if ( b ) { - while ( (b = b.parentNode) ) { + while ( ( b = b.parentNode ) ) { if ( b === a ) { return true; } @@ -1426,7 +1487,11 @@ } // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected @@ -1434,13 +1499,24 @@ // Disconnected nodes if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { // Choose the first element that is related to our preferred document - if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { return -1; } - if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { return 1; } @@ -1453,6 +1529,7 @@ return compare & 4 ? -1 : 1; } : function( a, b ) { + // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; @@ -1468,8 +1545,14 @@ // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { - return a === document ? -1 : - b === document ? 1 : + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ aup ? -1 : bup ? 1 : sortInput ? @@ -1483,26 +1566,32 @@ // Otherwise we need full lists of their ancestors for comparison cur = a; - while ( (cur = cur.parentNode) ) { + while ( ( cur = cur.parentNode ) ) { ap.unshift( cur ); } cur = b; - while ( (cur = cur.parentNode) ) { + while ( ( cur = cur.parentNode ) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { + while ( ap[ i ] === bp[ i ] ) { i++; } return i ? + // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : + siblingCheck( ap[ i ], bp[ i ] ) : // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ 0; }; @@ -1514,16 +1603,10 @@ }; Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); + setDocument( elem ); if ( support.matchesSelector && documentIsHTML && - !compilerCache[ expr + " " ] && + !nonnativeSelectorCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { @@ -1532,32 +1615,46 @@ // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { return ret; } - } catch (e) {} + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { + // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { + // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : @@ -1567,13 +1664,13 @@ val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? + ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { - return (sel + "").replace( rcssescape, fcssescape ); + return ( sel + "" ).replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { @@ -1596,7 +1693,7 @@ results.sort( sortOrder ); if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { + while ( ( elem = results[ i++ ] ) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } @@ -1624,17 +1721,21 @@ nodeType = elem.nodeType; if ( !nodeType ) { + // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { + while ( ( node = elem[ i++ ] ) ) { + // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { + // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); @@ -1643,6 +1744,7 @@ } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } + // Do not include comment or processing instruction nodes return ret; @@ -1670,19 +1772,21 @@ preFilter: { "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) @@ -1693,22 +1797,25 @@ 7 sign of y-component 8 y of y-component */ - match[1] = match[1].toLowerCase(); + match[ 1 ] = match[ 1 ].toLowerCase(); - if ( match[1].slice( 0, 3 ) === "nth" ) { + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); } return match; @@ -1716,26 +1823,28 @@ "PSEUDO": function( match ) { var excess, - unquoted = !match[6] && match[2]; + unquoted = !match[ 6 ] && match[ 2 ]; - if ( matchExpr["CHILD"].test( match[0] ) ) { + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { return null; } // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && + ( excess = tokenize( unquoted, true ) ) && + // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) @@ -1748,7 +1857,9 @@ "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? - function() { return true; } : + function() { + return true; + } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; @@ -1758,10 +1869,16 @@ var pattern = classCache[ className + " " ]; return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); - }); + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); }, "ATTR": function( name, operator, check ) { @@ -1777,6 +1894,8 @@ result += ""; + /* eslint-disable max-len */ + return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : @@ -1785,10 +1904,12 @@ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; + /* eslint-enable max-len */ + }; }, - "CHILD": function( type, what, argument, first, last ) { + "CHILD": function( type, what, _argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; @@ -1800,7 +1921,7 @@ return !!elem.parentNode; } : - function( elem, context, xml ) { + function( elem, _context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, @@ -1814,7 +1935,7 @@ if ( simple ) { while ( dir ) { node = elem; - while ( (node = node[ dir ]) ) { + while ( ( node = node[ dir ] ) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { @@ -1822,6 +1943,7 @@ return false; } } + // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } @@ -1837,22 +1959,22 @@ // ...in a gzip-friendly way node = parent; - outerCache = node[ expando ] || (node[ expando ] = {}); + outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); + ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; - while ( (node = ++nodeIndex && node && node[ dir ] || + while ( ( node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { + ( diff = nodeIndex = 0 ) || start.pop() ) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { @@ -1862,16 +1984,18 @@ } } else { + // Use previously-cached element index if available if ( useCache ) { + // ...in a gzip-friendly way node = elem; - outerCache = node[ expando ] || (node[ expando ] = {}); + outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); + ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; @@ -1881,9 +2005,10 @@ // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : @@ -1892,12 +2017,13 @@ // Cache the index of each encountered element if ( useCache ) { - outerCache = node[ expando ] || (node[ expando ] = {}); + outerCache = node[ expando ] || + ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); + ( outerCache[ node.uniqueID ] = {} ); uniqueCache[ type ] = [ dirruns, diff ]; } @@ -1918,6 +2044,7 @@ }, "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters @@ -1937,15 +2064,15 @@ if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { + markFunction( function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { - idx = indexOf( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); } - }) : + } ) : function( elem ) { return fn( elem, 0, args ); }; @@ -1956,8 +2083,10 @@ }, pseudos: { + // Potentially complex pseudos - "not": markFunction(function( selector ) { + "not": markFunction( function( selector ) { + // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators @@ -1966,39 +2095,40 @@ matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { + markFunction( function( seed, matches, _context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); } } - }) : - function( elem, context, xml ) { - input[0] = elem; + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; matcher( input, null, xml, results ); + // Don't keep the element (issue #299) - input[0] = null; + input[ 0 ] = null; return !results.pop(); }; - }), + } ), - "has": markFunction(function( selector ) { + "has": markFunction( function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; - }), + } ), - "contains": markFunction(function( text ) { + "contains": markFunction( function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; }; - }), + } ), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value @@ -2008,25 +2138,26 @@ // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { + // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { + if ( !ridentifier.test( lang || "" ) ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { - if ( (elemLang = documentIsHTML ? + if ( ( elemLang = documentIsHTML ? elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); return false; }; - }), + } ), // Miscellaneous "target": function( elem ) { @@ -2039,7 +2170,9 @@ }, "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); }, // Boolean properties @@ -2047,16 +2180,20 @@ "disabled": createDisabledPseudo( true ), "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); }, "selected": function( elem ) { + // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions elem.parentNode.selectedIndex; } @@ -2065,6 +2202,7 @@ // Contents "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) @@ -2078,7 +2216,7 @@ }, "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); + return !Expr.pseudos[ "empty" ]( elem ); }, // Element/input types @@ -2102,57 +2240,62 @@ // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); }, // Position-in-collection - "first": createPositionalPseudo(function() { + "first": createPositionalPseudo( function() { return [ 0 ]; - }), + } ), - "last": createPositionalPseudo(function( matchIndexes, length ) { + "last": createPositionalPseudo( function( _matchIndexes, length ) { return [ length - 1 ]; - }), + } ), - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; - }), + } ), - "even": createPositionalPseudo(function( matchIndexes, length ) { + "even": createPositionalPseudo( function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; - }), + } ), - "odd": createPositionalPseudo(function( matchIndexes, length ) { + "odd": createPositionalPseudo( function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; - }), + } ), - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; - }), + } ), - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; - }) + } ) } }; -Expr.pseudos["nth"] = Expr.pseudos["eq"]; +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { @@ -2183,37 +2326,39 @@ while ( soFar ) { // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { if ( match ) { + // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; + soFar = soFar.slice( match[ 0 ].length ) || soFar; } - groups.push( (tokens = []) ); + groups.push( ( tokens = [] ) ); } matched = false; // Combinators - if ( (match = rcombinators.exec( soFar )) ) { + if ( ( match = rcombinators.exec( soFar ) ) ) { matched = match.shift(); - tokens.push({ + tokens.push( { value: matched, + // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); + type: match[ 0 ].replace( rtrim, " " ) + } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { matched = match.shift(); - tokens.push({ + tokens.push( { value: matched, type: type, matches: match - }); + } ); soFar = soFar.slice( matched.length ); } } @@ -2230,6 +2375,7 @@ soFar.length : soFar ? Sizzle.error( selector ) : + // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; @@ -2239,7 +2385,7 @@ len = tokens.length, selector = ""; for ( ; i < len; i++ ) { - selector += tokens[i].value; + selector += tokens[ i ].value; } return selector; } @@ -2252,9 +2398,10 @@ doneName = done++; return combinator.first ? + // Check against closest ancestor/preceding element function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { + while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } @@ -2269,7 +2416,7 @@ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { - while ( (elem = elem[ dir ]) ) { + while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; @@ -2277,27 +2424,29 @@ } } } else { - while ( (elem = elem[ dir ]) ) { + while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; - } else if ( (oldCache = uniqueCache[ key ]) && + } else if ( ( oldCache = uniqueCache[ key ] ) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); + return ( newCache[ 2 ] = oldCache[ 2 ] ); } else { + // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { return true; } } @@ -2313,20 +2462,20 @@ function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { + if ( !matchers[ i ]( elem, context, xml ) ) { return false; } } return true; } : - matchers[0]; + matchers[ 0 ]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); + Sizzle( selector, contexts[ i ], results ); } return results; } @@ -2339,7 +2488,7 @@ mapped = map != null; for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { + if ( ( elem = unmatched[ i ] ) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { @@ -2359,14 +2508,18 @@ if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } - return markFunction(function( seed, results, context, xml ) { + return markFunction( function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? @@ -2374,6 +2527,7 @@ elems, matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? @@ -2397,8 +2551,8 @@ // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); } } } @@ -2406,25 +2560,27 @@ if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { - if ( (elem = matcherOut[i]) ) { + if ( ( elem = matcherOut[ i ] ) ) { + // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); + temp.push( ( matcherIn[ i ] = elem ) ); } } - postFinder( null, (matcherOut = []), temp, xml ); + postFinder( null, ( matcherOut = [] ), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { - seed[temp] = !(results[temp] = elem); + seed[ temp ] = !( results[ temp ] = elem ); } } } @@ -2442,14 +2598,14 @@ push.apply( results, matcherOut ); } } - }); + } ); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) @@ -2461,38 +2617,43 @@ }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? + ( checkContext = context ).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { + if ( Expr.relative[ tokens[ j ].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), j < len && toSelector( tokens ) ); } @@ -2513,28 +2674,40 @@ unmatched = seed && [], setMatched = [], contextBackup = outermostContext, + // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), len = elems.length; if ( outermost ) { - outermostContext = context === document || context || outermost; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { if ( byElement && elem ) { j = 0; - if ( !context && elem.ownerDocument !== document ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { setDocument( elem ); xml = !documentIsHTML; } - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context || document, xml) ) { + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { results.push( elem ); break; } @@ -2546,8 +2719,9 @@ // Track unmatched elements for set filters if ( bySet ) { + // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { + if ( ( elem = !matcher && elem ) ) { matchedCount--; } @@ -2571,16 +2745,17 @@ // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; - while ( (matcher = setMatchers[j++]) ) { + while ( ( matcher = setMatchers[ j++ ] ) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); } } } @@ -2621,13 +2796,14 @@ cached = compilerCache[ selector + " " ]; if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { - cached = matcherFromTokens( match[i] ); + cached = matcherFromTokens( match[ i ] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { @@ -2636,7 +2812,10 @@ } // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); // Save selector and tokenization cached.selector = selector; @@ -2656,7 +2835,7 @@ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); results = results || []; @@ -2665,11 +2844,12 @@ if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; if ( !context ) { return results; @@ -2682,20 +2862,22 @@ } // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; while ( i-- ) { - token = tokens[i]; + token = tokens[ i ]; // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { + if ( Expr.relative[ ( type = token.type ) ] ) { break; } - if ( (find = Expr.find[ type ]) ) { + if ( ( find = Expr.find[ type ] ) ) { + // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); @@ -2726,7 +2908,7 @@ // One-time assignments // Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function @@ -2737,58 +2919,59 @@ // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( el ) { +support.sortDetached = assert( function( el ) { + // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; -}); + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( el ) { +if ( !assert( function( el ) { el.innerHTML = "<a href='#'></a>"; - return el.firstChild.getAttribute("href") === "#" ; -}) ) { + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } - }); + } ); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( el ) { +if ( !support.attributes || !assert( function( el ) { el.innerHTML = "<input/>"; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } - }); + } ); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( el ) { - return el.getAttribute("disabled") == null; -}) ) { +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? + ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : - null; + null; } - }); + } ); } return Sizzle; -})( window ); +} )( window ); @@ -2848,11 +3031,9 @@ -var risSimple = /^.[^:#\[\.,]*$/; - // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { + if ( isFunction( qualifier ) ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); @@ -2872,16 +3053,8 @@ } ); } - // Simple selector that can be filtered directly, removing non-Elements - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - // Complex selector, compare the two sets, removing non-Elements - qualifier = jQuery.filter( qualifier, elements ); - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; - } ); + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { @@ -3002,7 +3175,7 @@ for ( match in context ) { // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { + if ( isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes @@ -3045,7 +3218,7 @@ // HANDLE: $(function) // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { + } else if ( isFunction( selector ) ) { return root.ready !== undefined ? root.ready( selector ) : @@ -3167,7 +3340,7 @@ parents: function( elem ) { return dir( elem, "parentNode" ); }, - parentsUntil: function( elem, i, until ) { + parentsUntil: function( elem, _i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { @@ -3182,10 +3355,10 @@ prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, - nextUntil: function( elem, i, until ) { + nextUntil: function( elem, _i, until ) { return dir( elem, "nextSibling", until ); }, - prevUntil: function( elem, i, until ) { + prevUntil: function( elem, _i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { @@ -3195,18 +3368,24 @@ return siblings( elem.firstChild ); }, contents: function( elem ) { - if ( nodeName( elem, "iframe" ) ) { - return elem.contentDocument; - } + if ( elem.contentDocument != null && - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } + // Support: IE 11+ + // <object> elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { - return jQuery.merge( [], elem.childNodes ); + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { @@ -3360,11 +3539,11 @@ ( function add( args ) { jQuery.each( args, function( _, arg ) { - if ( jQuery.isFunction( arg ) ) { + if ( isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } - } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + } else if ( arg && arg.length && toType( arg ) !== "string" ) { // Inspect recursively add( arg ); @@ -3479,11 +3658,11 @@ try { // Check for promise aspect first to privilege synchronous behavior - if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { + if ( value && isFunction( ( method = value.promise ) ) ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables - } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { + } else if ( value && isFunction( ( method = value.then ) ) ) { method.call( value, resolve, reject ); // Other non-thenables @@ -3538,17 +3717,17 @@ var fns = arguments; return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { + jQuery.each( tuples, function( _i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { + if ( returned && isFunction( returned.promise ) ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) @@ -3602,7 +3781,7 @@ returned.then; // Handle a returned thenable - if ( jQuery.isFunction( then ) ) { + if ( isFunction( then ) ) { // Special processors (notify) just wait for resolution if ( special ) { @@ -3698,7 +3877,7 @@ resolve( 0, newDefer, - jQuery.isFunction( onProgress ) ? + isFunction( onProgress ) ? onProgress : Identity, newDefer.notifyWith @@ -3710,7 +3889,7 @@ resolve( 0, newDefer, - jQuery.isFunction( onFulfilled ) ? + isFunction( onFulfilled ) ? onFulfilled : Identity ) @@ -3721,7 +3900,7 @@ resolve( 0, newDefer, - jQuery.isFunction( onRejected ) ? + isFunction( onRejected ) ? onRejected : Thrower ) @@ -3761,8 +3940,15 @@ // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock ); } @@ -3832,7 +4018,7 @@ // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( master.state() === "pending" || - jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { return master.then(); } @@ -3960,7 +4146,7 @@ bulk = key == null; // Sets many values - if ( jQuery.type( key ) === "object" ) { + if ( toType( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); @@ -3970,7 +4156,7 @@ } else if ( value !== undefined ) { chainable = true; - if ( !jQuery.isFunction( value ) ) { + if ( !isFunction( value ) ) { raw = true; } @@ -3984,7 +4170,7 @@ // ...except when executing function values } else { bulk = fn; - fn = function( elem, key, value ) { + fn = function( elem, _key, value ) { return bulk.call( jQuery( elem ), value ); }; } @@ -4012,6 +4198,23 @@ return len ? fn( elems[ 0 ], key ) : emptyGet; }; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} var acceptData = function( owner ) { // Accepts only: @@ -4074,14 +4277,14 @@ // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { - cache[ jQuery.camelCase( data ) ] = value; + cache[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { - cache[ jQuery.camelCase( prop ) ] = data[ prop ]; + cache[ camelCase( prop ) ] = data[ prop ]; } } return cache; @@ -4091,7 +4294,7 @@ this.cache( owner ) : // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( owner, key, value ) { @@ -4139,9 +4342,9 @@ // If key is an array of keys... // We always set camelCase keys, so remove that. - key = key.map( jQuery.camelCase ); + key = key.map( camelCase ); } else { - key = jQuery.camelCase( key ); + key = camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace @@ -4287,7 +4490,7 @@ if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice( 5 ) ); + name = camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } @@ -4491,6 +4694,26 @@ var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } var isHiddenWithinTree = function( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; @@ -4505,37 +4728,15 @@ // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. - jQuery.contains( elem.ownerDocument, elem ) && + isAttached( elem ) && jQuery.css( elem, "display" ) === "none"; }; -var swap = function( elem, options, callback, args ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, - scale = 1, + var adjusted, scale, maxIterations = 20, currentValue = tween ? function() { @@ -4548,35 +4749,39 @@ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), // Starting value computation is required for potential unit mismatches - initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; - // Make sure we update the tween properties later on - valueParts = valueParts || []; - // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; - do { + while ( maxIterations-- ) { - // If previous iteration zeroed out, double until we get *something*. - // Use string for doubling so we don't accidentally see scale as unchanged below - scale = scale || ".5"; - - // Adjust and apply - initialInUnit = initialInUnit / scale; + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; - // Update scale, tolerating zero or NaN from tween.cur() - // Break the loop if scale is unchanged or perfect, or if we've just had enough. - } while ( - scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations - ); + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; } if ( valueParts ) { @@ -4692,18 +4897,47 @@ } ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); -var rscriptType = ( /^$|\/(?:java|ecma)script/i ); +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces <option> tags with their contents when inserted outside of + // the select element. + div.innerHTML = "<option></option>"; + support.option = !!div.lastChild; +} )(); + + // We have to close these tags to support XHTML (#13200) var wrapMap = { - // Support: IE <=9 only - option: [ 1, "<select multiple='multiple'>", "</select>" ], - // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting <tbody> or other required elements. @@ -4715,12 +4949,14 @@ _default: [ 0, "", "" ] }; -// Support: IE <=9 only -wrapMap.optgroup = wrapMap.option; - wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; +} + function getAll( context, tag ) { @@ -4764,7 +5000,7 @@ var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, contains, j, + var elem, tmp, tag, wrap, attached, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, @@ -4776,7 +5012,7 @@ if ( elem || elem === 0 ) { // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { + if ( toType( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit @@ -4828,13 +5064,13 @@ continue; } - contains = jQuery.contains( elem.ownerDocument, elem ); + attached = isAttached( elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history - if ( contains ) { + if ( attached ) { setGlobalEval( tmp ); } @@ -4853,34 +5089,6 @@ } -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = "<textarea>x</textarea>"; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -} )(); -var documentElement = document.documentElement; - - - var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, @@ -4894,8 +5102,19 @@ return false; } +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + // Support: IE <=9 only -// See #13393 for more info +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 function safeActiveElement() { try { return document.activeElement; @@ -4978,8 +5197,8 @@ special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { return; } @@ -5003,7 +5222,7 @@ // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { - events = elemData.events = {}; + events = elemData.events = Object.create( null ); } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { @@ -5161,12 +5380,15 @@ dispatch: function( nativeEvent ) { - // Make a writable jQuery.Event from the native event object - var event = jQuery.event.fix( nativeEvent ); - var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), - handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event @@ -5195,9 +5417,10 @@ while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; @@ -5286,7 +5509,7 @@ enumerable: true, configurable: true, - get: jQuery.isFunction( hook ) ? + get: isFunction( hook ) ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); @@ -5321,39 +5544,51 @@ // Prevent triggered image.load events from bubbling to window.load noBubble: true }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { - this.click(); - return false; + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; }, - // For cross-browser consistency, don't fire native .click() on links + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack _default: function( event ) { - return nodeName( event.target, "a" ); + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); } }, @@ -5370,6 +5605,93 @@ } }; +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects @@ -5421,7 +5743,7 @@ } // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); + this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[ jQuery.expando ] = true; @@ -5482,6 +5804,7 @@ shiftKey: true, view: true, "char": true, + code: true, charCode: true, key: true, keyCode: true, @@ -5528,6 +5851,33 @@ } }, jQuery.event.addProp ); +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout @@ -5613,21 +5963,13 @@ var - /* eslint-disable max-len */ - - // See https://github.com/eslint/eslint/issues/3229 - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - - /* eslint-enable */ - - // Support: IE <=10 - 11, Edge 12 - 13 + // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /<script|<style|<link/i, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptTypeMasked = /^true\/(.*)/, rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; // Prefer a tbody over its parent table for containing new rows @@ -5635,7 +5977,7 @@ if ( nodeName( elem, "table" ) && nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - return jQuery( ">tbody", elem )[ 0 ] || elem; + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; } return elem; @@ -5647,10 +5989,8 @@ return elem; } function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - - if ( match ) { - elem.type = match[ 1 ]; + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); } else { elem.removeAttribute( "type" ); } @@ -5659,7 +5999,7 @@ } function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + var i, l, type, pdataOld, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; @@ -5667,13 +6007,11 @@ // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.access( src ); - pdataCur = dataPriv.set( dest, pdataOld ); + pdataOld = dataPriv.get( src ); events = pdataOld.events; if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; + dataPriv.remove( dest, "handle events" ); for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { @@ -5709,22 +6047,22 @@ function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays - args = concat.apply( [], args ); + args = flat( args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], - isFunction = jQuery.isFunction( value ); + valueIsFunction = isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || + if ( valueIsFunction || ( l > 1 && typeof value === "string" && !support.checkClone && rchecked.test( value ) ) ) { return collection.each( function( index ) { var self = collection.eq( index ); - if ( isFunction ) { + if ( valueIsFunction ) { args[ 0 ] = value.call( this, index, self.html() ); } domManip( self, args, callback, ignored ); @@ -5778,14 +6116,16 @@ !dataPriv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - if ( node.src ) { + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); } } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); } } } @@ -5807,7 +6147,7 @@ } if ( node.parentNode ) { - if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + if ( keepData && isAttached( node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); @@ -5819,13 +6159,13 @@ jQuery.extend( { htmlPrefilter: function( html ) { - return html.replace( rxhtmlTag, "<$1></$2>" ); + return html; }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), - inPage = jQuery.contains( elem.ownerDocument, elem ); + inPage = isAttached( elem ); // Fix IE cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && @@ -6065,8 +6405,6 @@ return this.pushStack( ret ); }; } ); -var rmargin = ( /^margin/ ); - var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { @@ -6083,6 +6421,29 @@ return view.getComputedStyle( elem ); }; +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + ( function() { @@ -6096,25 +6457,35 @@ return; } + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; div.style.cssText = - "box-sizing:border-box;" + - "position:relative;display:block;" + + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + - "top:1%;width:50%"; - div.innerHTML = ""; - documentElement.appendChild( container ); + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = divStyle.marginLeft === "2px"; - boxSizingReliableVal = divStyle.width === "4px"; + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - // Support: Android 4.0 - 4.3 only + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't - div.style.marginRight = "50%"; - pixelMarginRightVal = divStyle.marginRight === "4px"; + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; documentElement.removeChild( container ); @@ -6123,7 +6494,12 @@ div = null; } - var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); @@ -6138,26 +6514,55 @@ div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; - container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + - "padding:0;margin-top:1px;position:absolute"; - container.appendChild( div ); - jQuery.extend( support, { - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, boxSizingReliable: function() { computeStyleTests(); return boxSizingReliableVal; }, - pixelMarginRight: function() { + pixelBoxStyles: function() { computeStyleTests(); - return pixelMarginRightVal; + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; } } ); } )(); @@ -6180,7 +6585,7 @@ if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; - if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + if ( ret === "" && !isAttached( elem ) ) { ret = jQuery.style( elem, name ); } @@ -6189,7 +6594,7 @@ // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { // Remember the original values width = style.width; @@ -6236,30 +6641,13 @@ } -var +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }, - - cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style; - -// Return a css property mapped to a potentially vendor prefixed property +// Return a vendor-prefixed property or undefined function vendorPropName( name ) { - // Shortcut for names that are not vendor prefixed - if ( name in emptyStyle ) { - return name; - } - // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; @@ -6272,17 +6660,34 @@ } } -// Return a property mapped along what jQuery.cssProps suggests or to -// a vendor prefixed property. +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property function finalPropName( name ) { - var ret = jQuery.cssProps[ name ]; - if ( !ret ) { - ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; } - return ret; + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; } -function setPositiveNumber( elem, value, subtract ) { + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point @@ -6294,87 +6699,146 @@ value; } -function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { - var i, - val = 0; +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; - // If we already have the right measurement, avoid augmentation - if ( extra === ( isBorderBox ? "border" : "content" ) ) { - i = 4; - - // Otherwise initialize for horizontal or vertical properties - } else { - i = name === "width" ? 1 : 0; + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; } for ( ; i < 4; i += 2 ) { - // Both box models exclude margin, so add it if we want it - if ( extra === "margin" ) { - val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); } - if ( isBorderBox ) { + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { - // border-box includes padding, so remove it if we want content - if ( extra === "content" ) { - val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } - // At this point, extra isn't border nor margin, so remove border - if ( extra !== "margin" ) { - val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" } else { - // At this point, extra isn't content, so add padding - val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } - // At this point, extra isn't content nor padding, so add border - if ( extra !== "padding" ) { - val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } - return val; + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; } -function getWidthOrHeight( elem, name, extra ) { +function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style - var valueIsBorderBox, - styles = getStyles( elem ), - val = curCSS( elem, name, styles ), + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test( val ) ) { - return val; + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } } - // Check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = isBorderBox && - ( support.boxSizingReliable() || val === elem.style[ name ] ); - - // Fall back to offsetWidth/Height when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - if ( val === "auto" ) { - val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ]; - } - - // Normalize "", auto, and prepare for extra + // Normalize "" and auto val = parseFloat( val ) || 0; - // Use the active box-sizing model to add/subtract irrelevant styles + // Adjust for the element's box model return ( val + - augmentWidthOrHeight( + boxModelAdjustment( elem, - name, + dimension, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, - styles + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val ) ) + "px"; } @@ -6404,6 +6868,13 @@ "flexGrow": true, "flexShrink": true, "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, "lineHeight": true, "opacity": true, "order": true, @@ -6415,9 +6886,7 @@ // Add in properties whose names you wish to fix before // setting or getting the value - cssProps: { - "float": "cssFloat" - }, + cssProps: {}, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { @@ -6429,7 +6898,7 @@ // Make sure that we're working with the right name var ret, type, hooks, - origName = jQuery.camelCase( name ), + origName = camelCase( name ), isCustomProp = rcustomProp.test( name ), style = elem.style; @@ -6461,7 +6930,9 @@ } // If a number was passed in, add the unit (except for certain CSS properties) - if ( type === "number" ) { + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } @@ -6497,7 +6968,7 @@ css: function( elem, name, extra, styles ) { var val, num, hooks, - origName = jQuery.camelCase( name ), + origName = camelCase( name ), isCustomProp = rcustomProp.test( name ); // Make sure that we're working with the right name. We don't @@ -6535,8 +7006,8 @@ } } ); -jQuery.each( [ "height", "width" ], function( i, name ) { - jQuery.cssHooks[ name ] = { +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { @@ -6552,29 +7023,52 @@ // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { - return getWidthOrHeight( elem, name, extra ); + return getWidthOrHeight( elem, dimension, extra ); } ) : - getWidthOrHeight( elem, name, extra ); + getWidthOrHeight( elem, dimension, extra ); } }, set: function( elem, value, extra ) { var matches, - styles = extra && getStyles( elem ), - subtract = extra && augmentWidthOrHeight( - elem, - name, - extra, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - styles + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 ); + } // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { - elem.style[ name ] = value; - value = jQuery.css( elem, name ); + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); } return setPositiveNumber( elem, value, subtract ); @@ -6618,7 +7112,7 @@ } }; - if ( !rmargin.test( prefix ) ) { + if ( prefix !== "margin" ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); @@ -6728,9 +7222,9 @@ // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && - ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || - jQuery.cssHooks[ tween.prop ] ) ) { + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; @@ -6789,7 +7283,7 @@ window.setTimeout( function() { fxNow = undefined; } ); - return ( fxNow = jQuery.now() ); + return ( fxNow = Date.now() ); } // Generate parameters to create a standard animation @@ -6893,9 +7387,10 @@ // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { - // Support: IE <=9 - 11, Edge 12 - 13 + // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade @@ -7003,7 +7498,7 @@ // camelCase, specialEasing and expand cssHook pass for ( index in props ) { - name = jQuery.camelCase( index ); + name = camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( Array.isArray( value ) ) { @@ -7128,9 +7623,9 @@ for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { - if ( jQuery.isFunction( result.stop ) ) { + if ( isFunction( result.stop ) ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - jQuery.proxy( result.stop, result ); + result.stop.bind( result ); } return result; } @@ -7138,7 +7633,7 @@ jQuery.map( props, createTween, animation ); - if ( jQuery.isFunction( animation.opts.start ) ) { + if ( isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } @@ -7171,7 +7666,7 @@ }, tweener: function( props, callback ) { - if ( jQuery.isFunction( props ) ) { + if ( isFunction( props ) ) { callback = props; props = [ "*" ]; } else { @@ -7203,9 +7698,9 @@ jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || - jQuery.isFunction( speed ) && speed, + isFunction( speed ) && speed, duration: speed, - easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + easing: fn && easing || easing && !isFunction( easing ) && easing }; // Go to the end state if fx are off @@ -7232,7 +7727,7 @@ opt.old = opt.complete; opt.complete = function() { - if ( jQuery.isFunction( opt.old ) ) { + if ( isFunction( opt.old ) ) { opt.old.call( this ); } @@ -7284,7 +7779,7 @@ clearQueue = type; type = undefined; } - if ( clearQueue && type !== false ) { + if ( clearQueue ) { this.queue( type || "fx", [] ); } @@ -7367,7 +7862,7 @@ } } ); -jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? @@ -7396,7 +7891,7 @@ i = 0, timers = jQuery.timers; - fxNow = jQuery.now(); + fxNow = Date.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; @@ -7588,7 +8083,7 @@ } }; -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { @@ -7749,7 +8244,7 @@ // Strip and collapse whitespace according to HTML spec - // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); @@ -7760,20 +8255,30 @@ return elem.getAttribute && elem.getAttribute( "class" ) || ""; } +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + jQuery.fn.extend( { addClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; - if ( jQuery.isFunction( value ) ) { + if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } - if ( typeof value === "string" && value ) { - classes = value.match( rnothtmlwhite ) || []; + classes = classesToArray( value ); + if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); @@ -7802,7 +8307,7 @@ var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; - if ( jQuery.isFunction( value ) ) { + if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); @@ -7812,9 +8317,9 @@ return this.attr( "class", "" ); } - if ( typeof value === "string" && value ) { - classes = value.match( rnothtmlwhite ) || []; + classes = classesToArray( value ); + if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); @@ -7844,13 +8349,14 @@ }, toggleClass: function( value, stateVal ) { - var type = typeof value; + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); - if ( typeof stateVal === "boolean" && type === "string" ) { + if ( typeof stateVal === "boolean" && isValidValue ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } - if ( jQuery.isFunction( value ) ) { + if ( isFunction( value ) ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), @@ -7862,12 +8368,12 @@ return this.each( function() { var className, i, self, classNames; - if ( type === "string" ) { + if ( isValidValue ) { // Toggle individual class names i = 0; self = jQuery( this ); - classNames = value.match( rnothtmlwhite ) || []; + classNames = classesToArray( value ); while ( ( className = classNames[ i++ ] ) ) { @@ -7926,7 +8432,7 @@ jQuery.fn.extend( { val: function( value ) { - var hooks, ret, isFunction, + var hooks, ret, valueIsFunction, elem = this[ 0 ]; if ( !arguments.length ) { @@ -7955,7 +8461,7 @@ return; } - isFunction = jQuery.isFunction( value ); + valueIsFunction = isFunction( value ); return this.each( function( i ) { var val; @@ -7964,7 +8470,7 @@ return; } - if ( isFunction ) { + if ( valueIsFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; @@ -8106,18 +8612,24 @@ // Return jQuery for attributes-only inclusion -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { - var i, cur, tmp, bubbleType, ontype, handle, special, + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [ elem || document ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - cur = tmp = elem = elem || document; + cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { @@ -8169,7 +8681,7 @@ // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { @@ -8189,13 +8701,15 @@ // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - + lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); @@ -8221,7 +8735,7 @@ // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; @@ -8232,7 +8746,17 @@ // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + jQuery.event.triggered = undefined; if ( tmp ) { @@ -8278,31 +8802,6 @@ } ); -jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup contextmenu" ).split( " " ), - function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; -} ); - -jQuery.fn.extend( { - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -} ); - - - - -support.focusin = "onfocusin" in window; - - // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 @@ -8321,7 +8820,10 @@ jQuery.event.special[ fix ] = { setup: function() { - var doc = this.ownerDocument || this, + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { @@ -8330,7 +8832,7 @@ dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { - var doc = this.ownerDocument || this, + var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { @@ -8346,7 +8848,7 @@ } var location = window.location; -var nonce = jQuery.now(); +var nonce = { guid: Date.now() }; var rquery = ( /\?/ ); @@ -8404,7 +8906,7 @@ } } ); - } else if ( !traditional && jQuery.type( obj ) === "object" ) { + } else if ( !traditional && toType( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { @@ -8426,7 +8928,7 @@ add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value - var value = jQuery.isFunction( valueOrFunction ) ? + var value = isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction; @@ -8434,6 +8936,10 @@ encodeURIComponent( value == null ? "" : value ); }; + if ( a == null ) { + return ""; + } + // If an array was passed in, assume that it is an array of form elements. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { @@ -8474,7 +8980,7 @@ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ) - .map( function( i, elem ) { + .map( function( _i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { @@ -8544,7 +9050,7 @@ i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - if ( jQuery.isFunction( func ) ) { + if ( isFunction( func ) ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { @@ -8936,12 +9442,14 @@ if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); } } - match = responseHeaders[ key.toLowerCase() ]; + match = responseHeaders[ key.toLowerCase() + " " ]; } - return match == null ? null : match; + return match == null ? null : match.join( ", " ); }, // Raw string @@ -9016,7 +9524,7 @@ if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); - // Support: IE <=8 - 11, Edge 12 - 13 + // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { @@ -9074,8 +9582,8 @@ // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); - // If data is available, append data to url - if ( s.data ) { + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry @@ -9085,7 +9593,8 @@ // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) @@ -9218,6 +9727,11 @@ response = ajaxHandleResponses( s, jqXHR, responses ); } + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); @@ -9308,11 +9822,11 @@ } } ); -jQuery.each( [ "get", "post" ], function( i, method ) { +jQuery.each( [ "get", "post" ], function( _i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted - if ( jQuery.isFunction( data ) ) { + if ( isFunction( data ) ) { type = type || callback; callback = data; data = undefined; @@ -9329,8 +9843,17 @@ }; } ); +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); -jQuery._evalUrl = function( url ) { + +jQuery._evalUrl = function( url, options, doc ) { return jQuery.ajax( { url: url, @@ -9340,7 +9863,16 @@ cache: true, async: false, global: false, - "throws": true + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } } ); }; @@ -9350,7 +9882,7 @@ var wrap; if ( this[ 0 ] ) { - if ( jQuery.isFunction( html ) ) { + if ( isFunction( html ) ) { html = html.call( this[ 0 ] ); } @@ -9376,7 +9908,7 @@ }, wrapInner: function( html ) { - if ( jQuery.isFunction( html ) ) { + if ( isFunction( html ) ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); @@ -9396,10 +9928,10 @@ }, wrap: function( html ) { - var isFunction = jQuery.isFunction( html ); + var htmlIsFunction = isFunction( html ); return this.each( function( i ) { - jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, @@ -9491,7 +10023,8 @@ return function() { if ( callback ) { callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); @@ -9531,7 +10064,7 @@ // Listen to events xhr.onload = callback(); - errorCallback = xhr.onerror = callback( "error" ); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); // Support: IE 9 only // Use onreadystatechange to replace onabort @@ -9622,24 +10155,21 @@ // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { - // This transport only deals with cross domain requests - if ( s.crossDomain ) { + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { var script, callback; return { send: function( _, complete ) { - script = jQuery( "<script>" ).prop( { - charset: s.scriptCharset, - src: s.url - } ).on( - "load error", - callback = function( evt ) { + script = jQuery( "<script>" ) + .attr( s.scriptAttrs || {} ) + .prop( { charset: s.scriptCharset, src: s.url } ) + .on( "load error", callback = function( evt ) { script.remove(); callback = null; if ( evt ) { complete( evt.type === "error" ? 404 : 200, evt.type ); } - } - ); + } ); // Use native DOM manipulation to avoid our domManip AJAX trickery document.head.appendChild( script[ 0 ] ); @@ -9663,7 +10193,7 @@ jQuery.ajaxSetup( { jsonp: "callback", jsonpCallback: function() { - var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); this[ callback ] = true; return callback; } @@ -9685,7 +10215,7 @@ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { // Get callback name, remembering preexisting value associated with it - callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback; @@ -9736,7 +10266,7 @@ } // Call if it was a function and we have a response - if ( responseContainer && jQuery.isFunction( overwritten ) ) { + if ( responseContainer && isFunction( overwritten ) ) { overwritten( responseContainer[ 0 ] ); } @@ -9828,7 +10358,7 @@ } // If it's a function - if ( jQuery.isFunction( params ) ) { + if ( isFunction( params ) ) { // We assume that it's the callback callback = params; @@ -9880,23 +10410,6 @@ -// Attach a bunch of functions for handling common AJAX events -jQuery.each( [ - "ajaxStart", - "ajaxStop", - "ajaxComplete", - "ajaxError", - "ajaxSuccess", - "ajaxSend" -], function( i, type ) { - jQuery.fn[ type ] = function( fn ) { - return this.on( type, fn ); - }; -} ); - - - - jQuery.expr.pseudos.animated = function( elem ) { return jQuery.grep( jQuery.timers, function( fn ) { return elem === fn.elem; @@ -9936,7 +10449,7 @@ curLeft = parseFloat( curCSSLeft ) || 0; } - if ( jQuery.isFunction( options ) ) { + if ( isFunction( options ) ) { // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); @@ -9953,12 +10466,20 @@ options.using.call( elem, props ); } else { + if ( typeof props.top === "number" ) { + props.top += "px"; + } + if ( typeof props.left === "number" ) { + props.left += "px"; + } curElem.css( props ); } } }; jQuery.fn.extend( { + + // offset() relates an element's border box to the document origin offset: function( options ) { // Preserve chaining for setter @@ -9970,7 +10491,7 @@ } ); } - var doc, docElem, rect, win, + var rect, win, elem = this[ 0 ]; if ( !elem ) { @@ -9985,50 +10506,52 @@ return { top: 0, left: 0 }; } + // Get document-relative position by adding viewport scroll to viewport-relative gBCR rect = elem.getBoundingClientRect(); - - doc = elem.ownerDocument; - docElem = doc.documentElement; - win = doc.defaultView; - + win = elem.ownerDocument.defaultView; return { - top: rect.top + win.pageYOffset - docElem.clientTop, - left: rect.left + win.pageXOffset - docElem.clientLeft + top: rect.top + win.pageYOffset, + left: rect.left + win.pageXOffset }; }, + // position() relates an element's margin box to its offset parent's padding box + // This corresponds to the behavior of CSS absolute positioning position: function() { if ( !this[ 0 ] ) { return; } - var offsetParent, offset, + var offsetParent, offset, doc, elem = this[ 0 ], parentOffset = { top: 0, left: 0 }; - // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, - // because it is its only offset parent + // position:fixed elements are offset from the viewport, which itself always has zero offset if ( jQuery.css( elem, "position" ) === "fixed" ) { - // Assume getBoundingClientRect is there when computed position is fixed + // Assume position:fixed implies availability of getBoundingClientRect offset = elem.getBoundingClientRect(); } else { - - // Get *real* offsetParent - offsetParent = this.offsetParent(); - - // Get correct offsets offset = this.offset(); - if ( !nodeName( offsetParent[ 0 ], "html" ) ) { - parentOffset = offsetParent.offset(); - } - // Add offsetParent borders - parentOffset = { - top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ), - left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) - }; + // Account for the *real* offset parent, which can be the document or its root element + // when a statically positioned element is identified + doc = elem.ownerDocument; + offsetParent = elem.offsetParent || doc.documentElement; + while ( offsetParent && + ( offsetParent === doc.body || offsetParent === doc.documentElement ) && + jQuery.css( offsetParent, "position" ) === "static" ) { + + offsetParent = offsetParent.parentNode; + } + if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { + + // Incorporate borders into its offset, since they are outside its content origin + parentOffset = jQuery( offsetParent ).offset(); + parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); + parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); + } } // Subtract parent offsets and element margins @@ -10070,7 +10593,7 @@ // Coalesce documents and windows var win; - if ( jQuery.isWindow( elem ) ) { + if ( isWindow( elem ) ) { win = elem; } else if ( elem.nodeType === 9 ) { win = elem.defaultView; @@ -10099,7 +10622,7 @@ // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 // getComputedStyle returns percent when specified for top/left/bottom/right; // rather than make the css module depend on the offset module, just check for it here -jQuery.each( [ "top", "left" ], function( i, prop ) { +jQuery.each( [ "top", "left" ], function( _i, prop ) { jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, function( elem, computed ) { if ( computed ) { @@ -10128,7 +10651,7 @@ return access( this, function( elem, type, value ) { var doc; - if ( jQuery.isWindow( elem ) ) { + if ( isWindow( elem ) ) { // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) return funcName.indexOf( "outer" ) === 0 ? @@ -10162,6 +10685,22 @@ } ); +jQuery.each( [ + "ajaxStart", + "ajaxStop", + "ajaxComplete", + "ajaxError", + "ajaxSuccess", + "ajaxSend" +], function( _i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +} ); + + + + jQuery.fn.extend( { bind: function( types, data, fn ) { @@ -10180,9 +10719,64 @@ return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } } ); +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup contextmenu" ).split( " " ), + function( _i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + } ); + + + + +// Support: Android <=4.0 only +// Make sure we trim BOM and NBSP +var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +// Bind a function to a context, optionally partially applying any +// arguments. +// jQuery.proxy is deprecated to promote standards (specifically Function#bind) +// However, it is not slated for removal any time soon +jQuery.proxy = function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; +}; + jQuery.holdReady = function( hold ) { if ( hold ) { jQuery.readyWait++; @@ -10193,7 +10787,32 @@ jQuery.isArray = Array.isArray; jQuery.parseJSON = JSON.parse; jQuery.nodeName = nodeName; +jQuery.isFunction = isFunction; +jQuery.isWindow = isWindow; +jQuery.camelCase = camelCase; +jQuery.type = toType; +jQuery.now = Date.now; + +jQuery.isNumeric = function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); +}; + +jQuery.trim = function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); +}; @@ -10242,7 +10861,7 @@ // Expose jQuery and $ identifiers, even in AMD // (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) -if ( !noGlobal ) { +if ( typeof noGlobal === "undefined" ) { window.jQuery = window.$ = jQuery; }
diff --git a/third_party/mako/doc/_static/jquery.js b/third_party/mako/doc/_static/jquery.js index 644d35e2..b061403 100644 --- a/third_party/mako/doc/_static/jquery.js +++ b/third_party/mako/doc/_static/jquery.js
@@ -1,4 +1,2 @@ -/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), -a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), -null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(D).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var j,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function Se(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function ke(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Ae(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,Ce)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click",Ce),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Ae(this,e,Se),!1},trigger:function(){return Ae(this,e),!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return ke(this,e,t,n,r)},one:function(e,t,n,r){return ke(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){S.event.remove(this,e,n,t)})}});var Ne=/<script|<style|<link/i,De=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function Pe(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&De.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,He),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(je,""),u,l))}return n}function Re(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Me=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Ie=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},We=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Fe=new RegExp(ne.join("|"),"i");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||Ie(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Me.test(a)&&Fe.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function $e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px",t.style.height="1px",n.style.height="9px",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}}))}();var _e=["Webkit","Moz","ms"],ze=E.createElement("div").style,Ue={};function Xe(e){var t=S.cssProps[e]||Ue[e];return t||(e in ze?e:Ue[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=_e.length;while(n--)if((e=_e[n]+t)in ze)return e}(e)||e)}var Ve=/^(none|table(?!-c[ea]).+)/,Ge=/^--/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):We(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Ie(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=$e(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ct(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",y.checkOn=""!==rt.value,y.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",y.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(P)||[]).join(" ")}function yt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,yt(this)))});if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,yt(this)))});if(!arguments.length)return this.attr("class","");if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,yt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=mt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=yt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+vt(yt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:vt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||S.error("Invalid XML: "+e),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function Dt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):Dt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)Dt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)Dt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var jt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Bt(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function $t(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,S.ajaxSettings),t):$t(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Bt(Rt,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Ot.test(v.type),f=v.url.replace(qt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(jt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Et.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+It+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Bt(Mt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();y.cors=!!zt&&"withCredentials"in zt,y.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(y.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=vt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
diff --git a/third_party/mako/doc/_static/language_data.js b/third_party/mako/doc/_static/language_data.js index 5266fb19..0e7dc7e 100644 --- a/third_party/mako/doc/_static/language_data.js +++ b/third_party/mako/doc/_static/language_data.js
@@ -5,7 +5,7 @@ * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */
diff --git a/third_party/mako/doc/_static/pygments.css b/third_party/mako/doc/_static/pygments.css index 20c4814..de7af262 100644 --- a/third_party/mako/doc/_static/pygments.css +++ b/third_party/mako/doc/_static/pygments.css
@@ -1,5 +1,10 @@ +pre { line-height: 125%; } +td.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; } +span.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; } +td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } -.highlight { background: #eeffcc; } +.highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */
diff --git a/third_party/mako/doc/_static/searchtools.js b/third_party/mako/doc/_static/searchtools.js index 6031f991..6fc9e7f 100644 --- a/third_party/mako/doc/_static/searchtools.js +++ b/third_party/mako/doc/_static/searchtools.js
@@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for the full-text search. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -59,10 +59,15 @@ _pulse_status : -1, htmlToText : function(htmlString) { - var htmlElement = document.createElement('span'); - htmlElement.innerHTML = htmlString; - $(htmlElement).find('.headerlink').remove(); - docContent = $(htmlElement).find('[role=main]')[0]; + var virtualDocument = document.implementation.createHTMLDocument('virtual'); + var htmlElement = $(htmlString, virtualDocument); + htmlElement.find('.headerlink').remove(); + docContent = htmlElement.find('[role=main]')[0]; + if(docContent === undefined) { + console.warn("Content block not found. Sphinx search tries to obtain it " + + "via '[role=main]'. Could you check your theme or template."); + return ""; + } return docContent.textContent || docContent.innerText; }, @@ -161,8 +166,7 @@ objectterms.push(tmp[i].toLowerCase()); } - if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) || - tmp[i] === "") { + if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") { // skip this "word" continue; } @@ -245,7 +249,9 @@ if (results.length) { var item = results.pop(); var listItem = $('<li style="display:none"></li>'); - if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { + var requestUrl = ""; + var linkUrl = ""; + if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') { // dirhtml builder var dirname = item[0] + '/'; if (dirname.match(/\/index\/$/)) { @@ -253,15 +259,17 @@ } else if (dirname == 'index/') { dirname = ''; } - listItem.append($('<a/>').attr('href', - DOCUMENTATION_OPTIONS.URL_ROOT + dirname + - highlightstring + item[2]).html(item[1])); + requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname; + linkUrl = requestUrl; + } else { // normal html builders - listItem.append($('<a/>').attr('href', - item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + - highlightstring + item[2]).html(item[1])); + requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX; + linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX; } + listItem.append($('<a/>').attr('href', + linkUrl + + highlightstring + item[2]).html(item[1])); if (item[3]) { listItem.append($('<span> (' + item[3] + ')</span>')); Search.output.append(listItem); @@ -269,7 +277,7 @@ displayNextItem(); }); } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { - $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX, + $.ajax({url: requestUrl, dataType: "text", complete: function(jqxhr, textstatus) { var data = jqxhr.responseText; @@ -424,7 +432,7 @@ for (j = 0; j < _files.length; j++) { file = _files[j]; if (!(file in scoreMap)) - scoreMap[file] = {} + scoreMap[file] = {}; scoreMap[file][word] = o.score; } }); @@ -432,7 +440,7 @@ // create the mapping for (j = 0; j < files.length; j++) { file = files[j]; - if (file in fileMap) + if (file in fileMap && fileMap[file].indexOf(word) === -1) fileMap[file].push(word); else fileMap[file] = [word];
diff --git a/third_party/mako/doc/_static/sphinx_paramlinks.css b/third_party/mako/doc/_static/sphinx_paramlinks.css index be75d7a..27a1c02 100644 --- a/third_party/mako/doc/_static/sphinx_paramlinks.css +++ b/third_party/mako/doc/_static/sphinx_paramlinks.css
@@ -1,7 +1,9 @@ -a.paramlink { +li > a.paramlink { visibility: hidden; } -li:hover > a.paramlink { + +p:hover > a.headerlink, p:hover > a.paramlink, li:hover > a.paramlink, li:hover > a.headerlink { visibility: visible; } +
diff --git a/third_party/mako/doc/build/changelog.rst b/third_party/mako/doc/build/changelog.rst index acbd7bd..5254cf7 100644 --- a/third_party/mako/doc/build/changelog.rst +++ b/third_party/mako/doc/build/changelog.rst
@@ -1,7 +1,128 @@ + ========= Changelog ========= +1.1 +=== + +.. changelog:: + :version: 1.1.4 + :released: Thu Jan 14 2021 + + .. change:: + :tags: bug, py3k + :tickets: 328 + + Fixed Python deprecation issues related to module importing, as well as + file access within the Lingua plugin, for deprecated APIs that began to + emit warnings under Python 3.10. Pull request courtesy Petr Viktorin. + +.. changelog:: + :version: 1.1.3 + :released: Fri May 29 2020 + + .. change:: + :tags: bug, templates + :tickets: 267 + + The default template encoding is now utf-8. Previously, the encoding was + "ascii", which was standard throughout Python 2. This allows that + "magic encoding comment" for utf-8 templates is no longer required. + + +.. changelog:: + :version: 1.1.2 + :released: Sun Mar 1 2020 + + .. change:: + :tags: feature, commands + :tickets: 283 + + Added --output-file argument to the Mako command line runner, which allows + a specific output file to be selected. Pull request courtesy Björn + Dahlgren. + +.. changelog:: + :version: 1.1.1 + :released: Mon Jan 20 2020 + + .. change:: + :tags: bug, py3k + :tickets: 310 + + Replaced usage of the long-superseded "parser.suite" module in the + mako.util package for parsing the python magic encoding comment with the + "ast.parse" function introduced many years ago in Python 2.5, as + "parser.suite" is emitting deprecation warnings in Python 3.9. + + + + .. change:: + :tags: bug, ext + :tickets: 304 + + Added "babel" and "lingua" dependency entries to the setuptools entrypoints + for the babel and lingua extensions, so that pkg_resources can check that + these extra dependencies are available, raising an informative + exception if not. Pull request courtesy sinoroc. + + + +.. changelog:: + :version: 1.1.0 + :released: Thu Aug 1 2019 + + .. change:: + :tags: bug, py3k, windows + :tickets: 301 + + Replaced usage of time.clock() on windows as well as time.time() elsewhere + for microsecond timestamps with timeit.default_timer(), as time.clock() is + being removed in Python 3.8. Pull request courtesy Christoph Reiter. + + + .. change:: + :tags: bug, py3k + :tickets: 295 + + Replaced usage of ``inspect.getfullargspec()`` with the vendored version + used by SQLAlchemy, Alembic to avoid future deprecation warnings. Also + cleans up an additional version of the same function that's apparently + been floating around for some time. + + + .. change:: + :tags: changed, setup + :tickets: 303 + + Removed the "python setup.py test" feature in favor of a straight run of + "tox". Per Pypa / pytest developers, "setup.py" commands are in general + headed towards deprecation in favor of tox. The tox.ini script has been + updated such that running "tox" with no arguments will perform a single run + of the test suite against the default installed Python interpreter. + + .. seealso:: + + https://github.com/pypa/setuptools/issues/1684 + + https://github.com/pytest-dev/pytest/issues/5534 + + .. change:: + :tags: changed, py3k, installer + :tickets: 249 + + Mako 1.1 now supports Python versions: + + * 2.7 + * 3.4 and higher + + This includes that setup.py no longer includes any conditionals, allowing + for a pure Python wheel build, however this is not necessarily part of the + Pypi release process as of yet. The test suite also raises for Python + deprecation warnings. + + 1.0 === @@ -65,7 +186,7 @@ :released: Fri May 31 2019 .. change:: - :tags: change + :tags: changed Updated for additional project metadata in setup.py. Additionally, the code has been reformatted using Black and zimports. @@ -1016,7 +1137,7 @@ :tags: :tickets: 148 - Fixed missing **extra collection in + Fixed missing \**extra collection in setup.py which prevented setup.py from running 2to3 on install. @@ -1269,7 +1390,7 @@ The <%page args> tag can now be used in a base inheriting template - the full set of render() arguments are passed down through the inherits - chain. Undeclared arguments go into **pageargs + chain. Undeclared arguments go into \**pageargs as usual. .. change:: @@ -1624,16 +1745,16 @@ added "attr" accessor to namespaces. Returns attributes configured as module level attributes, i.e. - within <%! %> sections. i.e.: + within <%! %> sections. i.e.:: - # somefile.html - <%! - foo = 27 - %> + # somefile.html + <%! + foo = 27 + %> - # some other template - <%namespace name="myns" file="somefile.html"/> - ${myns.attr.foo} + # some other template + <%namespace name="myns" file="somefile.html"/> + ${myns.attr.foo} The slight backwards incompatibility here is, you can't have namespace defs named "attr" since the @@ -2027,7 +2148,7 @@ :tickets: <%include> plus arguments is also programmatically available via - self.include_file(<filename>, **kwargs) + self.include_file(<filename>, \**kwargs) .. change:: :tags:
diff --git a/third_party/mako/doc/build/conf.py b/third_party/mako/doc/build/conf.py index 4e3e2bb..8c3b1ab7 100644 --- a/third_party/mako/doc/build/conf.py +++ b/third_party/mako/doc/build/conf.py
@@ -10,28 +10,35 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('../..')) -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath("../..")) +sys.path.insert(0, os.path.abspath(".")) -import mako +if True: + import mako # noqa + # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', +# extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', # 'sphinx.ext.doctest', 'builder.builders'] -extensions = ['sphinx.ext.autodoc', - 'changelog', 'sphinx_paramlinks', 'zzzeeksphinx'] +extensions = [ + "sphinx.ext.autodoc", + "changelog", + "sphinx_paramlinks", + "zzzeeksphinx", +] changelog_render_ticket = "https://github.com/sqlalchemy/mako/issues/%s" @@ -40,8 +47,19 @@ "github": "https://github.com/sqlalchemy/mako/pull/%s", } +# tags to sort on inside of sections +changelog_sections = [ + "changed", + "feature", + "bug", + "usecase", + "moved", + "removed", +] + + # Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] +templates_path = ["templates"] nitpicky = True @@ -51,17 +69,17 @@ site_adapter_py = "docs_adapter.py" # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'Mako' -copyright = u'the Mako authors and contributors' +project = u"Mako" +copyright = u"the Mako authors and contributors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -70,224 +88,225 @@ # The short X.Y version. version = mako.__version__ # The full version, including alpha/beta/rc tags. -release = "1.0.14" +release = "1.1.4" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['build'] +exclude_patterns = ["build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'zsmako' +html_theme = "zsmako" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. -html_style = 'default.css' +html_style = "default.css" # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". html_title = "%s %s Documentation" % (project, release) # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['static'] +html_static_path = ["static"] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -html_last_updated_fmt = '%m/%d/%Y %H:%M:%S' +html_last_updated_fmt = "%m/%d/%Y %H:%M:%S" # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. html_domain_indices = False # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, the reST sources are included in the HTML build as _sources/<name>. -#html_copy_source = True +# html_copy_source = True html_copy_source = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True html_show_sourcelink = False # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a <link> tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Makodoc' +htmlhelp_basename = "Makodoc" -#autoclass_content = 'both' +# autoclass_content = 'both' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +# latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' +# latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'mako_%s.tex' % release.replace('.', '_'), u'Mako Documentation', - u'Mike Bayer', 'manual'), + ( + "index", + "mako_%s.tex" % release.replace(".", "_"), + u"Mako Documentation", + u"Mike Bayer", + "manual", + ) ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Additional stuff for the LaTeX preamble. # sets TOC depth to 2. -latex_preamble = '\setcounter{tocdepth}{3}' +latex_preamble = r"\setcounter{tocdepth}{3}" # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True -#latex_elements = { +# latex_elements = { # 'papersize': 'letterpaper', # 'pointsize': '10pt', -#} +# } # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'mako', u'Mako Documentation', - [u'Mako authors'], 1) -] +man_pages = [("index", "mako", u"Mako Documentation", [u"Mako authors"], 1)] # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. -epub_title = u'Mako' -epub_author = u'Mako authors' -epub_publisher = u'Mako authors' -epub_copyright = u'Mako authors' +epub_title = u"Mako" +epub_author = u"Mako authors" +epub_publisher = u"Mako authors" +epub_copyright = u"Mako authors" # The language of the text. It defaults to the language option # or en if the language is not set. -#epub_language = '' +# epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' +# epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. -#epub_identifier = '' +# epub_identifier = '' # A unique identification for the text. -#epub_uid = '' +# epub_uid = '' # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. -#epub_pre_files = [] +# epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. -#epub_post_files = [] +# epub_post_files = [] # A list of files that should not be packed into the epub file. -#epub_exclude_files = [] +# epub_exclude_files = [] # The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 +# epub_tocdepth = 3 # Allow duplicate toc entries. -#epub_tocdup = True - +# epub_tocdup = True
diff --git a/third_party/mako/doc/build/unicode.rst b/third_party/mako/doc/build/unicode.rst index 1ba364e..2f77f6a 100644 --- a/third_party/mako/doc/build/unicode.rst +++ b/third_party/mako/doc/build/unicode.rst
@@ -4,6 +4,9 @@ The Unicode Chapter =================== +.. note:: this chapter was written many years ago and is very Python-2 + centric. As of Mako 1.1.3, the default template encoding is ``utf-8``. + The Python language supports two ways of representing what we know as "strings", i.e. series of characters. In Python 2, the two types are ``string`` and ``unicode``, and in Python 3 they are @@ -89,35 +92,23 @@ Specifying the Encoding of a Template File ========================================== -This is the most basic encoding-related setting, and it is -equivalent to Python's "magic encoding comment", as described in -`pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_. Any -template that contains non-ASCII characters requires that this -comment be present so that Mako can decode to unicode (and also -make usage of Python's AST parsing services). Mako's lexer will -use this encoding in order to convert the template source into a -``unicode`` object before continuing its parsing: +.. versionchanged:: 1.1.3 + + As of Mako 1.1.3, the default template encoding is "utf-8". Previously, a + Python "magic encoding comment" was required for templates that were not + using ASCII. + +Mako templates support Python's "magic encoding comment" syntax +described in `pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_: .. sourcecode:: mako ## -*- coding: utf-8 -*- - Alors vous imaginez ma surprise, au lever du jour, quand + Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » -For the picky, the regular expression used is derived from that -of the above mentioned pep: - -.. sourcecode:: python - - #.*coding[:=]\s*([-\w.]+).*\n - -The lexer will convert to unicode in all cases, so that if any -characters exist in the template that are outside of the -specified encoding (or the default of ``ascii``), the error will -be immediate. - As an alternative, the template encoding can be specified programmatically to either :class:`.Template` or :class:`.TemplateLookup` via the ``input_encoding`` parameter:
diff --git a/third_party/mako/doc/build/usage.rst b/third_party/mako/doc/build/usage.rst index ceb8d41..c439c35 100644 --- a/third_party/mako/doc/build/usage.rst +++ b/third_party/mako/doc/build/usage.rst
@@ -355,7 +355,7 @@ Pygments -------- -A `Pygments <http://pygments.pocoo.org>`_-compatible syntax +A `Pygments <https://pygments.org/>`_-compatible syntax highlighting module is included under :mod:`mako.ext.pygmentplugin`. This module is used in the generation of Mako documentation and also contains various `setuptools` entry points under the heading
diff --git a/third_party/mako/doc/caching.html b/third_party/mako/doc/caching.html index 927f4cd1..035a177a 100644 --- a/third_party/mako/doc/caching.html +++ b/third_party/mako/doc/caching.html
@@ -12,7 +12,7 @@ Caching — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Changelog" href="changelog.html" /> <link rel="prev" title="The Unicode Chapter" href="unicode.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Caching @@ -166,7 +166,7 @@ </div> <p>The above template, after being executed the first time, will store its content within a cache that by default is scoped -within memory. Subsequent calls to the template’s <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> +within memory. Subsequent calls to the template’s <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> method will return content directly from the cache. When the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object itself falls out of scope, its corresponding cache is garbage collected along with the template.</p> @@ -225,7 +225,7 @@ e.g.:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span> <span class="n">directories</span><span class="o">=</span><span class="s1">'/path/to/templates'</span><span class="p">,</span> - <span class="n">cache_enabled</span> <span class="o">=</span> <span class="bp">False</span> + <span class="n">cache_enabled</span> <span class="o">=</span> <span class="kc">False</span> <span class="p">)</span></pre></div> </div> </li> @@ -371,7 +371,7 @@ <span class="n">template</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">invalidate</span><span class="p">(</span><span class="s1">'somekey'</span><span class="p">)</span></pre></div> </div> <p>You can access any special method or attribute of the <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">CacheImpl</span></code></a> -itself using the <a class="reference internal" href="#mako.cache.Cache.impl" title="mako.cache.Cache.impl"><code class="xref py py-attr docutils literal notranslate"><span class="pre">impl</span></code></a> attribute:</p> +itself using the <a class="reference internal" href="#mako.cache.Cache.impl" title="mako.cache.Cache.impl"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Cache.impl</span></code></a> attribute:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">template</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">impl</span><span class="o">.</span><span class="n">do_something_special</span><span class="p">()</span></pre></div> </div> <p>Note that using implementation-specific methods will mean you can’t @@ -414,14 +414,14 @@ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="k">def</span> <span class="nf">invalidate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> - <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> + <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="c1"># optional - register the class locally</span> <span class="n">register_plugin</span><span class="p">(</span><span class="s2">"simple"</span><span class="p">,</span> <span class="vm">__name__</span><span class="p">,</span> <span class="s2">"SimpleCacheImpl"</span><span class="p">)</span></pre></div> </div> <p>Enabling the above plugin in a template would look like:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"mytemplate"</span><span class="p">,</span> - <span class="nb">file</span><span class="o">=</span><span class="s2">"mytemplate.html"</span><span class="p">,</span> + <span class="n">file</span><span class="o">=</span><span class="s2">"mytemplate.html"</span><span class="p">,</span> <span class="n">cache_impl</span><span class="o">=</span><span class="s1">'simple'</span><span class="p">)</span></pre></div> </div> <div class="section" id="guidelines-for-writing-cache-plugins"> @@ -466,9 +466,34 @@ </div> <div class="section" id="api-reference"> <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2> -<dl class="class"> +<table class="longtable docutils"> +<colgroup> +<col style="width: 10%" /> +<col style="width: 90%" /> +</colgroup> +<thead> +<tr class="row-odd"><th class="head">Object Name</th> +<th class="head">Description</th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.ext.beaker_cache.BeakerCacheImpl"><code class="sig-name descname">BeakerCacheImpl</code></a></p></td> +<td><p>Bases: <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.cache.CacheImpl</span></code></a></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.cache.Cache"><code class="sig-name descname">Cache</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.cache.CacheImpl"><code class="sig-name descname">CacheImpl</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.cache.register_plugin"><code class="sig-name descname">register_plugin</code></a></p></td> +<td></td> +</tr> +</tbody> +</table> +<dl class="py class"> <dt id="mako.cache.Cache"> -<em class="property">class </em><code class="sig-prename descclassname">mako.cache.</code><code class="sig-name descname">Cache</code><span class="sig-paren">(</span><em class="sig-param">template</em>, <em class="sig-param">*args</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.cache.</code><code class="sig-name descname">Cache</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">template</span></em>, <em class="sig-param"><span class="o">*</span><span class="n">args</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>Represents a data content cache made available to the module space of a specific <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object.</p> @@ -484,9 +509,9 @@ <p>The construction of a <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><code class="xref py py-class docutils literal notranslate"><span class="pre">Cache</span></code></a> is part of the mechanics of a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>, and programmatic access to this cache is typically via the <code class="xref py py-attr docutils literal notranslate"><span class="pre">Template.cache</span></code> attribute.</p> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.get"> -<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.get" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.get" title="Permalink to this definition">¶</a></dt> <dd><p>Retrieve a value from the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -501,16 +526,16 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.get_or_create"> -<code class="sig-name descname">get_or_create</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">creation_function</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.get_or_create" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">get_or_create</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">creation_function</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.get_or_create" title="Permalink to this definition">¶</a></dt> <dd><p>Retrieve a value from the cache, using the given creation function to generate a new value.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.cache.Cache.id"> -<code class="sig-name descname">id</code><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.id" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">id</code><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.id" title="Permalink to this definition">¶</a></dt> <dd><p>Return the ‘id’ that identifies this cache.</p> <p>This is a value that should be globally unique to the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> associated with this cache, and can @@ -518,17 +543,17 @@ for data specific to this template.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.cache.Cache.impl"> -<code class="sig-name descname">impl</code><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.impl" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">impl</code><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.impl" title="Permalink to this definition">¶</a></dt> <dd><p>Provide the <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">CacheImpl</span></code></a> in use by this <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><code class="xref py py-class docutils literal notranslate"><span class="pre">Cache</span></code></a>.</p> <p>This accessor allows a <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">CacheImpl</span></code></a> with additional methods beyond that of <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><code class="xref py py-class docutils literal notranslate"><span class="pre">Cache</span></code></a> to be used programmatically.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.invalidate"> -<code class="sig-name descname">invalidate</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">invalidate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate" title="Permalink to this definition">¶</a></dt> <dd><p>Invalidate a value in the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -543,16 +568,16 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.invalidate_body"> -<code class="sig-name descname">invalidate_body</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate_body" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">invalidate_body</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate_body" title="Permalink to this definition">¶</a></dt> <dd><p>Invalidate the cached content of the “body” method for this template.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.invalidate_closure"> -<code class="sig-name descname">invalidate_closure</code><span class="sig-paren">(</span><em class="sig-param">name</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate_closure" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">invalidate_closure</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate_closure" title="Permalink to this definition">¶</a></dt> <dd><p>Invalidate a nested <code class="docutils literal notranslate"><span class="pre"><%def></span></code> within this template.</p> <p>Caching of nested defs is a blunt tool as there is no management of scope – nested defs that use cache tags @@ -561,23 +586,23 @@ each other.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.invalidate_def"> -<code class="sig-name descname">invalidate_def</code><span class="sig-paren">(</span><em class="sig-param">name</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate_def" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">invalidate_def</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.invalidate_def" title="Permalink to this definition">¶</a></dt> <dd><p>Invalidate the cached content of a particular <code class="docutils literal notranslate"><span class="pre"><%def></span></code> within this template.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.put"> -<code class="sig-name descname">put</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">value</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.put" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">put</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">value</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.put" title="Permalink to this definition">¶</a></dt> <dd><p>A synonym for <a class="reference internal" href="#mako.cache.Cache.set" title="mako.cache.Cache.set"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Cache.set()</span></code></a>.</p> <p>This is here for backwards compatibility.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.Cache.set"> -<code class="sig-name descname">set</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">value</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.set" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">set</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">value</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.Cache.set" title="Permalink to this definition">¶</a></dt> <dd><p>Place a value in the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -590,9 +615,9 @@ </dl> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.cache.Cache.starttime"> -<code class="sig-name descname">starttime</code><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.starttime" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.cache.Cache"><code class="docutils literal notranslate"><span class="pre">mako.cache.Cache.</span></code></a><code class="sig-name descname">starttime</code><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.starttime" title="Permalink to this definition">¶</a></dt> <dd><p>Epochal time value for when the owning <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> was first compiled.</p> <p>A cache implementation may wish to invalidate data earlier than @@ -604,14 +629,14 @@ </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.cache.CacheImpl"> -<em class="property">class </em><code class="sig-prename descclassname">mako.cache.</code><code class="sig-name descname">CacheImpl</code><span class="sig-paren">(</span><em class="sig-param">cache</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.cache.</code><code class="sig-name descname">CacheImpl</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">cache</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>Provide a cache implementation for use by <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><code class="xref py py-class docutils literal notranslate"><span class="pre">Cache</span></code></a>.</p> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.CacheImpl.get"> -<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.get" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.CacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.cache.CacheImpl.</span></code></a><code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.get" title="Permalink to this definition">¶</a></dt> <dd><p>Retrieve a value from the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -623,9 +648,9 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.CacheImpl.get_or_create"> -<code class="sig-name descname">get_or_create</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">creation_function</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.get_or_create" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.CacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.cache.CacheImpl.</span></code></a><code class="sig-name descname">get_or_create</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">creation_function</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.get_or_create" title="Permalink to this definition">¶</a></dt> <dd><p>Retrieve a value from the cache, using the given creation function to generate a new value.</p> <p>This function <em>must</em> return a value, either from @@ -645,9 +670,9 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.CacheImpl.invalidate"> -<code class="sig-name descname">invalidate</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.invalidate" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.CacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.cache.CacheImpl.</span></code></a><code class="sig-name descname">invalidate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.invalidate" title="Permalink to this definition">¶</a></dt> <dd><p>Invalidate a value in the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -659,16 +684,16 @@ </dl> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.cache.CacheImpl.pass_context"> -<code class="sig-name descname">pass_context</code><em class="property"> = False</em><a class="headerlink" href="#mako.cache.CacheImpl.pass_context" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.cache.CacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.cache.CacheImpl.</span></code></a><code class="sig-name descname">pass_context</code><em class="property"> = False</em><a class="headerlink" href="#mako.cache.CacheImpl.pass_context" title="Permalink to this definition">¶</a></dt> <dd><p>If <code class="docutils literal notranslate"><span class="pre">True</span></code>, the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> will be passed to -<a class="reference internal" href="#mako.cache.CacheImpl.get_or_create" title="mako.cache.CacheImpl.get_or_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_or_create</span></code></a> as the name <code class="docutils literal notranslate"><span class="pre">'context'</span></code>.</p> +<a class="reference internal" href="#mako.cache.CacheImpl.get_or_create" title="mako.cache.CacheImpl.get_or_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">CacheImpl.get_or_create()</span></code></a> as the name <code class="docutils literal notranslate"><span class="pre">'context'</span></code>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.cache.CacheImpl.set"> -<code class="sig-name descname">set</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">value</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.set" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.cache.CacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.cache.CacheImpl.</span></code></a><code class="sig-name descname">set</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">value</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.CacheImpl.set" title="Permalink to this definition">¶</a></dt> <dd><p>Place a value in the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -683,23 +708,26 @@ </dd></dl> -<dl class="function"> +<dl class="py function"> <dt id="mako.cache.register_plugin"> -<code class="sig-prename descclassname">mako.cache.</code><code class="sig-name descname">register_plugin</code><span class="sig-paren">(</span><em class="sig-param">name</em>, <em class="sig-param">modulepath</em>, <em class="sig-param">objname</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.register_plugin" title="Permalink to this definition">¶</a></dt> +<em class="property">function </em><code class="sig-prename descclassname">mako.cache.</code><code class="sig-name descname">register_plugin</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">modulepath</span></em>, <em class="sig-param"><span class="n">objname</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.cache.register_plugin" title="Permalink to this definition">¶</a></dt> <dd></dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.ext.beaker_cache.BeakerCacheImpl"> -<em class="property">class </em><code class="sig-prename descclassname">mako.ext.beaker_cache.</code><code class="sig-name descname">BeakerCacheImpl</code><span class="sig-paren">(</span><em class="sig-param">cache</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.ext.beaker_cache.</code><code class="sig-name descname">BeakerCacheImpl</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">cache</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.cache.CacheImpl</span></code></a></p> -<p>Bases: <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.cache.CacheImpl</span></code></a></p> <p>A <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">CacheImpl</span></code></a> provided for the Beaker caching system.</p> <p>This plugin is used by default, based on the default value of <code class="docutils literal notranslate"><span class="pre">'beaker'</span></code> for the <code class="docutils literal notranslate"><span class="pre">cache_impl</span></code> parameter of the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> classes.</p> -<dl class="method"> +<div class="class-bases docutils container"> +<p><strong>Class signature</strong></p> +<p>class <a class="reference internal" href="#mako.ext.beaker_cache.BeakerCacheImpl" title="mako.ext.beaker_cache.BeakerCacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.ext.beaker_cache.BeakerCacheImpl</span></code></a> (<a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.cache.CacheImpl</span></code></a>)</p> +</div> +<dl class="py method"> <dt id="mako.ext.beaker_cache.BeakerCacheImpl.get"> -<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl.get" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.ext.beaker_cache.BeakerCacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.ext.beaker_cache.BeakerCacheImpl.</span></code></a><code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl.get" title="Permalink to this definition">¶</a></dt> <dd><p>Retrieve a value from the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -711,9 +739,9 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.ext.beaker_cache.BeakerCacheImpl.get_or_create"> -<code class="sig-name descname">get_or_create</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">creation_function</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl.get_or_create" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.ext.beaker_cache.BeakerCacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.ext.beaker_cache.BeakerCacheImpl.</span></code></a><code class="sig-name descname">get_or_create</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">creation_function</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl.get_or_create" title="Permalink to this definition">¶</a></dt> <dd><p>Retrieve a value from the cache, using the given creation function to generate a new value.</p> <p>This function <em>must</em> return a value, either from @@ -733,9 +761,9 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.ext.beaker_cache.BeakerCacheImpl.invalidate"> -<code class="sig-name descname">invalidate</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kw</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl.invalidate" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.ext.beaker_cache.BeakerCacheImpl"><code class="docutils literal notranslate"><span class="pre">mako.ext.beaker_cache.BeakerCacheImpl.</span></code></a><code class="sig-name descname">invalidate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kw</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl.invalidate" title="Permalink to this definition">¶</a></dt> <dd><p>Invalidate a value in the cache.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> @@ -764,7 +792,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -779,7 +807,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -791,7 +819,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/changelog.html b/third_party/mako/doc/changelog.html index 1e0c3772..46a86a52 100644 --- a/third_party/mako/doc/changelog.html +++ b/third_party/mako/doc/changelog.html
@@ -12,7 +12,7 @@ Changelog — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="prev" title="Caching" href="caching.html" /> <!-- end layout.mako headers --> @@ -55,7 +55,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -67,7 +67,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -88,7 +88,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Changelog @@ -113,45 +113,159 @@ <h3><a href="index.html">Table of Contents</a></h3> <ul> <li><a class="reference internal" href="#">Changelog</a><ul> -<li><a class="reference internal" href="#id1">1.0</a><ul> -<li><a class="reference internal" href="#change-1.0.14">1.0.14</a></li> -<li><a class="reference internal" href="#change-1.0.13">1.0.13</a></li> -<li><a class="reference internal" href="#change-1.0.12">1.0.12</a></li> -<li><a class="reference internal" href="#change-1.0.11">1.0.11</a></li> -<li><a class="reference internal" href="#change-1.0.10">1.0.10</a></li> -<li><a class="reference internal" href="#change-1.0.9">1.0.9</a></li> -<li><a class="reference internal" href="#change-1.0.8">1.0.8</a></li> -<li><a class="reference internal" href="#change-1.0.7">1.0.7</a></li> -<li><a class="reference internal" href="#change-1.0.6">1.0.6</a></li> -<li><a class="reference internal" href="#change-1.0.5">1.0.5</a></li> -<li><a class="reference internal" href="#change-1.0.4">1.0.4</a></li> -<li><a class="reference internal" href="#change-1.0.3">1.0.3</a></li> -<li><a class="reference internal" href="#change-1.0.2">1.0.2</a></li> -<li><a class="reference internal" href="#change-1.0.1">1.0.1</a></li> -<li><a class="reference internal" href="#change-1.0.0">1.0.0</a></li> +<li><a class="reference internal" href="#id1">1.1</a><ul> +<li><a class="reference internal" href="#change-1.1.4">1.1.4</a><ul> +<li><a class="reference internal" href="#change-1.1.4-bug">bug</a></li> </ul> </li> -<li><a class="reference internal" href="#id2">0.9</a><ul> -<li><a class="reference internal" href="#change-0.9.1">0.9.1</a></li> -<li><a class="reference internal" href="#change-0.9.0">0.9.0</a></li> +<li><a class="reference internal" href="#change-1.1.3">1.1.3</a><ul> +<li><a class="reference internal" href="#change-1.1.3-bug">bug</a></li> </ul> </li> -<li><a class="reference internal" href="#id3">0.8</a><ul> -<li><a class="reference internal" href="#change-0.8.1">0.8.1</a></li> -<li><a class="reference internal" href="#change-0.8.0">0.8.0</a></li> +<li><a class="reference internal" href="#change-1.1.2">1.1.2</a><ul> +<li><a class="reference internal" href="#change-1.1.2-feature">feature</a></li> </ul> </li> -<li><a class="reference internal" href="#id4">0.7</a><ul> -<li><a class="reference internal" href="#change-0.7.3">0.7.3</a></li> -<li><a class="reference internal" href="#change-0.7.2">0.7.2</a></li> -<li><a class="reference internal" href="#change-0.7.1">0.7.1</a></li> -<li><a class="reference internal" href="#change-0.7.0">0.7.0</a></li> +<li><a class="reference internal" href="#change-1.1.1">1.1.1</a><ul> +<li><a class="reference internal" href="#change-1.1.1-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.1.0">1.1.0</a><ul> +<li><a class="reference internal" href="#change-1.1.0-changed">changed</a></li> +<li><a class="reference internal" href="#change-1.1.0-bug">bug</a></li> +</ul> +</li> +</ul> +</li> +<li><a class="reference internal" href="#id2">1.0</a><ul> +<li><a class="reference internal" href="#change-1.0.14">1.0.14</a><ul> +<li><a class="reference internal" href="#change-1.0.14-feature">feature</a></li> +<li><a class="reference internal" href="#change-1.0.14-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.13">1.0.13</a><ul> +<li><a class="reference internal" href="#change-1.0.13-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.12">1.0.12</a><ul> +<li><a class="reference internal" href="#change-1.0.12-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.11">1.0.11</a><ul> +<li><a class="reference internal" href="#change-1.0.11-changed">changed</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.10">1.0.10</a><ul> +<li><a class="reference internal" href="#change-1.0.10-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.9">1.0.9</a><ul> +<li><a class="reference internal" href="#change-1.0.9-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.8">1.0.8</a><ul> +<li><a class="reference internal" href="#change-1.0.8-feature">feature</a></li> +<li><a class="reference internal" href="#change-1.0.8-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.7">1.0.7</a><ul> +<li><a class="reference internal" href="#change-1.0.7-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.6">1.0.6</a><ul> +<li><a class="reference internal" href="#change-1.0.6-feature">feature</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.5">1.0.5</a><ul> +<li><a class="reference internal" href="#change-1.0.5-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.4">1.0.4</a><ul> +<li><a class="reference internal" href="#change-1.0.4-feature">feature</a></li> +<li><a class="reference internal" href="#change-1.0.4-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.3">1.0.3</a><ul> +<li><a class="reference internal" href="#change-1.0.3-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.2">1.0.2</a><ul> +<li><a class="reference internal" href="#change-1.0.2-feature">feature</a></li> +<li><a class="reference internal" href="#change-1.0.2-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.1">1.0.1</a><ul> +<li><a class="reference internal" href="#change-1.0.1-feature">feature</a></li> +<li><a class="reference internal" href="#change-1.0.1-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-1.0.0">1.0.0</a><ul> +<li><a class="reference internal" href="#change-1.0.0-feature">feature</a></li> +<li><a class="reference internal" href="#change-1.0.0-bug">bug</a></li> +<li><a class="reference internal" href="#change-1.0.0-misc">misc</a></li> +</ul> +</li> +</ul> +</li> +<li><a class="reference internal" href="#id3">0.9</a><ul> +<li><a class="reference internal" href="#change-0.9.1">0.9.1</a><ul> +<li><a class="reference internal" href="#change-0.9.1-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.9.0">0.9.0</a><ul> +<li><a class="reference internal" href="#change-0.9.0-bug">bug</a></li> +</ul> +</li> +</ul> +</li> +<li><a class="reference internal" href="#id4">0.8</a><ul> +<li><a class="reference internal" href="#change-0.8.1">0.8.1</a><ul> +<li><a class="reference internal" href="#change-0.8.1-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.8.0">0.8.0</a><ul> +<li><a class="reference internal" href="#change-0.8.0-feature">feature</a></li> +<li><a class="reference internal" href="#change-0.8.0-bug">bug</a></li> +</ul> +</li> +</ul> +</li> +<li><a class="reference internal" href="#id5">0.7</a><ul> +<li><a class="reference internal" href="#change-0.7.3">0.7.3</a><ul> +<li><a class="reference internal" href="#change-0.7.3-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.7.2">0.7.2</a><ul> +<li><a class="reference internal" href="#change-0.7.2-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.7.1">0.7.1</a><ul> +<li><a class="reference internal" href="#change-0.7.1-feature">feature</a></li> +<li><a class="reference internal" href="#change-0.7.1-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.7.0">0.7.0</a><ul> +<li><a class="reference internal" href="#change-0.7.0-feature">feature</a></li> +<li><a class="reference internal" href="#change-0.7.0-bug">bug</a></li> +</ul> +</li> </ul> </li> <li><a class="reference internal" href="#older-versions">Older Versions</a><ul> -<li><a class="reference internal" href="#change-0.6.2">0.6.2</a></li> -<li><a class="reference internal" href="#change-0.6.1">0.6.1</a></li> -<li><a class="reference internal" href="#change-0.6.0">0.6.0</a></li> +<li><a class="reference internal" href="#change-0.6.2">0.6.2</a><ul> +<li><a class="reference internal" href="#change-0.6.2-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.6.1">0.6.1</a><ul> +<li><a class="reference internal" href="#change-0.6.1-bug">bug</a></li> +</ul> +</li> +<li><a class="reference internal" href="#change-0.6.0">0.6.0</a><ul> +<li><a class="reference internal" href="#change-0.6.0-feature">feature</a></li> +<li><a class="reference internal" href="#change-0.6.0-bug">bug</a></li> +<li><a class="reference internal" href="#change-0.6.0-misc">misc</a></li> +</ul> +</li> <li><a class="reference internal" href="#change-0.5.0">0.5.0</a></li> <li><a class="reference internal" href="#change-0.4.2">0.4.2</a></li> <li><a class="reference internal" href="#change-0.4.1">0.4.1</a></li> @@ -208,11 +322,131 @@ <div class="section" id="changelog"> <h1>Changelog<a class="headerlink" href="#changelog" title="Permalink to this headline">¶</a></h1> <div class="section" id="id1"> -<h2>1.0<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2> +<h2>1.1<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2> +<div class="section" id="change-1.1.4"> +<h3 class="release-version">1.1.4<a class="headerlink" href="#change-1.1.4" title="Permalink to this headline">¶</a></h3> +Released: Thu Jan 14 2021<div class="section" id="change-1.1.4-bug"> +<h4>bug<a class="headerlink" href="#change-1.1.4-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.1.4-0"><span class="target" id="change-2198f165c14deba5d21e3467595f0bf0"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-2198f165c14deba5d21e3467595f0bf0">¶</a></span><p>Fixed Python deprecation issues related to module importing, as well as +file access within the Lingua plugin, for deprecated APIs that began to +emit warnings under Python 3.10. Pull request courtesy Petr Viktorin.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/328">#328</a></p> +</p> +</li> +</ul> +</div> +</div> +<div class="section" id="change-1.1.3"> +<h3 class="release-version">1.1.3<a class="headerlink" href="#change-1.1.3" title="Permalink to this headline">¶</a></h3> +Released: Fri May 29 2020<div class="section" id="change-1.1.3-bug"> +<h4>bug<a class="headerlink" href="#change-1.1.3-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.1.3-0"><span class="target" id="change-b827956014d40c0443d48def8b2e1460"><strong>[bug] [templates]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b827956014d40c0443d48def8b2e1460">¶</a></span><p>The default template encoding is now utf-8. Previously, the encoding was +“ascii”, which was standard throughout Python 2. This allows that +“magic encoding comment” for utf-8 templates is no longer required.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/267">#267</a></p> +</p> +</li> +</ul> +</div> +</div> +<div class="section" id="change-1.1.2"> +<h3 class="release-version">1.1.2<a class="headerlink" href="#change-1.1.2" title="Permalink to this headline">¶</a></h3> +Released: Sun Mar 1 2020<div class="section" id="change-1.1.2-feature"> +<h4>feature<a class="headerlink" href="#change-1.1.2-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.1.2-0"><span class="target" id="change-a2ae3a121ae4bb4fb9cc45c62b699fee"><strong>[feature] [commands]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a2ae3a121ae4bb4fb9cc45c62b699fee">¶</a></span><p>Added –output-file argument to the Mako command line runner, which allows +a specific output file to be selected. Pull request courtesy Björn +Dahlgren.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/283">#283</a></p> +</p> +</li> +</ul> +</div> +</div> +<div class="section" id="change-1.1.1"> +<h3 class="release-version">1.1.1<a class="headerlink" href="#change-1.1.1" title="Permalink to this headline">¶</a></h3> +Released: Mon Jan 20 2020<div class="section" id="change-1.1.1-bug"> +<h4>bug<a class="headerlink" href="#change-1.1.1-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.1.1-0"><span class="target" id="change-5b12c29068f3f97f496036d44cc2ba65"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5b12c29068f3f97f496036d44cc2ba65">¶</a></span><p>Replaced usage of the long-superseded “parser.suite” module in the +mako.util package for parsing the python magic encoding comment with the +“ast.parse” function introduced many years ago in Python 2.5, as +“parser.suite” is emitting deprecation warnings in Python 3.9.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/310">#310</a></p> +</p> +</li> +<li><p class="caption" id="change-1.1.1-1"><span class="target" id="change-1e8b3a81120c667493fbb54b2803b5bb"><strong>[bug] [ext]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1e8b3a81120c667493fbb54b2803b5bb">¶</a></span><p>Added “babel” and “lingua” dependency entries to the setuptools entrypoints +for the babel and lingua extensions, so that pkg_resources can check that +these extra dependencies are available, raising an informative +exception if not. Pull request courtesy sinoroc.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/304">#304</a></p> +</p> +</li> +</ul> +</div> +</div> +<div class="section" id="change-1.1.0"> +<h3 class="release-version">1.1.0<a class="headerlink" href="#change-1.1.0" title="Permalink to this headline">¶</a></h3> +Released: Thu Aug 1 2019<div class="section" id="change-1.1.0-changed"> +<h4>changed<a class="headerlink" href="#change-1.1.0-changed" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.1.0-0"><span class="target" id="change-32be580287d30b2fa09e8f3df3343de9"><strong>[changed] [setup]</strong> <a class="changelog-reference headerlink reference internal" href="#change-32be580287d30b2fa09e8f3df3343de9">¶</a></span><p>Removed the “python setup.py test” feature in favor of a straight run of +“tox”. Per Pypa / pytest developers, “setup.py” commands are in general +headed towards deprecation in favor of tox. The tox.ini script has been +updated such that running “tox” with no arguments will perform a single run +of the test suite against the default installed Python interpreter.</p> +<div class="admonition seealso"> +<p class="admonition-title">See also</p> +<p><a class="reference external" href="https://github.com/pypa/setuptools/issues/1684">https://github.com/pypa/setuptools/issues/1684</a></p> +<p><a class="reference external" href="https://github.com/pytest-dev/pytest/issues/5534">https://github.com/pytest-dev/pytest/issues/5534</a></p> +</div> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/303">#303</a></p> +</p> +</li> +<li><p class="caption" id="change-1.1.0-1"><span class="target" id="change-71619fc844090f4805f08c14eeb89cc1"><strong>[changed] [installer] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-71619fc844090f4805f08c14eeb89cc1">¶</a></span><p>Mako 1.1 now supports Python versions:</p> +<ul> +<li><p>2.7</p></li> +<li><p>3.4 and higher</p></li> +</ul> +<p>This includes that setup.py no longer includes any conditionals, allowing +for a pure Python wheel build, however this is not necessarily part of the +Pypi release process as of yet. The test suite also raises for Python +deprecation warnings.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/249">#249</a></p> +</p> +</li> +</ul> +</div> +<div class="section" id="change-1.1.0-bug"> +<h4>bug<a class="headerlink" href="#change-1.1.0-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.1.0-2"><span class="target" id="change-08be3c602d917d4d36bb3b5833f3b5b9"><strong>[bug] [py3k] [windows]</strong> <a class="changelog-reference headerlink reference internal" href="#change-08be3c602d917d4d36bb3b5833f3b5b9">¶</a></span><p>Replaced usage of time.clock() on windows as well as time.time() elsewhere +for microsecond timestamps with timeit.default_timer(), as time.clock() is +being removed in Python 3.8. Pull request courtesy Christoph Reiter.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/301">#301</a></p> +</p> +</li> +<li><p class="caption" id="change-1.1.0-3"><span class="target" id="change-0f042d5af246f70a46fa93469405de6c"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0f042d5af246f70a46fa93469405de6c">¶</a></span><p>Replaced usage of <code class="docutils literal notranslate"><span class="pre">inspect.getfullargspec()</span></code> with the vendored version +used by SQLAlchemy, Alembic to avoid future deprecation warnings. Also +cleans up an additional version of the same function that’s apparently +been floating around for some time.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/295">#295</a></p> +</p> +</li> +</ul> +</div> +</div> +</div> +<div class="section" id="id2"> +<h2>1.0<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h2> <div class="section" id="change-1.0.14"> -<h3>1.0.14<a class="headerlink" href="#change-1.0.14" title="Permalink to this headline">¶</a></h3> -Released: Sat Jul 20 2019<ul class="simple"> -<li><p id="change-1.0.14-0"><span class="target" id="change-1591877700fd8523662d8a3494e99b0c"><strong>[feature] [template] </strong></span><p>The <code class="docutils literal notranslate"><span class="pre">n</span></code> filter is now supported in the <code class="docutils literal notranslate"><span class="pre"><%page></span></code> tag. This allows a +<h3 class="release-version">1.0.14<a class="headerlink" href="#change-1.0.14" title="Permalink to this headline">¶</a></h3> +Released: Sat Jul 20 2019<div class="section" id="change-1.0.14-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.14-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.14-0"><span class="target" id="change-1591877700fd8523662d8a3494e99b0c"><strong>[feature] [template]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1591877700fd8523662d8a3494e99b0c">¶</a></span><p>The <code class="docutils literal notranslate"><span class="pre">n</span></code> filter is now supported in the <code class="docutils literal notranslate"><span class="pre"><%page></span></code> tag. This allows a template to omit the default expression filters throughout a whole template, for those cases where a template-wide filter needs to have default filtering disabled. Pull request courtesy Martin von Gagern.</p> @@ -220,196 +454,224 @@ <p class="admonition-title">See also</p> <p><a class="reference internal" href="filtering.html#expression-filtering-nfilter"><span class="std std-ref">Turning off Filtering with the n Filter</span></a></p> </div> -<a class="changeset-link headerlink reference internal" href="#change-1591877700fd8523662d8a3494e99b0c">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.14-1"><span class="target" id="change-0698bc3cc55123a08f1da73c5cc7d8c3"><strong>[bug] [exceptions] </strong></span><p>Fixed issue where the correct file URI would not be shown in the -template-formatted exception traceback if the template filename were not -known. Additionally fixes an issue where stale filenames would be -displayed if a stack trace alternated between different templates. Pull -request courtesy Martin von Gagern.</p> -<a class="changeset-link headerlink reference internal" href="#change-0698bc3cc55123a08f1da73c5cc7d8c3">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +<div class="section" id="change-1.0.14-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.14-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.14-1"><span class="target" id="change-0698bc3cc55123a08f1da73c5cc7d8c3"><strong>[bug] [exceptions]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0698bc3cc55123a08f1da73c5cc7d8c3">¶</a></span><p>Fixed issue where the correct file URI would not be shown in the +template-formatted exception traceback if the template filename were not +known. Additionally fixes an issue where stale filenames would be +displayed if a stack trace alternated between different templates. Pull +request courtesy Martin von Gagern.</p> +<p></p> +</p> +</li> +</ul> +</div> +</div> <div class="section" id="change-1.0.13"> -<h3>1.0.13<a class="headerlink" href="#change-1.0.13" title="Permalink to this headline">¶</a></h3> -Released: Mon Jul 1 2019<ul class="simple"> -<li><p id="change-1.0.13-0"><span class="target" id="change-936d44c09a4e19aed6e0f50386fb14d8"><strong>[bug] [exceptions] </strong></span><p>Improved the line-number tracking for source lines inside of Python <code class="docutils literal notranslate"><span class="pre"><%</span> +<h3 class="release-version">1.0.13<a class="headerlink" href="#change-1.0.13" title="Permalink to this headline">¶</a></h3> +Released: Mon Jul 1 2019<div class="section" id="change-1.0.13-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.13-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.13-0"><span class="target" id="change-936d44c09a4e19aed6e0f50386fb14d8"><strong>[bug] [exceptions]</strong> <a class="changelog-reference headerlink reference internal" href="#change-936d44c09a4e19aed6e0f50386fb14d8">¶</a></span><p>Improved the line-number tracking for source lines inside of Python <code class="docutils literal notranslate"><span class="pre"><%</span> <span class="pre">...</span> <span class="pre">%></span></code> blocks, such that text- and HTML-formatted exception traces such as that of <a class="reference internal" href="usage.html#mako.exceptions.html_error_template" title="mako.exceptions.html_error_template"><code class="xref py py-func docutils literal notranslate"><span class="pre">html_error_template()</span></code></a> now report the correct source line inside the block, rather than the first line of the block itself. Exceptions in <code class="docutils literal notranslate"><span class="pre"><%!</span> <span class="pre">...</span> <span class="pre">%></span></code> blocks which get raised while loading the module are still not reported correctly, as these are handled before the Mako code is generated. Pull request courtesy Martin von Gagern.</p> -<a class="changeset-link headerlink reference internal" href="#change-936d44c09a4e19aed6e0f50386fb14d8">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.12"> -<h3>1.0.12<a class="headerlink" href="#change-1.0.12" title="Permalink to this headline">¶</a></h3> -Released: Wed Jun 5 2019<ul class="simple"> -<li><p id="change-1.0.12-0"><span class="target" id="change-d789f9385416200220c8ae6a4921d8cd"><strong>[bug] [py3k] </strong></span><p>Fixed regression where import refactors in Mako 1.0.11 caused broken +<h3 class="release-version">1.0.12<a class="headerlink" href="#change-1.0.12" title="Permalink to this headline">¶</a></h3> +Released: Wed Jun 5 2019<div class="section" id="change-1.0.12-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.12-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.12-0"><span class="target" id="change-d789f9385416200220c8ae6a4921d8cd"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d789f9385416200220c8ae6a4921d8cd">¶</a></span><p>Fixed regression where import refactors in Mako 1.0.11 caused broken imports on Python 3.8.</p> -<a class="changeset-link headerlink reference internal" href="#change-d789f9385416200220c8ae6a4921d8cd">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/296">#296</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/296">#296</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.11"> -<h3>1.0.11<a class="headerlink" href="#change-1.0.11" title="Permalink to this headline">¶</a></h3> -Released: Fri May 31 2019<ul class="simple"> -<li><p id="change-1.0.11-0"><span class="target" id="change-ddf4199ea402d6338c0fd37db40b37c3"><strong>[change] </strong></span><p>Updated for additional project metadata in setup.py. Additionally, +<h3 class="release-version">1.0.11<a class="headerlink" href="#change-1.0.11" title="Permalink to this headline">¶</a></h3> +Released: Fri May 31 2019<div class="section" id="change-1.0.11-changed"> +<h4>changed<a class="headerlink" href="#change-1.0.11-changed" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.11-0"><span class="target" id="change-ddf4199ea402d6338c0fd37db40b37c3"><strong>[changed]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ddf4199ea402d6338c0fd37db40b37c3">¶</a></span><p>Updated for additional project metadata in setup.py. Additionally, the code has been reformatted using Black and zimports.</p> -<a class="changeset-link headerlink reference internal" href="#change-ddf4199ea402d6338c0fd37db40b37c3">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.10"> -<h3>1.0.10<a class="headerlink" href="#change-1.0.10" title="Permalink to this headline">¶</a></h3> -Released: Fri May 10 2019<ul class="simple"> -<li><p id="change-1.0.10-0"><span class="target" id="change-5cb52ab7e79764e97e2562d939f68cbf"><strong>[bug] [py3k] </strong></span><p>Added a default encoding of “utf-8” when the <a class="reference internal" href="usage.html#mako.exceptions.RichTraceback" title="mako.exceptions.RichTraceback"><code class="xref py py-class docutils literal notranslate"><span class="pre">RichTraceback</span></code></a> +<h3 class="release-version">1.0.10<a class="headerlink" href="#change-1.0.10" title="Permalink to this headline">¶</a></h3> +Released: Fri May 10 2019<div class="section" id="change-1.0.10-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.10-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.10-0"><span class="target" id="change-5cb52ab7e79764e97e2562d939f68cbf"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5cb52ab7e79764e97e2562d939f68cbf">¶</a></span><p>Added a default encoding of “utf-8” when the <a class="reference internal" href="usage.html#mako.exceptions.RichTraceback" title="mako.exceptions.RichTraceback"><code class="xref py py-class docutils literal notranslate"><span class="pre">RichTraceback</span></code></a> object retrieves Python source lines from a Python traceback; as these are bytes in Python 3 they need to be decoded so that they can be formatted in the template.</p> -<a class="changeset-link headerlink reference internal" href="#change-5cb52ab7e79764e97e2562d939f68cbf">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/293">#293</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/293">#293</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.9"> -<h3>1.0.9<a class="headerlink" href="#change-1.0.9" title="Permalink to this headline">¶</a></h3> -Released: Mon Apr 15 2019<ul class="simple"> -<li><p id="change-1.0.9-0"><span class="target" id="change-93c86f7c375b8505ff6c28ce4f40ed34"><strong>[bug] </strong></span><p>Further corrected the previous fix for <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/287">#287</a> as it relied upon +<h3 class="release-version">1.0.9<a class="headerlink" href="#change-1.0.9" title="Permalink to this headline">¶</a></h3> +Released: Mon Apr 15 2019<div class="section" id="change-1.0.9-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.9-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.9-0"><span class="target" id="change-93c86f7c375b8505ff6c28ce4f40ed34"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-93c86f7c375b8505ff6c28ce4f40ed34">¶</a></span><p>Further corrected the previous fix for <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/287">#287</a> as it relied upon an attribute that is monkeypatched by Python’s <code class="docutils literal notranslate"><span class="pre">ast</span></code> module for some reason, which fails if <code class="docutils literal notranslate"><span class="pre">ast</span></code> hasn’t been imported; the correct attribute <code class="docutils literal notranslate"><span class="pre">Constant.value</span></code> is now used. Also note the issue was mis-numbered in the previous changelog note.</p> -<a class="changeset-link headerlink reference internal" href="#change-93c86f7c375b8505ff6c28ce4f40ed34">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/287">#287</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/287">#287</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.8"> -<h3>1.0.8<a class="headerlink" href="#change-1.0.8" title="Permalink to this headline">¶</a></h3> -Released: Wed Mar 20 2019<ul class="simple"> -<li><p id="change-1.0.8-0"><span class="target" id="change-ee8aabc71dd9f97ffd13bbd017da1920"><strong>[bug] </strong></span><p>Fixed an element in the AST Python generator which changed -for Python 3.8, causing expression generation to fail.</p> -<a class="changeset-link headerlink reference internal" href="#change-ee8aabc71dd9f97ffd13bbd017da1920">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/287">#287</a></p> -</p> -</li> -<li><p id="change-1.0.8-1"><span class="target" id="change-5c5f66915e537125bd4a0f5e76fa6486"><strong>[feature] </strong></span><p>Added <code class="docutils literal notranslate"><span class="pre">--output-encoding</span></code> flag to the mako-render script. +<h3 class="release-version">1.0.8<a class="headerlink" href="#change-1.0.8" title="Permalink to this headline">¶</a></h3> +Released: Wed Mar 20 2019<div class="section" id="change-1.0.8-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.8-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.8-0"><span class="target" id="change-5c5f66915e537125bd4a0f5e76fa6486"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5c5f66915e537125bd4a0f5e76fa6486">¶</a></span><p>Added <code class="docutils literal notranslate"><span class="pre">--output-encoding</span></code> flag to the mako-render script. Pull request courtesy lacsaP.</p> -<a class="changeset-link headerlink reference internal" href="#change-5c5f66915e537125bd4a0f5e76fa6486">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/271">#271</a></p> -</p> -</li> -<li><p id="change-1.0.8-2"><span class="target" id="change-311d5820d86dd3ed4e3b0d2fd8643a7a"><strong>[bug] </strong></span><p>Removed unnecessary “usage” prefix from mako-render script. -Pull request courtesy Hugo.</p> -<a class="changeset-link headerlink reference internal" href="#change-311d5820d86dd3ed4e3b0d2fd8643a7a">¶</a><p></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/271">#271</a></p> </p> </li> </ul> </div> +<div class="section" id="change-1.0.8-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.8-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.8-1"><span class="target" id="change-ee8aabc71dd9f97ffd13bbd017da1920"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ee8aabc71dd9f97ffd13bbd017da1920">¶</a></span><p>Fixed an element in the AST Python generator which changed +for Python 3.8, causing expression generation to fail.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/287">#287</a></p> +</p> +</li> +<li><p class="caption" id="change-1.0.8-2"><span class="target" id="change-311d5820d86dd3ed4e3b0d2fd8643a7a"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-311d5820d86dd3ed4e3b0d2fd8643a7a">¶</a></span><p>Removed unnecessary “usage” prefix from mako-render script. +Pull request courtesy Hugo.</p> +<p></p> +</p> +</li> +</ul> +</div> +</div> <div class="section" id="change-1.0.7"> -<h3>1.0.7<a class="headerlink" href="#change-1.0.7" title="Permalink to this headline">¶</a></h3> -Released: Thu Jul 13 2017<ul class="simple"> -<li><p id="change-1.0.7-0"><span class="target" id="change-50698bda8346f71d565b22949ec42fa6"><strong>[bug] </strong></span><p>Changed the “print” in the mako-render command to +<h3 class="release-version">1.0.7<a class="headerlink" href="#change-1.0.7" title="Permalink to this headline">¶</a></h3> +Released: Thu Jul 13 2017<div class="section" id="change-1.0.7-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.7-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.7-0"><span class="target" id="change-50698bda8346f71d565b22949ec42fa6"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-50698bda8346f71d565b22949ec42fa6">¶</a></span><p>Changed the “print” in the mako-render command to sys.stdout.write(), avoiding the extra newline at the end of the template output. Pull request courtesy Yves Chevallier.</p> -<a class="changeset-link headerlink reference internal" href="#change-50698bda8346f71d565b22949ec42fa6">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.6"> -<h3>1.0.6<a class="headerlink" href="#change-1.0.6" title="Permalink to this headline">¶</a></h3> -Released: Wed Nov 9 2016<ul class="simple"> -<li><p id="change-1.0.6-0"><span class="target" id="change-1ab45bb9f44f0ac0c491437d7cd278d1"><strong>[feature] </strong></span><p>Added new parameter <a class="reference internal" href="usage.html#mako.template.Template.params.include_error_handler" title="mako.template.Template"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Template.include_error_handler</span></code></a> . +<h3 class="release-version">1.0.6<a class="headerlink" href="#change-1.0.6" title="Permalink to this headline">¶</a></h3> +Released: Wed Nov 9 2016<div class="section" id="change-1.0.6-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.6-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.6-0"><span class="target" id="change-1ab45bb9f44f0ac0c491437d7cd278d1"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1ab45bb9f44f0ac0c491437d7cd278d1">¶</a></span><p>Added new parameter <a class="reference internal" href="usage.html#mako.template.Template.params.include_error_handler" title="mako.template.Template"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Template.include_error_handler</span></code></a> . This works like <a class="reference internal" href="usage.html#mako.template.Template.params.error_handler" title="mako.template.Template"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Template.error_handler</span></code></a> but indicates the handler should take place when this template is included within another template via the <code class="docutils literal notranslate"><span class="pre"><%include></span></code> tag. Pull request courtesy Huayi Zhang.</p> -<a class="changeset-link headerlink reference internal" href="#change-1ab45bb9f44f0ac0c491437d7cd278d1">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.5"> -<h3>1.0.5<a class="headerlink" href="#change-1.0.5" title="Permalink to this headline">¶</a></h3> -Released: Wed Nov 2 2016<ul class="simple"> -<li><p id="change-1.0.5-0"><span class="target" id="change-a888b5e8bb3335eb6b79287ee7e3e65e"><strong>[bug] </strong></span><p>Updated the Sphinx documentation builder to work with recent +<h3 class="release-version">1.0.5<a class="headerlink" href="#change-1.0.5" title="Permalink to this headline">¶</a></h3> +Released: Wed Nov 2 2016<div class="section" id="change-1.0.5-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.5-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.5-0"><span class="target" id="change-a888b5e8bb3335eb6b79287ee7e3e65e"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a888b5e8bb3335eb6b79287ee7e3e65e">¶</a></span><p>Updated the Sphinx documentation builder to work with recent versions of Sphinx.</p> -<a class="changeset-link headerlink reference internal" href="#change-a888b5e8bb3335eb6b79287ee7e3e65e">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.4"> -<h3>1.0.4<a class="headerlink" href="#change-1.0.4" title="Permalink to this headline">¶</a></h3> -Released: Thu Mar 10 2016<ul class="simple"> -<li><p id="change-1.0.4-0"><span class="target" id="change-a0f9819d8082887201784fd7fe175897"><strong>[feature] [test] </strong></span><p>The default test runner is now py.test. Running “python setup.py test” +<h3 class="release-version">1.0.4<a class="headerlink" href="#change-1.0.4" title="Permalink to this headline">¶</a></h3> +Released: Thu Mar 10 2016<div class="section" id="change-1.0.4-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.4-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.4-0"><span class="target" id="change-a0f9819d8082887201784fd7fe175897"><strong>[feature] [test]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a0f9819d8082887201784fd7fe175897">¶</a></span><p>The default test runner is now py.test. Running “python setup.py test” will make use of py.test instead of nose. nose still works as a test runner as well, however.</p> -<a class="changeset-link headerlink reference internal" href="#change-a0f9819d8082887201784fd7fe175897">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-1.0.4-1"><span class="target" id="change-5a254376fcfe88072601688a7fd34bb2"><strong>[bug] [lexer] </strong></span><p>Major improvements to lexing of intricate Python sections which may +<li><p class="caption" id="change-1.0.4-1"><span class="target" id="change-159bcf8ab71d37b6e32321c2d62b7fa5"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-159bcf8ab71d37b6e32321c2d62b7fa5">¶</a></span><p>Added new method <a class="reference internal" href="usage.html#mako.template.Template.list_defs" title="mako.template.Template.list_defs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.list_defs()</span></code></a>. Pull request courtesy +Jonathan Vanasco.</p> +<p></p> +</p> +</li> +</ul> +</div> +<div class="section" id="change-1.0.4-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.4-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.4-2"><span class="target" id="change-5a254376fcfe88072601688a7fd34bb2"><strong>[bug] [lexer]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5a254376fcfe88072601688a7fd34bb2">¶</a></span><p>Major improvements to lexing of intricate Python sections which may contain complex backslash sequences, as well as support for the bitwise operator (e.g. pipe symbol) inside of expression sections distinct from the Mako “filter” operator, provided the operator is enclosed within parentheses or brackets. Pull request courtesy Daniel Martin.</p> -<a class="changeset-link headerlink reference internal" href="#change-5a254376fcfe88072601688a7fd34bb2">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/pull/19">pull request github:19</a></p> -</p> -</li> -<li><p id="change-1.0.4-2"><span class="target" id="change-159bcf8ab71d37b6e32321c2d62b7fa5"><strong>[feature] </strong></span><p>Added new method <a class="reference internal" href="usage.html#mako.template.Template.list_defs" title="mako.template.Template.list_defs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.list_defs()</span></code></a>. Pull request courtesy -Jonathan Vanasco.</p> -<a class="changeset-link headerlink reference internal" href="#change-159bcf8ab71d37b6e32321c2d62b7fa5">¶</a><p></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/pull/19">pull request github:19</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.3"> -<h3>1.0.3<a class="headerlink" href="#change-1.0.3" title="Permalink to this headline">¶</a></h3> -Released: Tue Oct 27 2015<ul class="simple"> -<li><p id="change-1.0.3-0"><span class="target" id="change-a8691815262bf7a1a4857ab58b59972d"><strong>[babel] [bug] </strong></span><p>Fixed an issue where the Babel plugin would not handle a translation +<h3 class="release-version">1.0.3<a class="headerlink" href="#change-1.0.3" title="Permalink to this headline">¶</a></h3> +Released: Tue Oct 27 2015<div class="section" id="change-1.0.3-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.3-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.3-0"><span class="target" id="change-a8691815262bf7a1a4857ab58b59972d"><strong>[bug] [babel]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a8691815262bf7a1a4857ab58b59972d">¶</a></span><p>Fixed an issue where the Babel plugin would not handle a translation symbol that contained non-ascii characters. Pull request courtesy Roman Imankulov.</p> -<a class="changeset-link headerlink reference internal" href="#change-a8691815262bf7a1a4857ab58b59972d">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-1.0.2"> -<h3>1.0.2<a class="headerlink" href="#change-1.0.2" title="Permalink to this headline">¶</a></h3> -Released: Wed Aug 26 2015<ul class="simple"> -<li><p id="change-1.0.2-0"><span class="target" id="change-7a886c9ddff2888de5388a76c07f5fb1"><strong>[bug] [installation] </strong></span><p>The “universal wheel” marker is removed from setup.cfg, because -our setup.py currently makes use of conditional dependencies. -In <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/249">#249</a>, the discussion is ongoing on how to correct our -setup.cfg / setup.py fully so that we can handle the per-version -dependency changes while still maintaining optimal wheel settings, -so this issue is not yet fully resolved.</p> -<a class="changeset-link headerlink reference internal" href="#change-7a886c9ddff2888de5388a76c07f5fb1">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/249">#249</a></p> -</p> -</li> -<li><p id="change-1.0.2-1"><span class="target" id="change-d512dee8244e65df20387799e2bf1c3e"><strong>[bug] [py3k] </strong></span><p>Repair some calls within the ast module that no longer work on Python3.5; -additionally replace the use of <code class="docutils literal notranslate"><span class="pre">inspect.getargspec()</span></code> under -Python 3 (seems to be called from the TG plugin) to avoid deprecation -warnings.</p> -<a class="changeset-link headerlink reference internal" href="#change-d512dee8244e65df20387799e2bf1c3e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/250">#250</a></p> -</p> -</li> -<li><p id="change-1.0.2-2"><span class="target" id="change-821f277b7de91a50393a39180bedba19"><strong>[bug] </strong></span><p>Update the Lingua translation extraction plugin to correctly -handle templates mixing Python control statements (such as if, -for and while) with template fragments. Pull request courtesy -Laurent Daverio.</p> -<a class="changeset-link headerlink reference internal" href="#change-821f277b7de91a50393a39180bedba19">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.2-3"><span class="target" id="change-5198757b33888a7f8f96e2cee5db8f62"><strong>[feature] </strong></span><p>Added <code class="docutils literal notranslate"><span class="pre">STOP_RENDERING</span></code> keyword for returning/exiting from a +<h3 class="release-version">1.0.2<a class="headerlink" href="#change-1.0.2" title="Permalink to this headline">¶</a></h3> +Released: Wed Aug 26 2015<div class="section" id="change-1.0.2-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.2-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.2-0"><span class="target" id="change-5198757b33888a7f8f96e2cee5db8f62"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5198757b33888a7f8f96e2cee5db8f62">¶</a></span><p>Added <code class="docutils literal notranslate"><span class="pre">STOP_RENDERING</span></code> keyword for returning/exiting from a template early, which is a synonym for an empty string <code class="docutils literal notranslate"><span class="pre">""</span></code>. Previously, the docs suggested a bare <code class="docutils literal notranslate"><span class="pre">return</span></code>, but this could cause <code class="docutils literal notranslate"><span class="pre">None</span></code> to appear in the @@ -418,84 +680,127 @@ <p class="admonition-title">See also</p> <p><a class="reference internal" href="syntax.html#syntax-exiting-early"><span class="std std-ref">Exiting Early from a Template</span></a></p> </div> -<a class="changeset-link headerlink reference internal" href="#change-5198757b33888a7f8f96e2cee5db8f62">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/236">#236</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/236">#236</a></p> </p> </li> </ul> </div> +<div class="section" id="change-1.0.2-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.2-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.2-1"><span class="target" id="change-7a886c9ddff2888de5388a76c07f5fb1"><strong>[bug] [installation]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7a886c9ddff2888de5388a76c07f5fb1">¶</a></span><p>The “universal wheel” marker is removed from setup.cfg, because +our setup.py currently makes use of conditional dependencies. +In <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/249">#249</a>, the discussion is ongoing on how to correct our +setup.cfg / setup.py fully so that we can handle the per-version +dependency changes while still maintaining optimal wheel settings, +so this issue is not yet fully resolved.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/249">#249</a></p> +</p> +</li> +<li><p class="caption" id="change-1.0.2-2"><span class="target" id="change-d512dee8244e65df20387799e2bf1c3e"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d512dee8244e65df20387799e2bf1c3e">¶</a></span><p>Repair some calls within the ast module that no longer work on Python3.5; +additionally replace the use of <code class="docutils literal notranslate"><span class="pre">inspect.getargspec()</span></code> under +Python 3 (seems to be called from the TG plugin) to avoid deprecation +warnings.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/250">#250</a></p> +</p> +</li> +<li><p class="caption" id="change-1.0.2-3"><span class="target" id="change-821f277b7de91a50393a39180bedba19"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-821f277b7de91a50393a39180bedba19">¶</a></span><p>Update the Lingua translation extraction plugin to correctly +handle templates mixing Python control statements (such as if, +for and while) with template fragments. Pull request courtesy +Laurent Daverio.</p> +<p></p> +</p> +</li> +</ul> +</div> +</div> <div class="section" id="change-1.0.1"> -<h3>1.0.1<a class="headerlink" href="#change-1.0.1" title="Permalink to this headline">¶</a></h3> -Released: Thu Jan 22 2015<ul class="simple"> -<li><p id="change-1.0.1-0"><span class="target" id="change-1975c829883f2b542d5cde07b22d03ed"><strong>[feature] </strong></span><p>Added support for Lingua, a translation extraction system as an +<h3 class="release-version">1.0.1<a class="headerlink" href="#change-1.0.1" title="Permalink to this headline">¶</a></h3> +Released: Thu Jan 22 2015<div class="section" id="change-1.0.1-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.1-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.1-0"><span class="target" id="change-1975c829883f2b542d5cde07b22d03ed"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1975c829883f2b542d5cde07b22d03ed">¶</a></span><p>Added support for Lingua, a translation extraction system as an alternative to Babel. Pull request courtesy Wichert Akkerman.</p> -<a class="changeset-link headerlink reference internal" href="#change-1975c829883f2b542d5cde07b22d03ed">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.1-1"><span class="target" id="change-32bb4d6d81d803d8fcce430daf6fe6c6"><strong>[bug] [py3k] </strong></span><p>Modernized the examples/wsgi/run_wsgi.py file for Py3k. -Pull requset courtesy Cody Taylor.</p> -<a class="changeset-link headerlink reference internal" href="#change-32bb4d6d81d803d8fcce430daf6fe6c6">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +<div class="section" id="change-1.0.1-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.1-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.1-1"><span class="target" id="change-32bb4d6d81d803d8fcce430daf6fe6c6"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-32bb4d6d81d803d8fcce430daf6fe6c6">¶</a></span><p>Modernized the examples/wsgi/run_wsgi.py file for Py3k. +Pull requset courtesy Cody Taylor.</p> +<p></p> +</p> +</li> +</ul> +</div> +</div> <div class="section" id="change-1.0.0"> -<h3>1.0.0<a class="headerlink" href="#change-1.0.0" title="Permalink to this headline">¶</a></h3> -Released: Sun Jun 8 2014<ul class="simple"> -<li><p id="change-1.0.0-0"><span class="target" id="change-a1b32dcfac59fb3d94194cc23d05eec4"><strong>[bug] [py2k] </strong></span><p>Improved the error re-raise operation when a custom -<a class="reference internal" href="usage.html#mako.template.Template.params.error_handler" title="mako.template.Template"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Template.error_handler</span></code></a> is used that does not handle -the exception; the original stack trace etc. is now preserved. -Pull request courtesy Manfred Haltner.</p> -<a class="changeset-link headerlink reference internal" href="#change-a1b32dcfac59fb3d94194cc23d05eec4">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.0-1"><span class="target" id="change-7f76f6ca5487a165840d3f1634e26b5f"><strong>[bug] [filters] [py2k] </strong></span><p>Added an html_escape filter that works in “non unicode” mode. -Previously, when using <code class="docutils literal notranslate"><span class="pre">disable_unicode=True</span></code>, the <code class="docutils literal notranslate"><span class="pre">u</span></code> filter -would fail to handle non-ASCII bytes properly. Pull request -courtesy George Xie.</p> -<a class="changeset-link headerlink reference internal" href="#change-7f76f6ca5487a165840d3f1634e26b5f">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.0-2"><span class="target" id="change-b602a175c0ec26eaa4f42962d23cca96"><strong>[general] </strong></span><p>Compatibility changes; in order to modernize the codebase, Mako -is now dropping support for Python 2.4 and Python 2.5 altogether. -The source base is now targeted at Python 2.6 and forwards.</p> -<a class="changeset-link headerlink reference internal" href="#change-b602a175c0ec26eaa4f42962d23cca96">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.0-3"><span class="target" id="change-ac6c8e7df6c612e92bf81577c4c96276"><strong>[feature] </strong></span><p>Template modules now generate a JSON “metadata” structure at the bottom +<h3 class="release-version">1.0.0<a class="headerlink" href="#change-1.0.0" title="Permalink to this headline">¶</a></h3> +Released: Sun Jun 8 2014<div class="section" id="change-1.0.0-feature"> +<h4>feature<a class="headerlink" href="#change-1.0.0-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.0-0"><span class="target" id="change-ac6c8e7df6c612e92bf81577c4c96276"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ac6c8e7df6c612e92bf81577c4c96276">¶</a></span><p>Template modules now generate a JSON “metadata” structure at the bottom of the source file which includes parseable information about the templates’ source file, encoding etc. as well as a mapping of module source lines to template lines, thus replacing the “# SOURCE LINE” markers throughout the source code. The structure also indicates those lines that are explicitly not part of the template’s source; the goal here is to allow better integration with coverage and other tools.</p> -<a class="changeset-link headerlink reference internal" href="#change-ac6c8e7df6c612e92bf81577c4c96276">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-1.0.0-4"><span class="target" id="change-48f95a70e6b509811d3c6c208b3bbafc"><strong>[bug] [py3k] </strong></span><p>Fixed bug in <code class="docutils literal notranslate"><span class="pre">decode.<encoding></span></code> filter where a non-string object -would not be correctly interpreted in Python 3.</p> -<a class="changeset-link headerlink reference internal" href="#change-48f95a70e6b509811d3c6c208b3bbafc">¶</a><p></p> -</p> -</li> -<li><p id="change-1.0.0-5"><span class="target" id="change-7638baccf1cc95230c98f9475713aff4"><strong>[bug] [py3k] </strong></span><p>Fixed bug in Python parsing logic which would fail on Python 3 -when a “try/except” targeted a tuple of exception types, rather -than a single exception.</p> -<a class="changeset-link headerlink reference internal" href="#change-7638baccf1cc95230c98f9475713aff4">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/227">#227</a></p> -</p> -</li> -<li><p id="change-1.0.0-6"><span class="target" id="change-4ed767c704faafcfcaa96c993b6c3ce8"><strong>[feature] </strong></span><p>mako-render is now implemented as a setuptools entrypoint script; +<li><p class="caption" id="change-1.0.0-1"><span class="target" id="change-4ed767c704faafcfcaa96c993b6c3ce8"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4ed767c704faafcfcaa96c993b6c3ce8">¶</a></span><p>mako-render is now implemented as a setuptools entrypoint script; a standalone mako.cmd.cmdline() callable is now available, and the system also uses argparse now instead of optparse. Pull request courtesy Derek Harland.</p> -<a class="changeset-link headerlink reference internal" href="#change-4ed767c704faafcfcaa96c993b6c3ce8">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-1.0.0-7"><span class="target" id="change-b514d619be9c65cb0abb149be8b3a1a2"><strong>[feature] </strong></span><p>The mako-render script will now catch exceptions and run them +<li><p class="caption" id="change-1.0.0-2"><span class="target" id="change-b514d619be9c65cb0abb149be8b3a1a2"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b514d619be9c65cb0abb149be8b3a1a2">¶</a></span><p>The mako-render script will now catch exceptions and run them into the text error handler, and exit with a non-zero exit code. Pull request courtesy Derek Harland.</p> -<a class="changeset-link headerlink reference internal" href="#change-b514d619be9c65cb0abb149be8b3a1a2">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-1.0.0-8"><span class="target" id="change-a328a21ec5123a69caf9021bbf70b90a"><strong>[bug] </strong></span><p>A rework of the mako-render script allows the script to run +<li><p class="caption" id="change-1.0.0-3"><span class="target" id="change-e39fabd3e579af9dd730204a7692c76f"><strong>[feature] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e39fabd3e579af9dd730204a7692c76f">¶</a></span><p>Support is added for Python 3 “keyword only” arguments, as used in +defs. Pull request courtesy Eevee.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/pull/7">pull request github:7</a></p> +</p> +</li> +</ul> +</div> +<div class="section" id="change-1.0.0-bug"> +<h4>bug<a class="headerlink" href="#change-1.0.0-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.0-4"><span class="target" id="change-a1b32dcfac59fb3d94194cc23d05eec4"><strong>[bug] [py2k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a1b32dcfac59fb3d94194cc23d05eec4">¶</a></span><p>Improved the error re-raise operation when a custom +<a class="reference internal" href="usage.html#mako.template.Template.params.error_handler" title="mako.template.Template"><code class="xref py py-paramref docutils literal notranslate"><span class="pre">Template.error_handler</span></code></a> is used that does not handle +the exception; the original stack trace etc. is now preserved. +Pull request courtesy Manfred Haltner.</p> +<p></p> +</p> +</li> +<li><p class="caption" id="change-1.0.0-5"><span class="target" id="change-7f76f6ca5487a165840d3f1634e26b5f"><strong>[bug] [filters] [py2k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7f76f6ca5487a165840d3f1634e26b5f">¶</a></span><p>Added an html_escape filter that works in “non unicode” mode. +Previously, when using <code class="docutils literal notranslate"><span class="pre">disable_unicode=True</span></code>, the <code class="docutils literal notranslate"><span class="pre">u</span></code> filter +would fail to handle non-ASCII bytes properly. Pull request +courtesy George Xie.</p> +<p></p> +</p> +</li> +<li><p class="caption" id="change-1.0.0-6"><span class="target" id="change-48f95a70e6b509811d3c6c208b3bbafc"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-48f95a70e6b509811d3c6c208b3bbafc">¶</a></span><p>Fixed bug in <code class="docutils literal notranslate"><span class="pre">decode.<encoding></span></code> filter where a non-string object +would not be correctly interpreted in Python 3.</p> +<p></p> +</p> +</li> +<li><p class="caption" id="change-1.0.0-7"><span class="target" id="change-7638baccf1cc95230c98f9475713aff4"><strong>[bug] [py3k]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7638baccf1cc95230c98f9475713aff4">¶</a></span><p>Fixed bug in Python parsing logic which would fail on Python 3 +when a “try/except” targeted a tuple of exception types, rather +than a single exception.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/227">#227</a></p> +</p> +</li> +<li><p class="caption" id="change-1.0.0-8"><span class="target" id="change-a328a21ec5123a69caf9021bbf70b90a"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a328a21ec5123a69caf9021bbf70b90a">¶</a></span><p>A rework of the mako-render script allows the script to run correctly when given a file pathname that is outside of the current directory, e.g. <code class="docutils literal notranslate"><span class="pre">mako-render</span> <span class="pre">../some_template.mako</span></code>. In this case, the “template root” defaults to the directory in which the template @@ -503,240 +808,280 @@ <code class="docutils literal notranslate"><span class="pre">--template-dir</span></code> which can be specified multiple times to establish template lookup directories. Standard input for templates also works now too. Pull request courtesy Derek Harland.</p> -<a class="changeset-link headerlink reference internal" href="#change-a328a21ec5123a69caf9021bbf70b90a">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-1.0.0-9"><span class="target" id="change-e39fabd3e579af9dd730204a7692c76f"><strong>[feature] [py3k] </strong></span><p>Support is added for Python 3 “keyword only” arguments, as used in -defs. Pull request courtesy Eevee.</p> -<a class="changeset-link headerlink reference internal" href="#change-e39fabd3e579af9dd730204a7692c76f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/pull/7">pull request github:7</a></p> +</ul> +</div> +<div class="section" id="change-1.0.0-misc"> +<h4>misc<a class="headerlink" href="#change-1.0.0-misc" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-1.0.0-9"><span class="target" id="change-b602a175c0ec26eaa4f42962d23cca96"><strong>[general]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b602a175c0ec26eaa4f42962d23cca96">¶</a></span><p>Compatibility changes; in order to modernize the codebase, Mako +is now dropping support for Python 2.4 and Python 2.5 altogether. +The source base is now targeted at Python 2.6 and forwards.</p> +<p></p> </p> </li> </ul> </div> </div> -<div class="section" id="id2"> -<h2>0.9<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h2> +</div> +<div class="section" id="id3"> +<h2>0.9<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h2> <div class="section" id="change-0.9.1"> -<h3>0.9.1<a class="headerlink" href="#change-0.9.1" title="Permalink to this headline">¶</a></h3> -Released: Thu Dec 26 2013<ul class="simple"> -<li><p id="change-0.9.1-0"><span class="target" id="change-8b4011d90ed7ddc770e03ef8ade6e6dc"><strong>[bug] </strong></span><p>Fixed bug in Babel plugin where translator comments +<h3 class="release-version">0.9.1<a class="headerlink" href="#change-0.9.1" title="Permalink to this headline">¶</a></h3> +Released: Thu Dec 26 2013<div class="section" id="change-0.9.1-bug"> +<h4>bug<a class="headerlink" href="#change-0.9.1-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.9.1-0"><span class="target" id="change-8b4011d90ed7ddc770e03ef8ade6e6dc"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-8b4011d90ed7ddc770e03ef8ade6e6dc">¶</a></span><p>Fixed bug in Babel plugin where translator comments would be lost if intervening text nodes were encountered. Fix courtesy Ned Batchelder.</p> -<a class="changeset-link headerlink reference internal" href="#change-8b4011d90ed7ddc770e03ef8ade6e6dc">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/225">#225</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/225">#225</a></p> </p> </li> -<li><p id="change-0.9.1-1"><span class="target" id="change-a7b4b7fb4a7bf5e4c0ca7c2a7b072eca"><strong>[bug] </strong></span><p>Fixed TGPlugin.render method to support unicode template +<li><p class="caption" id="change-0.9.1-1"><span class="target" id="change-a7b4b7fb4a7bf5e4c0ca7c2a7b072eca"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a7b4b7fb4a7bf5e4c0ca7c2a7b072eca">¶</a></span><p>Fixed TGPlugin.render method to support unicode template names in Py2K - courtesy Vladimir Magamedov.</p> -<a class="changeset-link headerlink reference internal" href="#change-a7b4b7fb4a7bf5e4c0ca7c2a7b072eca">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.9.1-2"><span class="target" id="change-c3dd59728d365b33fe9fcbf8ea96f9ab"><strong>[bug] </strong></span><p>Fixed an AST issue that was preventing correct operation +<li><p class="caption" id="change-0.9.1-2"><span class="target" id="change-c3dd59728d365b33fe9fcbf8ea96f9ab"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c3dd59728d365b33fe9fcbf8ea96f9ab">¶</a></span><p>Fixed an AST issue that was preventing correct operation under alpha versions of Python 3.4. Pullreq courtesy Zer0-.</p> -<a class="changeset-link headerlink reference internal" href="#change-c3dd59728d365b33fe9fcbf8ea96f9ab">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.9.1-3"><span class="target" id="change-166e48714e8db96013d1a6038e54aff4"><strong>[bug] </strong></span><p>Changed the format of the “source encoding” header output +<li><p class="caption" id="change-0.9.1-3"><span class="target" id="change-166e48714e8db96013d1a6038e54aff4"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-166e48714e8db96013d1a6038e54aff4">¶</a></span><p>Changed the format of the “source encoding” header output by the code generator to use the format <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">-*-</span> <span class="pre">coding:%s</span> <span class="pre">-*-</span></code> instead of <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">-*-</span> <span class="pre">encoding:%s</span> <span class="pre">-*-</span></code>; the former is more common and compatible with emacs. Courtesy Martin Geisler.</p> -<a class="changeset-link headerlink reference internal" href="#change-166e48714e8db96013d1a6038e54aff4">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.9.1-4"><span class="target" id="change-9a88fa8f596546fb451bfcbfa7ce6274"><strong>[bug] </strong></span><p>Fixed issue where an old lexer rule prevented a template line +<li><p class="caption" id="change-0.9.1-4"><span class="target" id="change-9a88fa8f596546fb451bfcbfa7ce6274"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9a88fa8f596546fb451bfcbfa7ce6274">¶</a></span><p>Fixed issue where an old lexer rule prevented a template line which looked like “#*” from being correctly parsed.</p> -<a class="changeset-link headerlink reference internal" href="#change-9a88fa8f596546fb451bfcbfa7ce6274">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/224">#224</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/224">#224</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-0.9.0"> -<h3>0.9.0<a class="headerlink" href="#change-0.9.0" title="Permalink to this headline">¶</a></h3> -Released: Tue Aug 27 2013<ul class="simple"> -<li><p id="change-0.9.0-0"><span class="target" id="change-f529d0d5bf50c9e01e436ee12672a7f8"><strong>[bug] </strong></span><p>The Context.locals_() method becomes a private underscored +<h3 class="release-version">0.9.0<a class="headerlink" href="#change-0.9.0" title="Permalink to this headline">¶</a></h3> +Released: Tue Aug 27 2013<div class="section" id="change-0.9.0-bug"> +<h4>bug<a class="headerlink" href="#change-0.9.0-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.9.0-0"><span class="target" id="change-f529d0d5bf50c9e01e436ee12672a7f8"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f529d0d5bf50c9e01e436ee12672a7f8">¶</a></span><p>The Context.locals_() method becomes a private underscored method, as this method has a specific internal use. The purpose of Context.kwargs has been clarified, in that it only delivers top level keyword arguments originally passed to template.render().</p> -<a class="changeset-link headerlink reference internal" href="#change-f529d0d5bf50c9e01e436ee12672a7f8">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/219">#219</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/219">#219</a></p> </p> </li> -<li><p id="change-0.9.0-1"><span class="target" id="change-41a0ced688ee0a615dcddf766d267241"><strong>[bug] </strong></span><p>Fixed the babel plugin to properly interpret ${} sections +<li><p class="caption" id="change-0.9.0-1"><span class="target" id="change-41a0ced688ee0a615dcddf766d267241"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-41a0ced688ee0a615dcddf766d267241">¶</a></span><p>Fixed the babel plugin to properly interpret ${} sections inside of a “call” tag, i.e. <%self:some_tag attr=”${_(‘foo’)}”/>. Code that’s subject to babel escapes in here needs to be specified as a Python expression, not a literal. This change is backwards incompatible vs. code that is relying upon a _(‘’) translation to be working within a call tag.</p> -<a class="changeset-link headerlink reference internal" href="#change-41a0ced688ee0a615dcddf766d267241">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.9.0-2"><span class="target" id="change-ac972a0d002a412c4a92175229d7444f"><strong>[bug] </strong></span><p>The Babel plugin has been repaired to work on Python 3.</p> -<a class="changeset-link headerlink reference internal" href="#change-ac972a0d002a412c4a92175229d7444f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/187">#187</a></p> +<li><p class="caption" id="change-0.9.0-2"><span class="target" id="change-ac972a0d002a412c4a92175229d7444f"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ac972a0d002a412c4a92175229d7444f">¶</a></span><p>The Babel plugin has been repaired to work on Python 3.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/187">#187</a></p> </p> </li> -<li><p id="change-0.9.0-3"><span class="target" id="change-dbf6f29e5e76133b9dd779baacb24818"><strong>[bug] </strong></span><p>Using <%namespace import=”*” module=”somemodule”/> now +<li><p class="caption" id="change-0.9.0-3"><span class="target" id="change-dbf6f29e5e76133b9dd779baacb24818"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-dbf6f29e5e76133b9dd779baacb24818">¶</a></span><p>Using <%namespace import=”*” module=”somemodule”/> now skips over module elements that are not explcitly callable, avoiding TypeError when trying to produce partials.</p> -<a class="changeset-link headerlink reference internal" href="#change-dbf6f29e5e76133b9dd779baacb24818">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/207">#207</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/207">#207</a></p> </p> </li> -<li><p id="change-0.9.0-4"><span class="target" id="change-693045b580eddfdc7e464ba0426b3495"><strong>[bug] </strong></span><p>Fixed Py3K bug where a “lambda” expression was not +<li><p class="caption" id="change-0.9.0-4"><span class="target" id="change-693045b580eddfdc7e464ba0426b3495"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-693045b580eddfdc7e464ba0426b3495">¶</a></span><p>Fixed Py3K bug where a “lambda” expression was not interpreted correctly within a template tag; also fixed in Py2.4.</p> -<a class="changeset-link headerlink reference internal" href="#change-693045b580eddfdc7e464ba0426b3495">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/190">#190</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/190">#190</a></p> </p> </li> </ul> </div> </div> -<div class="section" id="id3"> -<h2>0.8<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h2> -<div class="section" id="change-0.8.1"> -<h3>0.8.1<a class="headerlink" href="#change-0.8.1" title="Permalink to this headline">¶</a></h3> -Released: Fri May 24 2013<ul class="simple"> -<li><p id="change-0.8.1-0"><span class="target" id="change-bd4b9d8ffbf32fc1b15161268eefa4d3"><strong>[bug] </strong></span><p>Changed setup.py to skip installing markupsafe -if Python version is < 2.6 or is between 3.0 and -less than 3.3, as Markupsafe now only supports 2.6->2.X, -3.3->3.X.</p> -<a class="changeset-link headerlink reference internal" href="#change-bd4b9d8ffbf32fc1b15161268eefa4d3">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/216">#216</a></p> -</p> -</li> -<li><p id="change-0.8.1-1"><span class="target" id="change-422ca71aa24f94eb264fc0d653dc726e"><strong>[bug] </strong></span><p>Fixed regression where “entity” filter wasn’t -converted for py3k properly (added tests.)</p> -<a class="changeset-link headerlink reference internal" href="#change-422ca71aa24f94eb264fc0d653dc726e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/214">#214</a></p> -</p> -</li> -<li><p id="change-0.8.1-2"><span class="target" id="change-32c8f2eaa85fc02c7f1908ade43391a6"><strong>[bug] </strong></span><p>Fixed bug where mako-render script wasn’t -compatible with Py3k.</p> -<a class="changeset-link headerlink reference internal" href="#change-32c8f2eaa85fc02c7f1908ade43391a6">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/212">#212</a></p> -</p> -</li> -<li><p id="change-0.8.1-3"><span class="target" id="change-3493666706cc97f02aa1454a0bfa8b05"><strong>[bug] </strong></span><p>Cleaned up all the various deprecation/ -file warnings when running the tests under -various Pythons with warnings turned on.</p> -<a class="changeset-link headerlink reference internal" href="#change-3493666706cc97f02aa1454a0bfa8b05">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/213">#213</a></p> -</p> -</li> -</ul> -</div> -<div class="section" id="change-0.8.0"> -<h3>0.8.0<a class="headerlink" href="#change-0.8.0" title="Permalink to this headline">¶</a></h3> -Released: Wed Apr 10 2013<ul class="simple"> -<li><p id="change-0.8.0-0"><span class="target" id="change-6b0ea675bf69869d3082ead0019268ac"><strong>[feature] </strong></span><p>Performance improvement to the -“legacy” HTML escape feature, used for XML -escaping and when markupsafe isn’t present, -courtesy George Xie.</p> -<a class="changeset-link headerlink reference internal" href="#change-6b0ea675bf69869d3082ead0019268ac">¶</a><p></p> -</p> -</li> -<li><p id="change-0.8.0-1"><span class="target" id="change-9a75951207d1a79183ecde188ec6dc0f"><strong>[bug] </strong></span><p>Fixed bug whereby an exception in Python 3 -against a module compiled to the filesystem would -fail trying to produce a RichTraceback due to the -content being in bytes.</p> -<a class="changeset-link headerlink reference internal" href="#change-9a75951207d1a79183ecde188ec6dc0f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/209">#209</a></p> -</p> -</li> -<li><p id="change-0.8.0-2"><span class="target" id="change-c3d6a16577c7159388068ce214713af5"><strong>[bug] </strong></span><p>Change default for compile()->reserved_names -from tuple to frozenset, as this is expected to be -a set by default.</p> -<a class="changeset-link headerlink reference internal" href="#change-c3d6a16577c7159388068ce214713af5">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/208">#208</a></p> -</p> -</li> -<li><p id="change-0.8.0-3"><span class="target" id="change-eaf9d70768b7b2e3bf37574dc5776ddb"><strong>[feature] </strong></span><p>Code has been reworked to support Python 2.4-> -Python 3.xx in place. 2to3 no longer needed.</p> -<a class="changeset-link headerlink reference internal" href="#change-eaf9d70768b7b2e3bf37574dc5776ddb">¶</a><p></p> -</p> -</li> -<li><p id="change-0.8.0-4"><span class="target" id="change-26eea0f7e4b73fcb7f112ad6fff7181d"><strong>[feature] </strong></span><p>Added lexer_cls argument to Template, -TemplateLookup, allows alternate Lexer classes -to be used.</p> -<a class="changeset-link headerlink reference internal" href="#change-26eea0f7e4b73fcb7f112ad6fff7181d">¶</a><p></p> -</p> -</li> -<li><p id="change-0.8.0-5"><span class="target" id="change-b7ef07a547af42dd2677a0ee710a88d8"><strong>[feature] </strong></span><p>Added future_imports parameter to Template -and TemplateLookup, renders the __future__ header -with desired capabilities at the top of the generated -template module. Courtesy Ben Trofatter.</p> -<a class="changeset-link headerlink reference internal" href="#change-b7ef07a547af42dd2677a0ee710a88d8">¶</a><p></p> -</p> -</li> -</ul> -</div> </div> <div class="section" id="id4"> -<h2>0.7<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h2> +<h2>0.8<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h2> +<div class="section" id="change-0.8.1"> +<h3 class="release-version">0.8.1<a class="headerlink" href="#change-0.8.1" title="Permalink to this headline">¶</a></h3> +Released: Fri May 24 2013<div class="section" id="change-0.8.1-bug"> +<h4>bug<a class="headerlink" href="#change-0.8.1-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.8.1-0"><span class="target" id="change-bd4b9d8ffbf32fc1b15161268eefa4d3"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-bd4b9d8ffbf32fc1b15161268eefa4d3">¶</a></span><p>Changed setup.py to skip installing markupsafe +if Python version is < 2.6 or is between 3.0 and +less than 3.3, as Markupsafe now only supports 2.6->2.X, +3.3->3.X.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/216">#216</a></p> +</p> +</li> +<li><p class="caption" id="change-0.8.1-1"><span class="target" id="change-422ca71aa24f94eb264fc0d653dc726e"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-422ca71aa24f94eb264fc0d653dc726e">¶</a></span><p>Fixed regression where “entity” filter wasn’t +converted for py3k properly (added tests.)</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/214">#214</a></p> +</p> +</li> +<li><p class="caption" id="change-0.8.1-2"><span class="target" id="change-32c8f2eaa85fc02c7f1908ade43391a6"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-32c8f2eaa85fc02c7f1908ade43391a6">¶</a></span><p>Fixed bug where mako-render script wasn’t +compatible with Py3k.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/212">#212</a></p> +</p> +</li> +<li><p class="caption" id="change-0.8.1-3"><span class="target" id="change-3493666706cc97f02aa1454a0bfa8b05"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-3493666706cc97f02aa1454a0bfa8b05">¶</a></span><p>Cleaned up all the various deprecation/ +file warnings when running the tests under +various Pythons with warnings turned on.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/213">#213</a></p> +</p> +</li> +</ul> +</div> +</div> +<div class="section" id="change-0.8.0"> +<h3 class="release-version">0.8.0<a class="headerlink" href="#change-0.8.0" title="Permalink to this headline">¶</a></h3> +Released: Wed Apr 10 2013<div class="section" id="change-0.8.0-feature"> +<h4>feature<a class="headerlink" href="#change-0.8.0-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.8.0-0"><span class="target" id="change-6b0ea675bf69869d3082ead0019268ac"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6b0ea675bf69869d3082ead0019268ac">¶</a></span><p>Performance improvement to the +“legacy” HTML escape feature, used for XML +escaping and when markupsafe isn’t present, +courtesy George Xie.</p> +<p></p> +</p> +</li> +<li><p class="caption" id="change-0.8.0-1"><span class="target" id="change-eaf9d70768b7b2e3bf37574dc5776ddb"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-eaf9d70768b7b2e3bf37574dc5776ddb">¶</a></span><p>Code has been reworked to support Python 2.4-> +Python 3.xx in place. 2to3 no longer needed.</p> +<p></p> +</p> +</li> +<li><p class="caption" id="change-0.8.0-2"><span class="target" id="change-26eea0f7e4b73fcb7f112ad6fff7181d"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-26eea0f7e4b73fcb7f112ad6fff7181d">¶</a></span><p>Added lexer_cls argument to Template, +TemplateLookup, allows alternate Lexer classes +to be used.</p> +<p></p> +</p> +</li> +<li><p class="caption" id="change-0.8.0-3"><span class="target" id="change-b7ef07a547af42dd2677a0ee710a88d8"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b7ef07a547af42dd2677a0ee710a88d8">¶</a></span><p>Added future_imports parameter to Template +and TemplateLookup, renders the __future__ header +with desired capabilities at the top of the generated +template module. Courtesy Ben Trofatter.</p> +<p></p> +</p> +</li> +</ul> +</div> +<div class="section" id="change-0.8.0-bug"> +<h4>bug<a class="headerlink" href="#change-0.8.0-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.8.0-4"><span class="target" id="change-9a75951207d1a79183ecde188ec6dc0f"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9a75951207d1a79183ecde188ec6dc0f">¶</a></span><p>Fixed bug whereby an exception in Python 3 +against a module compiled to the filesystem would +fail trying to produce a RichTraceback due to the +content being in bytes.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/209">#209</a></p> +</p> +</li> +<li><p class="caption" id="change-0.8.0-5"><span class="target" id="change-c3d6a16577c7159388068ce214713af5"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c3d6a16577c7159388068ce214713af5">¶</a></span><p>Change default for compile()->reserved_names +from tuple to frozenset, as this is expected to be +a set by default.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/208">#208</a></p> +</p> +</li> +</ul> +</div> +</div> +</div> +<div class="section" id="id5"> +<h2>0.7<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h2> <div class="section" id="change-0.7.3"> -<h3>0.7.3<a class="headerlink" href="#change-0.7.3" title="Permalink to this headline">¶</a></h3> -Released: Wed Nov 7 2012<ul class="simple"> -<li><p id="change-0.7.3-0"><span class="target" id="change-5b7ac5083658b50ef3156f602a6fbc7f"><strong>[bug] </strong></span><p>legacy_html_escape function, used when +<h3 class="release-version">0.7.3<a class="headerlink" href="#change-0.7.3" title="Permalink to this headline">¶</a></h3> +Released: Wed Nov 7 2012<div class="section" id="change-0.7.3-bug"> +<h4>bug<a class="headerlink" href="#change-0.7.3-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.7.3-0"><span class="target" id="change-5b7ac5083658b50ef3156f602a6fbc7f"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5b7ac5083658b50ef3156f602a6fbc7f">¶</a></span><p>legacy_html_escape function, used when Markupsafe isn’t installed, was using an inline-compiled regexp which causes major slowdowns on Python 3.3; is now precompiled.</p> -<a class="changeset-link headerlink reference internal" href="#change-5b7ac5083658b50ef3156f602a6fbc7f">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.7.3-1"><span class="target" id="change-591582542cc9469802a12b959ae762fa"><strong>[bug] </strong></span><p>AST supporting now supports tuple-packed +<li><p class="caption" id="change-0.7.3-1"><span class="target" id="change-591582542cc9469802a12b959ae762fa"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-591582542cc9469802a12b959ae762fa">¶</a></span><p>AST supporting now supports tuple-packed function arguments inside pure-python def or lambda expressions.</p> -<a class="changeset-link headerlink reference internal" href="#change-591582542cc9469802a12b959ae762fa">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/201">#201</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/201">#201</a></p> </p> </li> -<li><p id="change-0.7.3-2"><span class="target" id="change-3b3a50e075d4d15358ec199aa7c10fa0"><strong>[bug] </strong></span><p>Fixed Py3K bug in the Babel extension.</p> -<a class="changeset-link headerlink reference internal" href="#change-3b3a50e075d4d15358ec199aa7c10fa0">¶</a><p></p> +<li><p class="caption" id="change-0.7.3-2"><span class="target" id="change-3b3a50e075d4d15358ec199aa7c10fa0"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-3b3a50e075d4d15358ec199aa7c10fa0">¶</a></span><p>Fixed Py3K bug in the Babel extension.</p> +<p></p> </p> </li> -<li><p id="change-0.7.3-3"><span class="target" id="change-535675bd3ae6ed887cfebf09a83d4311"><strong>[bug] </strong></span><p>Fixed the “filter” attribute of the +<li><p class="caption" id="change-0.7.3-3"><span class="target" id="change-535675bd3ae6ed887cfebf09a83d4311"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-535675bd3ae6ed887cfebf09a83d4311">¶</a></span><p>Fixed the “filter” attribute of the <%text> tag so that it pulls locally specified identifiers from the context the same way as that of <%block> and <%filter>.</p> -<a class="changeset-link headerlink reference internal" href="#change-535675bd3ae6ed887cfebf09a83d4311">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.7.3-4"><span class="target" id="change-618340e118c47998e9a6a21d3dfeab3c"><strong>[bug] </strong></span><p>Fixed bug in plugin loader to correctly +<li><p class="caption" id="change-0.7.3-4"><span class="target" id="change-618340e118c47998e9a6a21d3dfeab3c"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-618340e118c47998e9a6a21d3dfeab3c">¶</a></span><p>Fixed bug in plugin loader to correctly raise exception when non-existent plugin is specified.</p> -<a class="changeset-link headerlink reference internal" href="#change-618340e118c47998e9a6a21d3dfeab3c">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-0.7.2"> -<h3>0.7.2<a class="headerlink" href="#change-0.7.2" title="Permalink to this headline">¶</a></h3> -Released: Fri Jul 20 2012<ul class="simple"> -<li><p id="change-0.7.2-0"><span class="target" id="change-24885c510552de270fdab999df4d3ee3"><strong>[bug] </strong></span><p>Fixed regression in 0.7.1 where AST +<h3 class="release-version">0.7.2<a class="headerlink" href="#change-0.7.2" title="Permalink to this headline">¶</a></h3> +Released: Fri Jul 20 2012<div class="section" id="change-0.7.2-bug"> +<h4>bug<a class="headerlink" href="#change-0.7.2-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.7.2-0"><span class="target" id="change-24885c510552de270fdab999df4d3ee3"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-24885c510552de270fdab999df4d3ee3">¶</a></span><p>Fixed regression in 0.7.1 where AST parsing for Py2.4 was broken.</p> -<a class="changeset-link headerlink reference internal" href="#change-24885c510552de270fdab999df4d3ee3">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/193">#193</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/193">#193</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-0.7.1"> -<h3>0.7.1<a class="headerlink" href="#change-0.7.1" title="Permalink to this headline">¶</a></h3> -Released: Sun Jul 8 2012<ul class="simple"> -<li><p id="change-0.7.1-0"><span class="target" id="change-52ee3c2b0c1b4d4444ec4e93c7aafa2b"><strong>[feature] </strong></span><p>Control lines with no bodies will +<h3 class="release-version">0.7.1<a class="headerlink" href="#change-0.7.1" title="Permalink to this headline">¶</a></h3> +Released: Sun Jul 8 2012<div class="section" id="change-0.7.1-feature"> +<h4>feature<a class="headerlink" href="#change-0.7.1-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.7.1-0"><span class="target" id="change-52ee3c2b0c1b4d4444ec4e93c7aafa2b"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-52ee3c2b0c1b4d4444ec4e93c7aafa2b">¶</a></span><p>Control lines with no bodies will now succeed, as “pass” is added for these when no statements are otherwise present. Courtesy Ben Trofatter</p> -<a class="changeset-link headerlink reference internal" href="#change-52ee3c2b0c1b4d4444ec4e93c7aafa2b">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/146">#146</a></p> -</p> -</li> -<li><p id="change-0.7.1-1"><span class="target" id="change-149cdf4c14f9bacfe6dfa61ce8379d4e"><strong>[bug] </strong></span><p>Fixed some long-broken scoping behavior -involving variables declared in defs and such, -which only became apparent when -the strict_undefined flag was turned on.</p> -<a class="changeset-link headerlink reference internal" href="#change-149cdf4c14f9bacfe6dfa61ce8379d4e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/192">#192</a></p> -</p> -</li> -<li><p id="change-0.7.1-2"><span class="target" id="change-28b06199f79ad5944ce27c6ca795912e"><strong>[bug] </strong></span><p>Can now use strict_undefined at the -same time args passed to def() are used -by other elements of the <%def> tag.</p> -<a class="changeset-link headerlink reference internal" href="#change-28b06199f79ad5944ce27c6ca795912e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/191">#191</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/146">#146</a></p> </p> </li> </ul> </div> +<div class="section" id="change-0.7.1-bug"> +<h4>bug<a class="headerlink" href="#change-0.7.1-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.7.1-1"><span class="target" id="change-149cdf4c14f9bacfe6dfa61ce8379d4e"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-149cdf4c14f9bacfe6dfa61ce8379d4e">¶</a></span><p>Fixed some long-broken scoping behavior +involving variables declared in defs and such, +which only became apparent when +the strict_undefined flag was turned on.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/192">#192</a></p> +</p> +</li> +<li><p class="caption" id="change-0.7.1-2"><span class="target" id="change-28b06199f79ad5944ce27c6ca795912e"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-28b06199f79ad5944ce27c6ca795912e">¶</a></span><p>Can now use strict_undefined at the +same time args passed to def() are used +by other elements of the <%def> tag.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/191">#191</a></p> +</p> +</li> +</ul> +</div> +</div> <div class="section" id="change-0.7.0"> -<h3>0.7.0<a class="headerlink" href="#change-0.7.0" title="Permalink to this headline">¶</a></h3> -Released: Fri Mar 30 2012<ul class="simple"> -<li><p id="change-0.7.0-0"><span class="target" id="change-99281e61032772527b9b88fa8420e86a"><strong>[feature] </strong></span><p>Added new “loop” variable to templates, +<h3 class="release-version">0.7.0<a class="headerlink" href="#change-0.7.0" title="Permalink to this headline">¶</a></h3> +Released: Fri Mar 30 2012<div class="section" id="change-0.7.0-feature"> +<h4>feature<a class="headerlink" href="#change-0.7.0-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.7.0-0"><span class="target" id="change-99281e61032772527b9b88fa8420e86a"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-99281e61032772527b9b88fa8420e86a">¶</a></span><p>Added new “loop” variable to templates, is provided within a % for block to provide info about the loop such as index, first/last, odd/even, etc. A migration path is also provided @@ -744,85 +1089,99 @@ available on Template, TemplateLookup, and <%page>. Thanks to Ben Trofatter for all the work on this</p> -<a class="changeset-link headerlink reference internal" href="#change-99281e61032772527b9b88fa8420e86a">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/125">#125</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/125">#125</a></p> </p> </li> -<li><p id="change-0.7.0-1"><span class="target" id="change-7e9210f880731443d88f862a56ff6279"><strong>[feature] </strong></span><p>Added a real check for “reserved” +<li><p class="caption" id="change-0.7.0-1"><span class="target" id="change-7e9210f880731443d88f862a56ff6279"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7e9210f880731443d88f862a56ff6279">¶</a></span><p>Added a real check for “reserved” names, that is names which are never pulled from the context and cannot be passed to the template.render() method. Current names are “context”, “loop”, “UNDEFINED”.</p> -<a class="changeset-link headerlink reference internal" href="#change-7e9210f880731443d88f862a56ff6279">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.7.0-2"><span class="target" id="change-e3c973cf437f4220015f2d5107b90685"><strong>[feature] </strong></span><p>The html_error_template() will now +<li><p class="caption" id="change-0.7.0-2"><span class="target" id="change-e3c973cf437f4220015f2d5107b90685"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e3c973cf437f4220015f2d5107b90685">¶</a></span><p>The html_error_template() will now apply Pygments highlighting to the source code displayed in the traceback, if Pygments if available. Courtesy Ben Trofatter</p> -<a class="changeset-link headerlink reference internal" href="#change-e3c973cf437f4220015f2d5107b90685">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/95">#95</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/95">#95</a></p> </p> </li> -<li><p id="change-0.7.0-3"><span class="target" id="change-3fe398b17c8a48c37534222a31cb6e95"><strong>[feature] </strong></span><p>Added support for context managers, +<li><p class="caption" id="change-0.7.0-3"><span class="target" id="change-3fe398b17c8a48c37534222a31cb6e95"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-3fe398b17c8a48c37534222a31cb6e95">¶</a></span><p>Added support for context managers, i.e. “% with x as e:/ % endwith” support. Courtesy Ben Trofatter</p> -<a class="changeset-link headerlink reference internal" href="#change-3fe398b17c8a48c37534222a31cb6e95">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/147">#147</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/147">#147</a></p> </p> </li> -<li><p id="change-0.7.0-4"><span class="target" id="change-4071228d8de4b33e68b6655b7e55324b"><strong>[feature] </strong></span><p>Added class-level flag to CacheImpl +<li><p class="caption" id="change-0.7.0-4"><span class="target" id="change-4071228d8de4b33e68b6655b7e55324b"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4071228d8de4b33e68b6655b7e55324b">¶</a></span><p>Added class-level flag to CacheImpl “pass_context”; when True, the keyword argument ‘context’ will be passed to get_or_create() containing the Mako Context object.</p> -<a class="changeset-link headerlink reference internal" href="#change-4071228d8de4b33e68b6655b7e55324b">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/185">#185</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/185">#185</a></p> </p> </li> -<li><p id="change-0.7.0-5"><span class="target" id="change-9992c56ef372da93242c0408fde81739"><strong>[bug] </strong></span><p>Fixed some Py3K resource warnings due -to filehandles being implicitly closed.</p> -<a class="changeset-link headerlink reference internal" href="#change-9992c56ef372da93242c0408fde81739">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/182">#182</a></p> -</p> -</li> -<li><p id="change-0.7.0-6"><span class="target" id="change-99f0e301249bf150b6a9aa25f7271be5"><strong>[bug] </strong></span><p>Fixed endless recursion bug when -nesting multiple def-calls with content. -Thanks to Jeff Dairiki.</p> -<a class="changeset-link headerlink reference internal" href="#change-99f0e301249bf150b6a9aa25f7271be5">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/186">#186</a></p> -</p> -</li> -<li><p id="change-0.7.0-7"><span class="target" id="change-5a11b79be7c693f1faf8601f7f61ddfe"><strong>[feature] </strong></span><p>Added Jinja2 to the example +<li><p class="caption" id="change-0.7.0-5"><span class="target" id="change-5a11b79be7c693f1faf8601f7f61ddfe"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5a11b79be7c693f1faf8601f7f61ddfe">¶</a></span><p>Added Jinja2 to the example benchmark suite, courtesy Vincent Férotin</p> -<a class="changeset-link headerlink reference internal" href="#change-5a11b79be7c693f1faf8601f7f61ddfe">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +<div class="section" id="change-0.7.0-bug"> +<h4>bug<a class="headerlink" href="#change-0.7.0-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.7.0-6"><span class="target" id="change-9992c56ef372da93242c0408fde81739"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9992c56ef372da93242c0408fde81739">¶</a></span><p>Fixed some Py3K resource warnings due +to filehandles being implicitly closed.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/182">#182</a></p> +</p> +</li> +<li><p class="caption" id="change-0.7.0-7"><span class="target" id="change-99f0e301249bf150b6a9aa25f7271be5"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-99f0e301249bf150b6a9aa25f7271be5">¶</a></span><p>Fixed endless recursion bug when +nesting multiple def-calls with content. +Thanks to Jeff Dairiki.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/186">#186</a></p> +</p> +</li> +</ul> +</div> +</div> </div> <div class="section" id="older-versions"> <h2>Older Versions<a class="headerlink" href="#older-versions" title="Permalink to this headline">¶</a></h2> <div class="section" id="change-0.6.2"> -<h3>0.6.2<a class="headerlink" href="#change-0.6.2" title="Permalink to this headline">¶</a></h3> -Released: Thu Feb 2 2012<ul class="simple"> -<li><p id="change-0.6.2-0"><span class="target" id="change-9b201e18db55b80dfdde3ccedde47930"><strong>[bug] </strong></span><p>The ${{“foo”:”bar”}} parsing issue is fixed!! +<h3 class="release-version">0.6.2<a class="headerlink" href="#change-0.6.2" title="Permalink to this headline">¶</a></h3> +Released: Thu Feb 2 2012<div class="section" id="change-0.6.2-bug"> +<h4>bug<a class="headerlink" href="#change-0.6.2-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.6.2-0"><span class="target" id="change-9b201e18db55b80dfdde3ccedde47930"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9b201e18db55b80dfdde3ccedde47930">¶</a></span><p>The ${{“foo”:”bar”}} parsing issue is fixed!! The legendary Eevee has slain the dragon!. Also fixes quoting issue at.</p> -<a class="changeset-link headerlink reference internal" href="#change-9b201e18db55b80dfdde3ccedde47930">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/20">#20</a>, <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/86">#86</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/20">#20</a>, <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/86">#86</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-0.6.1"> -<h3>0.6.1<a class="headerlink" href="#change-0.6.1" title="Permalink to this headline">¶</a></h3> -Released: Sat Jan 28 2012<ul class="simple"> -<li><p id="change-0.6.1-0"><span class="target" id="change-cfec33b6e59137a9512e1f1395305774"><strong>[bug] </strong></span><p>Added special compatibility for the 0.5.0 +<h3 class="release-version">0.6.1<a class="headerlink" href="#change-0.6.1" title="Permalink to this headline">¶</a></h3> +Released: Sat Jan 28 2012<div class="section" id="change-0.6.1-bug"> +<h4>bug<a class="headerlink" href="#change-0.6.1-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.6.1-0"><span class="target" id="change-cfec33b6e59137a9512e1f1395305774"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-cfec33b6e59137a9512e1f1395305774">¶</a></span><p>Added special compatibility for the 0.5.0 Cache() constructor, which was preventing file version checks and not allowing Mako 0.6 to recompile the module files.</p> -<a class="changeset-link headerlink reference internal" href="#change-cfec33b6e59137a9512e1f1395305774">¶</a><p></p> +<p></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-0.6.0"> -<h3>0.6.0<a class="headerlink" href="#change-0.6.0" title="Permalink to this headline">¶</a></h3> -Released: Sat Jan 21 2012<ul class="simple"> -<li><p id="change-0.6.0-0"><span class="target" id="change-2b9d5caf9d33544a386cc21b37a81524"><strong>[feature] </strong></span><p>Template caching has been converted into a plugin +<h3 class="release-version">0.6.0<a class="headerlink" href="#change-0.6.0" title="Permalink to this headline">¶</a></h3> +Released: Sat Jan 21 2012<div class="section" id="change-0.6.0-feature"> +<h4>feature<a class="headerlink" href="#change-0.6.0-feature" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.6.0-0"><span class="target" id="change-2b9d5caf9d33544a386cc21b37a81524"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-2b9d5caf9d33544a386cc21b37a81524">¶</a></span><p>Template caching has been converted into a plugin system, whereby the usage of Beaker is just the default plugin. Template and TemplateLookup now accept a string “cache_impl” parameter which @@ -833,83 +1192,94 @@ using mako.cache.register_plugin(). The core plugin is the mako.cache.CacheImpl class.</p> -<a class="changeset-link headerlink reference internal" href="#change-2b9d5caf9d33544a386cc21b37a81524">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.6.0-1"><span class="target" id="change-6296089f9cbb6d381f1307e8c87903b3"><strong>[feature] </strong></span><p>Added support for Beaker cache regions +<li><p class="caption" id="change-0.6.0-1"><span class="target" id="change-6296089f9cbb6d381f1307e8c87903b3"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6296089f9cbb6d381f1307e8c87903b3">¶</a></span><p>Added support for Beaker cache regions in templates. Usage of regions should be considered as superseding the very obsolete idea of passing in backend options, timeouts, etc. within templates.</p> -<a class="changeset-link headerlink reference internal" href="#change-6296089f9cbb6d381f1307e8c87903b3">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.6.0-2"><span class="target" id="change-0843fd024a1d50547e36cb04a4e8b78a"><strong>[feature] </strong></span><p>The ‘put’ method on Cache is now +<li><p class="caption" id="change-0.6.0-2"><span class="target" id="change-0843fd024a1d50547e36cb04a4e8b78a"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0843fd024a1d50547e36cb04a4e8b78a">¶</a></span><p>The ‘put’ method on Cache is now ‘set’. ‘put’ is there for backwards compatibility.</p> -<a class="changeset-link headerlink reference internal" href="#change-0843fd024a1d50547e36cb04a4e8b78a">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.6.0-3"><span class="target" id="change-4f115c692e6156a01ef13450ebbd33dc"><strong>[feature] </strong></span><p>The <%def>, <%block> and <%page> tags now accept +<li><p class="caption" id="change-0.6.0-3"><span class="target" id="change-4f115c692e6156a01ef13450ebbd33dc"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4f115c692e6156a01ef13450ebbd33dc">¶</a></span><p>The <%def>, <%block> and <%page> tags now accept any argument named “cache_*”, and the key -minus the “<a href="#id11"><span class="problematic" id="id12">cache_</span></a>” prefix will be passed as keyword +minus the “<a href="#id6"><span class="problematic" id="id7">cache_</span></a>” prefix will be passed as keyword arguments to the CacheImpl methods.</p> -<a class="changeset-link headerlink reference internal" href="#change-4f115c692e6156a01ef13450ebbd33dc">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.6.0-4"><span class="target" id="change-7a7b3c617612239ebce8bf870d937090"><strong>[feature] </strong></span><p>Template and TemplateLookup now accept an argument +<li><p class="caption" id="change-0.6.0-4"><span class="target" id="change-7a7b3c617612239ebce8bf870d937090"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7a7b3c617612239ebce8bf870d937090">¶</a></span><p>Template and TemplateLookup now accept an argument cache_args, which refers to a dictionary containing cache parameters. The cache_dir, cache_url, cache_type, cache_timeout arguments are deprecated (will probably never be removed, however) and can be passed now as cache_args={‘url’:<some url>, ‘type’:’memcached’, ‘timeout’:50, ‘dir’:’/path/to/some/directory’}</p> -<a class="changeset-link headerlink reference internal" href="#change-7a7b3c617612239ebce8bf870d937090">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.6.0-5"><span class="target" id="change-d114a1d74a7437b6c3aabe27990a6ed2"><strong>[feature/bug] </strong></span><p>Can now refer to context variables +<li><p class="caption" id="change-0.6.0-5"><span class="target" id="change-9f5fae46c69a1c75f7490adf375f8050"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9f5fae46c69a1c75f7490adf375f8050">¶</a></span><p>Added “–var name=value” option to the mako-render +script, allows passing of kw to the template from +the command line.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/178">#178</a></p> +</p> +</li> +<li><p class="caption" id="change-0.6.0-6"><span class="target" id="change-ee72323bae6ecd6f7f0412b687fea6b1"><strong>[feature]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ee72323bae6ecd6f7f0412b687fea6b1">¶</a></span><p>Added module_writer argument to Template, +TemplateLookup, allows a callable to be passed which +takes over the writing of the template’s module source +file, so that special environment-specific steps +can be taken.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/181">#181</a></p> +</p> +</li> +</ul> +</div> +<div class="section" id="change-0.6.0-bug"> +<h4>bug<a class="headerlink" href="#change-0.6.0-bug" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.6.0-7"><span class="target" id="change-460448904caed525985e90d2fe23dc6f"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-460448904caed525985e90d2fe23dc6f">¶</a></span><p>The exception message in the html_error_template +is now escaped with the HTML filter.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/142">#142</a></p> +</p> +</li> +<li><p class="caption" id="change-0.6.0-8"><span class="target" id="change-0f53470e3d2ace00fedfec05980570bf"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0f53470e3d2ace00fedfec05980570bf">¶</a></span><p>Added “white-space:pre” style to html_error_template() +for code blocks so that indentation is preserved</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/173">#173</a></p> +</p> +</li> +<li><p class="caption" id="change-0.6.0-9"><span class="target" id="change-a268e715c3a48b1d2e6651948d9f6739"><strong>[bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a268e715c3a48b1d2e6651948d9f6739">¶</a></span><p>The “benchmark” example is now Python 3 compatible +(even though several of those old template libs aren’t +available on Py3K, so YMMV)</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/175">#175</a></p> +</p> +</li> +</ul> +</div> +<div class="section" id="change-0.6.0-misc"> +<h4>misc<a class="headerlink" href="#change-0.6.0-misc" title="Permalink to this headline">¶</a></h4> +<ul class="simple"> +<li><p class="caption" id="change-0.6.0-10"><span class="target" id="change-d114a1d74a7437b6c3aabe27990a6ed2"><strong>[feature/bug]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d114a1d74a7437b6c3aabe27990a6ed2">¶</a></span><p>Can now refer to context variables within extra arguments to <%block>, <%def>, i.e. <%block name=”foo” cache_key=”${somekey}”>. Filters can also be used in this way, i.e. <%def name=”foo()” filter=”myfilter”> then template.render(myfilter=some_callable)</p> -<a class="changeset-link headerlink reference internal" href="#change-d114a1d74a7437b6c3aabe27990a6ed2">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/180">#180</a></p> -</p> -</li> -<li><p id="change-0.6.0-6"><span class="target" id="change-9f5fae46c69a1c75f7490adf375f8050"><strong>[feature] </strong></span><p>Added “–var name=value” option to the mako-render -script, allows passing of kw to the template from -the command line.</p> -<a class="changeset-link headerlink reference internal" href="#change-9f5fae46c69a1c75f7490adf375f8050">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/178">#178</a></p> -</p> -</li> -<li><p id="change-0.6.0-7"><span class="target" id="change-ee72323bae6ecd6f7f0412b687fea6b1"><strong>[feature] </strong></span><p>Added module_writer argument to Template, -TemplateLookup, allows a callable to be passed which -takes over the writing of the template’s module source -file, so that special environment-specific steps -can be taken.</p> -<a class="changeset-link headerlink reference internal" href="#change-ee72323bae6ecd6f7f0412b687fea6b1">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/181">#181</a></p> -</p> -</li> -<li><p id="change-0.6.0-8"><span class="target" id="change-460448904caed525985e90d2fe23dc6f"><strong>[bug] </strong></span><p>The exception message in the html_error_template -is now escaped with the HTML filter.</p> -<a class="changeset-link headerlink reference internal" href="#change-460448904caed525985e90d2fe23dc6f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/142">#142</a></p> -</p> -</li> -<li><p id="change-0.6.0-9"><span class="target" id="change-0f53470e3d2ace00fedfec05980570bf"><strong>[bug] </strong></span><p>Added “white-space:pre” style to html_error_template() -for code blocks so that indentation is preserved</p> -<a class="changeset-link headerlink reference internal" href="#change-0f53470e3d2ace00fedfec05980570bf">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/173">#173</a></p> -</p> -</li> -<li><p id="change-0.6.0-10"><span class="target" id="change-a268e715c3a48b1d2e6651948d9f6739"><strong>[bug] </strong></span><p>The “benchmark” example is now Python 3 compatible -(even though several of those old template libs aren’t -available on Py3K, so YMMV)</p> -<a class="changeset-link headerlink reference internal" href="#change-a268e715c3a48b1d2e6651948d9f6739">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/175">#175</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/180">#180</a></p> </p> </li> </ul> </div> +</div> <div class="section" id="change-0.5.0"> -<h3>0.5.0<a class="headerlink" href="#change-0.5.0" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.5.0<a class="headerlink" href="#change-0.5.0" title="Permalink to this headline">¶</a></h3> Released: Wed Sep 28 2011<ul class="simple"> -<li><p id="change-0.5.0-0"><span class="target" id="change-d25af015b75fa0212ca7997ee8f85ee1"></span><p>A Template is explicitly disallowed +<li><p class="caption" id="change-0.5.0-0"><span class="target" id="change-d25af015b75fa0212ca7997ee8f85ee1"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d25af015b75fa0212ca7997ee8f85ee1">¶</a></span><p>A Template is explicitly disallowed from having a url that normalizes to relative outside of the root. That is, if the Lookup is based at /home/mytemplates, an include that would place @@ -925,31 +1295,31 @@ cached in the lookup under multiple, relative roots. TemplateLookup instead has always supported multiple file roots for this purpose.</p> -<a class="changeset-link headerlink reference internal" href="#change-d25af015b75fa0212ca7997ee8f85ee1">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/174">#174</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/174">#174</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.4.2"> -<h3>0.4.2<a class="headerlink" href="#change-0.4.2" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.4.2<a class="headerlink" href="#change-0.4.2" title="Permalink to this headline">¶</a></h3> Released: Fri Aug 5 2011<ul class="simple"> -<li><p id="change-0.4.2-0"><span class="target" id="change-0d5b25f911cea09b48a3cea73dc8b0ad"></span><p>Fixed bug regarding <%call>/def calls w/ content +<li><p class="caption" id="change-0.4.2-0"><span class="target" id="change-0d5b25f911cea09b48a3cea73dc8b0ad"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0d5b25f911cea09b48a3cea73dc8b0ad">¶</a></span><p>Fixed bug regarding <%call>/def calls w/ content whereby the identity of the “caller” callable inside the <%def> would be corrupted by the presence of another <%call> in the same block.</p> -<a class="changeset-link headerlink reference internal" href="#change-0d5b25f911cea09b48a3cea73dc8b0ad">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/170">#170</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/170">#170</a></p> </p> </li> -<li><p id="change-0.4.2-1"><span class="target" id="change-131badc51e07746b68123281fa7380a3"></span><p>Fixed the babel plugin to accommodate <%block></p> -<a class="changeset-link headerlink reference internal" href="#change-131badc51e07746b68123281fa7380a3">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/169">#169</a></p> +<li><p class="caption" id="change-0.4.2-1"><span class="target" id="change-131badc51e07746b68123281fa7380a3"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-131badc51e07746b68123281fa7380a3">¶</a></span><p>Fixed the babel plugin to accommodate <%block></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/169">#169</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.4.1"> -<h3>0.4.1<a class="headerlink" href="#change-0.4.1" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.4.1<a class="headerlink" href="#change-0.4.1" title="Permalink to this headline">¶</a></h3> Released: Wed Apr 6 2011<ul class="simple"> -<li><p id="change-0.4.1-0"><span class="target" id="change-464bf94bda97d9dfacb13c327c30f669"></span><p>New tag: <%block>. A variant on <%def> that +<li><p class="caption" id="change-0.4.1-0"><span class="target" id="change-464bf94bda97d9dfacb13c327c30f669"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-464bf94bda97d9dfacb13c327c30f669">¶</a></span><p>New tag: <%block>. A variant on <%def> that evaluates its contents in-place. Can be named or anonymous, the named version is intended for inheritance @@ -963,32 +1333,32 @@ for this purpose without at all replacing most other things that defs are still good for. Lots of new docs.</p> -<a class="changeset-link headerlink reference internal" href="#change-464bf94bda97d9dfacb13c327c30f669">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/164">#164</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/164">#164</a></p> </p> </li> -<li><p id="change-0.4.1-1"><span class="target" id="change-e5f029ea7d0f9f821c25e308c354006c"></span><p>a slight adjustment to the “highlight” logic +<li><p class="caption" id="change-0.4.1-1"><span class="target" id="change-e5f029ea7d0f9f821c25e308c354006c"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e5f029ea7d0f9f821c25e308c354006c">¶</a></span><p>a slight adjustment to the “highlight” logic for generating template bound stacktraces. Will stick to known template source lines without any extra guessing.</p> -<a class="changeset-link headerlink reference internal" href="#change-e5f029ea7d0f9f821c25e308c354006c">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/165">#165</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/165">#165</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.4.0"> -<h3>0.4.0<a class="headerlink" href="#change-0.4.0" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.4.0<a class="headerlink" href="#change-0.4.0" title="Permalink to this headline">¶</a></h3> Released: Sun Mar 6 2011<ul class="simple"> -<li><p id="change-0.4.0-0"><span class="target" id="change-24faf88ef298503c8544d93f64092984"></span><p>A 20% speedup for a basic two-page +<li><p class="caption" id="change-0.4.0-0"><span class="target" id="change-24faf88ef298503c8544d93f64092984"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-24faf88ef298503c8544d93f64092984">¶</a></span><p>A 20% speedup for a basic two-page inheritance setup rendering a table of escaped data (see <a class="reference external" href="http://techspot.zzzeek.org/2010/11/19/quick-mako-vs.-jinja-speed-test/">http://techspot.zzzeek.org/2010/11/19/quick-mako-vs.-jinja-speed-test/</a>). A few configurational changes which affect those in the I-don’t-do-unicode camp should be noted below.</p> -<a class="changeset-link headerlink reference internal" href="#change-24faf88ef298503c8544d93f64092984">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.4.0-1"><span class="target" id="change-4e7e70e466a6b372ba2085724f0c0dcc"></span><p>The FastEncodingBuffer is now used +<li><p class="caption" id="change-0.4.0-1"><span class="target" id="change-4e7e70e466a6b372ba2085724f0c0dcc"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4e7e70e466a6b372ba2085724f0c0dcc">¶</a></span><p>The FastEncodingBuffer is now used by default instead of cStringIO or StringIO, regardless of whether output_encoding is set to None or not. FEB is faster than @@ -1000,27 +1370,27 @@ mode of usage can be re-enabled by setting the flag bytestring_passthrough to True.</p> -<a class="changeset-link headerlink reference internal" href="#change-4e7e70e466a6b372ba2085724f0c0dcc">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.4.0-2"><span class="target" id="change-b23a68d0fccb2b8b34d1a727397669a5"></span><p>disable_unicode mode requires that +<li><p class="caption" id="change-0.4.0-2"><span class="target" id="change-b23a68d0fccb2b8b34d1a727397669a5"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b23a68d0fccb2b8b34d1a727397669a5">¶</a></span><p>disable_unicode mode requires that output_encoding be set to None - it also forces the bytestring_passthrough flag to True.</p> -<a class="changeset-link headerlink reference internal" href="#change-b23a68d0fccb2b8b34d1a727397669a5">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.4.0-3"><span class="target" id="change-0237ae4dc8e41beca5fe6392fbd68f4e"></span><p>the <%namespace> tag raises an error +<li><p class="caption" id="change-0.4.0-3"><span class="target" id="change-0237ae4dc8e41beca5fe6392fbd68f4e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0237ae4dc8e41beca5fe6392fbd68f4e">¶</a></span><p>the <%namespace> tag raises an error if the ‘template’ and ‘module’ attributes are specified at the same time in one tag. A different class is used for each case which allows a reduction in runtime conditional logic and function call overhead.</p> -<a class="changeset-link headerlink reference internal" href="#change-0237ae4dc8e41beca5fe6392fbd68f4e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/156">#156</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/156">#156</a></p> </p> </li> -<li><p id="change-0.4.0-4"><span class="target" id="change-a23ec787ca226d13d1115300493de625"></span><p>the keys() in the Context, as well as +<li><p class="caption" id="change-0.4.0-4"><span class="target" id="change-a23ec787ca226d13d1115300493de625"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a23ec787ca226d13d1115300493de625">¶</a></span><p>the keys() in the Context, as well as it’s internal _data dictionary, now include just what was specified to render() as well as Mako builtins @@ -1028,57 +1398,57 @@ of __builtin__ are no longer copied. Thanks to Daniel Lopez for pointing this out.</p> -<a class="changeset-link headerlink reference internal" href="#change-a23ec787ca226d13d1115300493de625">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/159">#159</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/159">#159</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.6"> -<h3>0.3.6<a class="headerlink" href="#change-0.3.6" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.6<a class="headerlink" href="#change-0.3.6" title="Permalink to this headline">¶</a></h3> Released: Sat Nov 13 2010<ul class="simple"> -<li><p id="change-0.3.6-0"><span class="target" id="change-ba90f64b03241356193e4e9fef913f63"></span><p>Documentation is on Sphinx.</p> -<a class="changeset-link headerlink reference internal" href="#change-ba90f64b03241356193e4e9fef913f63">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/126">#126</a></p> +<li><p class="caption" id="change-0.3.6-0"><span class="target" id="change-ba90f64b03241356193e4e9fef913f63"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ba90f64b03241356193e4e9fef913f63">¶</a></span><p>Documentation is on Sphinx.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/126">#126</a></p> </p> </li> -<li><p id="change-0.3.6-1"><span class="target" id="change-6fa26d3bfceaff55a258fb53794e6313"></span><p>Beaker is now part of “extras” in +<li><p class="caption" id="change-0.3.6-1"><span class="target" id="change-6fa26d3bfceaff55a258fb53794e6313"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6fa26d3bfceaff55a258fb53794e6313">¶</a></span><p>Beaker is now part of “extras” in setup.py instead of “install_requires”. This to produce a lighter weight install for those who don’t use the caching as well as to conform to Pyramid deployment practices.</p> -<a class="changeset-link headerlink reference internal" href="#change-6fa26d3bfceaff55a258fb53794e6313">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/154">#154</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/154">#154</a></p> </p> </li> -<li><p id="change-0.3.6-2"><span class="target" id="change-add98954fc4473f31b998fd2931c0c2c"></span><p>The Beaker import (or attempt thereof) +<li><p class="caption" id="change-0.3.6-2"><span class="target" id="change-add98954fc4473f31b998fd2931c0c2c"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-add98954fc4473f31b998fd2931c0c2c">¶</a></span><p>The Beaker import (or attempt thereof) is delayed until actually needed; this to remove the performance penalty from startup, particularly for “single execution” environments such as shell scripts.</p> -<a class="changeset-link headerlink reference internal" href="#change-add98954fc4473f31b998fd2931c0c2c">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/153">#153</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/153">#153</a></p> </p> </li> -<li><p id="change-0.3.6-3"><span class="target" id="change-6f50239252b9579a5a952a529cce3c8f"></span><p>Patch to lexer to not generate an empty +<li><p class="caption" id="change-0.3.6-3"><span class="target" id="change-6f50239252b9579a5a952a529cce3c8f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6f50239252b9579a5a952a529cce3c8f">¶</a></span><p>Patch to lexer to not generate an empty ‘’ write in the case of backslash-ended lines.</p> -<a class="changeset-link headerlink reference internal" href="#change-6f50239252b9579a5a952a529cce3c8f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/155">#155</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/155">#155</a></p> </p> </li> -<li><p id="change-0.3.6-4"><span class="target" id="change-9007a381dea9bd8a980aaf646712fa95"></span><p>Fixed missing <a href="#id5"><span class="problematic" id="id6">**</span></a>extra collection in +<li><p class="caption" id="change-0.3.6-4"><span class="target" id="change-717607f1417b677e796c1963cf7901b5"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-717607f1417b677e796c1963cf7901b5">¶</a></span><p>Fixed missing **extra collection in setup.py which prevented setup.py from running 2to3 on install.</p> -<a class="changeset-link headerlink reference internal" href="#change-9007a381dea9bd8a980aaf646712fa95">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/148">#148</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/148">#148</a></p> </p> </li> -<li><p id="change-0.3.6-5"><span class="target" id="change-d94085d95e60f190e30871ff1c472781"></span><p>New flag on Template, TemplateLookup - +<li><p class="caption" id="change-0.3.6-5"><span class="target" id="change-d94085d95e60f190e30871ff1c472781"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d94085d95e60f190e30871ff1c472781">¶</a></span><p>New flag on Template, TemplateLookup - strict_undefined=True, will cause variables not found in the context to raise a NameError immediately, instead of defaulting to the UNDEFINED value.</p> -<a class="changeset-link headerlink reference internal" href="#change-d94085d95e60f190e30871ff1c472781">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.3.6-6"><span class="target" id="change-c7f4bd0543dcd61c301325887e5e868f"></span><p>The range of Python identifiers that +<li><p class="caption" id="change-0.3.6-6"><span class="target" id="change-c7f4bd0543dcd61c301325887e5e868f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c7f4bd0543dcd61c301325887e5e868f">¶</a></span><p>The range of Python identifiers that are considered “undefined”, meaning they are pulled from the context, has been trimmed back to not include variables @@ -1091,48 +1461,48 @@ a little bit of tinkering in the AST code, which hadn’t really been touched for a couple of years, just FYI.</p> -<a class="changeset-link headerlink reference internal" href="#change-c7f4bd0543dcd61c301325887e5e868f">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.5"> -<h3>0.3.5<a class="headerlink" href="#change-0.3.5" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.5<a class="headerlink" href="#change-0.3.5" title="Permalink to this headline">¶</a></h3> Released: Sun Oct 24 2010<ul class="simple"> -<li><p id="change-0.3.5-0"><span class="target" id="change-4f131130d9a9c7503c1285d76453772e"></span><p>The <%namespace> tag allows expressions +<li><p class="caption" id="change-0.3.5-0"><span class="target" id="change-4f131130d9a9c7503c1285d76453772e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4f131130d9a9c7503c1285d76453772e">¶</a></span><p>The <%namespace> tag allows expressions for the <cite>file</cite> argument, i.e. with ${}. The <cite>context</cite> variable, if needed, must be referenced explicitly.</p> -<a class="changeset-link headerlink reference internal" href="#change-4f131130d9a9c7503c1285d76453772e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/141">#141</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/141">#141</a></p> </p> </li> -<li><p id="change-0.3.5-1"><span class="target" id="change-9260777204b90b5d2ef50591a9321f7f"></span><p>${} expressions embedded in tags, +<li><p class="caption" id="change-0.3.5-1"><span class="target" id="change-9260777204b90b5d2ef50591a9321f7f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9260777204b90b5d2ef50591a9321f7f">¶</a></span><p>${} expressions embedded in tags, such as <%foo:bar x=”${…}”>, now allow multiline Python expressions.</p> -<a class="changeset-link headerlink reference internal" href="#change-9260777204b90b5d2ef50591a9321f7f">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.3.5-2"><span class="target" id="change-b17753b5fc8d7a350d6c9d07d9e8698b"></span><p>Fixed previously non-covered regular +<li><p class="caption" id="change-0.3.5-2"><span class="target" id="change-b17753b5fc8d7a350d6c9d07d9e8698b"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b17753b5fc8d7a350d6c9d07d9e8698b">¶</a></span><p>Fixed previously non-covered regular expression, such that using a ${} expression inside of a tag element that doesn’t allow them raises a CompileException instead of silently failing.</p> -<a class="changeset-link headerlink reference internal" href="#change-b17753b5fc8d7a350d6c9d07d9e8698b">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.3.5-3"><span class="target" id="change-26a430536a4ef0aea275166c8ffead73"></span><p>Added a try/except around “import markupsafe”. +<li><p class="caption" id="change-0.3.5-3"><span class="target" id="change-26a430536a4ef0aea275166c8ffead73"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-26a430536a4ef0aea275166c8ffead73">¶</a></span><p>Added a try/except around “import markupsafe”. This to support GAE which can’t run markupsafe. No idea whatsoever if the install_requires in setup.py also breaks GAE, couldn’t get an answer on this.</p> -<a class="changeset-link headerlink reference internal" href="#change-26a430536a4ef0aea275166c8ffead73">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/151">#151</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/151">#151</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.4"> -<h3>0.3.4<a class="headerlink" href="#change-0.3.4" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.4<a class="headerlink" href="#change-0.3.4" title="Permalink to this headline">¶</a></h3> Released: Tue Jun 22 2010<ul class="simple"> -<li><p id="change-0.3.4-0"><span class="target" id="change-42a2094bdc5fa56af96f16ead2ea7a85"></span><p>Now using MarkupSafe for HTML escaping, +<li><p class="caption" id="change-0.3.4-0"><span class="target" id="change-42a2094bdc5fa56af96f16ead2ea7a85"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-42a2094bdc5fa56af96f16ead2ea7a85">¶</a></span><p>Now using MarkupSafe for HTML escaping, i.e. in place of cgi.escape(). Faster C-based implementation and also escapes single quotes for additional security. @@ -1144,97 +1514,97 @@ <p>Note that Pylons by default doesn’t use Mako’s filter - check your environment.py file.</p> -<a class="changeset-link headerlink reference internal" href="#change-42a2094bdc5fa56af96f16ead2ea7a85">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.3.4-1"><span class="target" id="change-c6b3b30f351cb6e68140eb7ff8ec9339"></span><p>Fixed call to “unicode.strip” in +<li><p class="caption" id="change-0.3.4-1"><span class="target" id="change-c6b3b30f351cb6e68140eb7ff8ec9339"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c6b3b30f351cb6e68140eb7ff8ec9339">¶</a></span><p>Fixed call to “unicode.strip” in exceptions.text_error_template which is not Py3k compatible.</p> -<a class="changeset-link headerlink reference internal" href="#change-c6b3b30f351cb6e68140eb7ff8ec9339">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/137">#137</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/137">#137</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.3"> -<h3>0.3.3<a class="headerlink" href="#change-0.3.3" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.3<a class="headerlink" href="#change-0.3.3" title="Permalink to this headline">¶</a></h3> Released: Mon May 31 2010<ul class="simple"> -<li><p id="change-0.3.3-0"><span class="target" id="change-bc6d3046e00861b0a815a3373dc21489"></span><p>Added conditional to RichTraceback +<li><p class="caption" id="change-0.3.3-0"><span class="target" id="change-bc6d3046e00861b0a815a3373dc21489"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-bc6d3046e00861b0a815a3373dc21489">¶</a></span><p>Added conditional to RichTraceback such that if no traceback is passed and sys.exc_info() has been reset, the formatter just returns blank for the “traceback” portion.</p> -<a class="changeset-link headerlink reference internal" href="#change-bc6d3046e00861b0a815a3373dc21489">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/135">#135</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/135">#135</a></p> </p> </li> -<li><p id="change-0.3.3-1"><span class="target" id="change-7398285484aa0b44f7cb4314d635343f"></span><p>Fixed sometimes incorrect usage of +<li><p class="caption" id="change-0.3.3-1"><span class="target" id="change-7398285484aa0b44f7cb4314d635343f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7398285484aa0b44f7cb4314d635343f">¶</a></span><p>Fixed sometimes incorrect usage of exc.__class__.__name__ in html/text error templates when using Python 2.4</p> -<a class="changeset-link headerlink reference internal" href="#change-7398285484aa0b44f7cb4314d635343f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/131">#131</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/131">#131</a></p> </p> </li> -<li><p id="change-0.3.3-2"><span class="target" id="change-fc38c54c185a03815b882ae0235dd0ec"></span><p>Fixed broken @property decorator on +<li><p class="caption" id="change-0.3.3-2"><span class="target" id="change-fc38c54c185a03815b882ae0235dd0ec"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-fc38c54c185a03815b882ae0235dd0ec">¶</a></span><p>Fixed broken @property decorator on template.last_modified</p> -<a class="changeset-link headerlink reference internal" href="#change-fc38c54c185a03815b882ae0235dd0ec">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.3.3-3"><span class="target" id="change-e351477ece87f96ce3b8dcbe2093927e"></span><p>Fixed error formatting when a stacktrace +<li><p class="caption" id="change-0.3.3-3"><span class="target" id="change-e351477ece87f96ce3b8dcbe2093927e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e351477ece87f96ce3b8dcbe2093927e">¶</a></span><p>Fixed error formatting when a stacktrace line contains no line number, as in when inside an eval/exec-generated function.</p> -<a class="changeset-link headerlink reference internal" href="#change-e351477ece87f96ce3b8dcbe2093927e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/132">#132</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/132">#132</a></p> </p> </li> -<li><p id="change-0.3.3-4"><span class="target" id="change-8465d2f035b94270f61add8d37b484b6"></span><p>When a .py is being created, the tempfile +<li><p class="caption" id="change-0.3.3-4"><span class="target" id="change-8465d2f035b94270f61add8d37b484b6"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-8465d2f035b94270f61add8d37b484b6">¶</a></span><p>When a .py is being created, the tempfile where the source is stored temporarily is now made in the same directory as that of the .py file. This ensures that the two files share the same filesystem, thus avoiding cross-filesystem synchronization issues. Thanks to Charles Cazabon.</p> -<a class="changeset-link headerlink reference internal" href="#change-8465d2f035b94270f61add8d37b484b6">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.2"> -<h3>0.3.2<a class="headerlink" href="#change-0.3.2" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.2<a class="headerlink" href="#change-0.3.2" title="Permalink to this headline">¶</a></h3> Released: Thu Mar 11 2010<ul class="simple"> -<li><p id="change-0.3.2-0"><span class="target" id="change-99967455a3839ef3b397981de9a7b95e"></span><p>Calling a def from the top, via +<li><p class="caption" id="change-0.3.2-0"><span class="target" id="change-99967455a3839ef3b397981de9a7b95e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-99967455a3839ef3b397981de9a7b95e">¶</a></span><p>Calling a def from the top, via template.get_def(…).render() now checks the argument signature the same way as it did in 0.2.5, so that TypeError is not raised. reopen of</p> -<a class="changeset-link headerlink reference internal" href="#change-99967455a3839ef3b397981de9a7b95e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/116">#116</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/116">#116</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.1"> -<h3>0.3.1<a class="headerlink" href="#change-0.3.1" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.1<a class="headerlink" href="#change-0.3.1" title="Permalink to this headline">¶</a></h3> Released: Sun Mar 7 2010<ul class="simple"> -<li><p id="change-0.3.1-0"><span class="target" id="change-10954fab107bd4f83df29f01b7a1db1a"></span><p>Fixed incorrect dir name in setup.py</p> -<a class="changeset-link headerlink reference internal" href="#change-10954fab107bd4f83df29f01b7a1db1a">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/129">#129</a></p> +<li><p class="caption" id="change-0.3.1-0"><span class="target" id="change-10954fab107bd4f83df29f01b7a1db1a"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-10954fab107bd4f83df29f01b7a1db1a">¶</a></span><p>Fixed incorrect dir name in setup.py</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/129">#129</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.3.0"> -<h3>0.3.0<a class="headerlink" href="#change-0.3.0" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.3.0<a class="headerlink" href="#change-0.3.0" title="Permalink to this headline">¶</a></h3> Released: Fri Mar 5 2010<ul class="simple"> -<li><p id="change-0.3.0-0"><span class="target" id="change-6696642b595c45f48c676d4321c80f4e"></span><p>Python 2.3 support is dropped.</p> -<a class="changeset-link headerlink reference internal" href="#change-6696642b595c45f48c676d4321c80f4e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/123">#123</a></p> +<li><p class="caption" id="change-0.3.0-0"><span class="target" id="change-6696642b595c45f48c676d4321c80f4e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6696642b595c45f48c676d4321c80f4e">¶</a></span><p>Python 2.3 support is dropped.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/123">#123</a></p> </p> </li> -<li><p id="change-0.3.0-1"><span class="target" id="change-4ac95d25798d0af74fcbbda6805f4117"></span><p>Python 3 support is added ! See README.py3k +<li><p class="caption" id="change-0.3.0-1"><span class="target" id="change-4ac95d25798d0af74fcbbda6805f4117"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4ac95d25798d0af74fcbbda6805f4117">¶</a></span><p>Python 3 support is added ! See README.py3k for installation and testing notes.</p> -<a class="changeset-link headerlink reference internal" href="#change-4ac95d25798d0af74fcbbda6805f4117">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/119">#119</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/119">#119</a></p> </p> </li> -<li><p id="change-0.3.0-2"><span class="target" id="change-580b71306f06a35525d94dbbc866dff5"></span><p>Unit tests now run with nose.</p> -<a class="changeset-link headerlink reference internal" href="#change-580b71306f06a35525d94dbbc866dff5">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/127">#127</a></p> +<li><p class="caption" id="change-0.3.0-2"><span class="target" id="change-580b71306f06a35525d94dbbc866dff5"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-580b71306f06a35525d94dbbc866dff5">¶</a></span><p>Unit tests now run with nose.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/127">#127</a></p> </p> </li> -<li><p id="change-0.3.0-3"><span class="target" id="change-254948cdd845470bc120bd9537620480"></span><p>Source code escaping has been simplified. +<li><p class="caption" id="change-0.3.0-3"><span class="target" id="change-254948cdd845470bc120bd9537620480"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-254948cdd845470bc120bd9537620480">¶</a></span><p>Source code escaping has been simplified. In particular, module source files are now generated with the Python “magic encoding comment”, and source code is passed through @@ -1242,154 +1612,154 @@ is regenerated from parsed Python source. This fixes usage of unicode in <%namespace:defname> tags.</p> -<a class="changeset-link headerlink reference internal" href="#change-254948cdd845470bc120bd9537620480">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/99">#99</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/99">#99</a></p> </p> </li> -<li><p id="change-0.3.0-4"><span class="target" id="change-b8d940f383df524cbcb09a4aa8785055"></span><p>RichTraceback(), html_error_template().render(), +<li><p class="caption" id="change-0.3.0-4"><span class="target" id="change-b8d940f383df524cbcb09a4aa8785055"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b8d940f383df524cbcb09a4aa8785055">¶</a></span><p>RichTraceback(), html_error_template().render(), text_error_template().render() now accept “error” and “traceback” as optional arguments, and these are now actually used.</p> -<a class="changeset-link headerlink reference internal" href="#change-b8d940f383df524cbcb09a4aa8785055">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/122">#122</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/122">#122</a></p> </p> </li> -<li><p id="change-0.3.0-5"><span class="target" id="change-c8b4a5c26a15e967ede79e6b3fc12673"></span><p>The exception output generated when +<li><p class="caption" id="change-0.3.0-5"><span class="target" id="change-c8b4a5c26a15e967ede79e6b3fc12673"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c8b4a5c26a15e967ede79e6b3fc12673">¶</a></span><p>The exception output generated when format_exceptions=True will now be as a Python unicode if it occurred during render_unicode(), or an encoded string if during render().</p> -<a class="changeset-link headerlink reference internal" href="#change-c8b4a5c26a15e967ede79e6b3fc12673">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.3.0-6"><span class="target" id="change-3685f613780a1778275c5a1c06ffd14d"></span><p>A percent sign can be emitted as the first +<li><p class="caption" id="change-0.3.0-6"><span class="target" id="change-3685f613780a1778275c5a1c06ffd14d"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-3685f613780a1778275c5a1c06ffd14d">¶</a></span><p>A percent sign can be emitted as the first non-whitespace character on a line by escaping it as in “%%”.</p> -<a class="changeset-link headerlink reference internal" href="#change-3685f613780a1778275c5a1c06ffd14d">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/112">#112</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/112">#112</a></p> </p> </li> -<li><p id="change-0.3.0-7"><span class="target" id="change-0b344165d32f9da5eebc93d2e36b751d"></span><p>Template accepts empty control structure, i.e. +<li><p class="caption" id="change-0.3.0-7"><span class="target" id="change-0b344165d32f9da5eebc93d2e36b751d"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0b344165d32f9da5eebc93d2e36b751d">¶</a></span><p>Template accepts empty control structure, i.e. % if: %endif, etc.</p> -<a class="changeset-link headerlink reference internal" href="#change-0b344165d32f9da5eebc93d2e36b751d">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/94">#94</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/94">#94</a></p> </p> </li> -<li><p id="change-0.3.0-8"><span class="target" id="change-4e41287388f6da51881b95c2fc27ff9d"></span><p>The <%page args> tag can now be used in a base +<li><p class="caption" id="change-0.3.0-8"><span class="target" id="change-4e41287388f6da51881b95c2fc27ff9d"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4e41287388f6da51881b95c2fc27ff9d">¶</a></span><p>The <%page args> tag can now be used in a base inheriting template - the full set of render() arguments are passed down through the inherits -chain. Undeclared arguments go into <a href="#id7"><span class="problematic" id="id8">**</span></a>pageargs +chain. Undeclared arguments go into **pageargs as usual.</p> -<a class="changeset-link headerlink reference internal" href="#change-4e41287388f6da51881b95c2fc27ff9d">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/116">#116</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/116">#116</a></p> </p> </li> -<li><p id="change-0.3.0-9"><span class="target" id="change-8f84b7484a62925c50f48334ee6a9756"></span><p>defs declared within a <%namespace> section, an +<li><p class="caption" id="change-0.3.0-9"><span class="target" id="change-8f84b7484a62925c50f48334ee6a9756"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-8f84b7484a62925c50f48334ee6a9756">¶</a></span><p>defs declared within a <%namespace> section, an uncommon feature, have been improved. The defs no longer get doubly-rendered in the body() scope, and now allow local variable assignment without breakage.</p> -<a class="changeset-link headerlink reference internal" href="#change-8f84b7484a62925c50f48334ee6a9756">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/109">#109</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/109">#109</a></p> </p> </li> -<li><p id="change-0.3.0-10"><span class="target" id="change-b282c56c8f7389792db2e50b26f4d871"></span><p>Windows paths are handled correctly if a Template +<li><p class="caption" id="change-0.3.0-10"><span class="target" id="change-b282c56c8f7389792db2e50b26f4d871"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b282c56c8f7389792db2e50b26f4d871">¶</a></span><p>Windows paths are handled correctly if a Template is passed only an absolute filename (i.e. with c: drive etc.) and no URI - the URI is converted to a forward-slash path and module_directory is treated as a windows path.</p> -<a class="changeset-link headerlink reference internal" href="#change-b282c56c8f7389792db2e50b26f4d871">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/128">#128</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/128">#128</a></p> </p> </li> -<li><p id="change-0.3.0-11"><span class="target" id="change-5ea16c786c94f8e04c3e8f5ea3a3b423"></span><p>TemplateLookup raises TopLevelLookupException for +<li><p class="caption" id="change-0.3.0-11"><span class="target" id="change-5ea16c786c94f8e04c3e8f5ea3a3b423"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5ea16c786c94f8e04c3e8f5ea3a3b423">¶</a></span><p>TemplateLookup raises TopLevelLookupException for a given path that is a directory, not a filename, instead of passing through to the template to generate IOError.</p> -<a class="changeset-link headerlink reference internal" href="#change-5ea16c786c94f8e04c3e8f5ea3a3b423">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/73">#73</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/73">#73</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.6"> -<h3>0.2.6<a class="headerlink" href="#change-0.2.6" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.6<a class="headerlink" href="#change-0.2.6" title="Permalink to this headline">¶</a></h3> no release date<ul class="simple"> -<li><p id="change-0.2.6-0"><span class="target" id="change-d1e4c26171841e1c4fbc0e3f56d0bf96"></span><p>Fix mako function decorators to preserve the +<li><p class="caption" id="change-0.2.6-0"><span class="target" id="change-d1e4c26171841e1c4fbc0e3f56d0bf96"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d1e4c26171841e1c4fbc0e3f56d0bf96">¶</a></span><p>Fix mako function decorators to preserve the original function’s name in all cases. Patch from Scott Torborg.</p> -<a class="changeset-link headerlink reference internal" href="#change-d1e4c26171841e1c4fbc0e3f56d0bf96">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.6-1"><span class="target" id="change-d1851b428e06541460cbd70bd5c6131f"></span><p>Support the <%namespacename:defname> syntax in +<li><p class="caption" id="change-0.2.6-1"><span class="target" id="change-d1851b428e06541460cbd70bd5c6131f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d1851b428e06541460cbd70bd5c6131f">¶</a></span><p>Support the <%namespacename:defname> syntax in the babel extractor.</p> -<a class="changeset-link headerlink reference internal" href="#change-d1851b428e06541460cbd70bd5c6131f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/118">#118</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/118">#118</a></p> </p> </li> -<li><p id="change-0.2.6-2"><span class="target" id="change-398bff9c71f24a9ff6c180d0a05018b4"></span><p>Further fixes to unicode handling of .py files with the +<li><p class="caption" id="change-0.2.6-2"><span class="target" id="change-398bff9c71f24a9ff6c180d0a05018b4"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-398bff9c71f24a9ff6c180d0a05018b4">¶</a></span><p>Further fixes to unicode handling of .py files with the html_error_template.</p> -<a class="changeset-link headerlink reference internal" href="#change-398bff9c71f24a9ff6c180d0a05018b4">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/88">#88</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/88">#88</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.5"> -<h3>0.2.5<a class="headerlink" href="#change-0.2.5" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.5<a class="headerlink" href="#change-0.2.5" title="Permalink to this headline">¶</a></h3> Released: Mon Sep 7 2009<ul class="simple"> -<li><p id="change-0.2.5-0"><span class="target" id="change-c79258c92155abe15ab0f249e56d36f8"></span><p>Added a “decorator” kw argument to <%def>, +<li><p class="caption" id="change-0.2.5-0"><span class="target" id="change-c79258c92155abe15ab0f249e56d36f8"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c79258c92155abe15ab0f249e56d36f8">¶</a></span><p>Added a “decorator” kw argument to <%def>, allows custom decoration functions to wrap rendering callables. Mainly intended for custom caching algorithms, not sure what other uses there may be (but there may be). Examples are in the “filtering” docs.</p> -<a class="changeset-link headerlink reference internal" href="#change-c79258c92155abe15ab0f249e56d36f8">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.5-1"><span class="target" id="change-4807d411f1e3cfa18c32decd089cab90"></span><p>When Mako creates subdirectories in which +<li><p class="caption" id="change-0.2.5-1"><span class="target" id="change-4807d411f1e3cfa18c32decd089cab90"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4807d411f1e3cfa18c32decd089cab90">¶</a></span><p>When Mako creates subdirectories in which to store templates, it uses the more permissive mode of 0775 instead of 0750, helping out with certain multi-process scenarios. Note that the mode is always subject to the restrictions of the existing umask.</p> -<a class="changeset-link headerlink reference internal" href="#change-4807d411f1e3cfa18c32decd089cab90">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/101">#101</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/101">#101</a></p> </p> </li> -<li><p id="change-0.2.5-2"><span class="target" id="change-8af1bb98b05bf16f832aaea1707f20fb"></span><p>Fixed namespace.__getattr__() to raise +<li><p class="caption" id="change-0.2.5-2"><span class="target" id="change-8af1bb98b05bf16f832aaea1707f20fb"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-8af1bb98b05bf16f832aaea1707f20fb">¶</a></span><p>Fixed namespace.__getattr__() to raise AttributeError on attribute not found instead of RuntimeError.</p> -<a class="changeset-link headerlink reference internal" href="#change-8af1bb98b05bf16f832aaea1707f20fb">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/104">#104</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/104">#104</a></p> </p> </li> -<li><p id="change-0.2.5-3"><span class="target" id="change-ca99b7588c54e67a73569aad8e06c0ce"></span><p>Added last_modified accessor to Template, +<li><p class="caption" id="change-0.2.5-3"><span class="target" id="change-ca99b7588c54e67a73569aad8e06c0ce"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ca99b7588c54e67a73569aad8e06c0ce">¶</a></span><p>Added last_modified accessor to Template, returns the time.time() when the module was created.</p> -<a class="changeset-link headerlink reference internal" href="#change-ca99b7588c54e67a73569aad8e06c0ce">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/97">#97</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/97">#97</a></p> </p> </li> -<li><p id="change-0.2.5-4"><span class="target" id="change-d18e860647e39ec0f72eeb38740111cb"></span><p>Fixed lexing support for whitespace +<li><p class="caption" id="change-0.2.5-4"><span class="target" id="change-d18e860647e39ec0f72eeb38740111cb"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d18e860647e39ec0f72eeb38740111cb">¶</a></span><p>Fixed lexing support for whitespace around ‘=’ sign in defs.</p> -<a class="changeset-link headerlink reference internal" href="#change-d18e860647e39ec0f72eeb38740111cb">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/102">#102</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/102">#102</a></p> </p> </li> -<li><p id="change-0.2.5-5"><span class="target" id="change-602d7edb91f7f94638496e5544c0b8ee"></span><p>Removed errant “lower()” in the lexer which +<li><p class="caption" id="change-0.2.5-5"><span class="target" id="change-602d7edb91f7f94638496e5544c0b8ee"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-602d7edb91f7f94638496e5544c0b8ee">¶</a></span><p>Removed errant “lower()” in the lexer which was causing tags to compile with case-insensitive names, thus messing up custom <%call> names.</p> -<a class="changeset-link headerlink reference internal" href="#change-602d7edb91f7f94638496e5544c0b8ee">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/108">#108</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/108">#108</a></p> </p> </li> -<li><p id="change-0.2.5-6"><span class="target" id="change-9980854809a31d4b404208e286a70d41"></span><p>added “mako.__version__” attribute to +<li><p class="caption" id="change-0.2.5-6"><span class="target" id="change-9980854809a31d4b404208e286a70d41"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9980854809a31d4b404208e286a70d41">¶</a></span><p>added “mako.__version__” attribute to the base module.</p> -<a class="changeset-link headerlink reference internal" href="#change-9980854809a31d4b404208e286a70d41">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/110">#110</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/110">#110</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.4"> -<h3>0.2.4<a class="headerlink" href="#change-0.2.4" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.4<a class="headerlink" href="#change-0.2.4" title="Permalink to this headline">¶</a></h3> Released: Tue Dec 23 2008<ul class="simple"> -<li><p id="change-0.2.4-0"><span class="target" id="change-4854b3f9b6cb5776937ab0695fff1435"></span><p>Fixed compatibility with Jython 2.5b1.</p> -<a class="changeset-link headerlink reference internal" href="#change-4854b3f9b6cb5776937ab0695fff1435">¶</a><p></p> +<li><p class="caption" id="change-0.2.4-0"><span class="target" id="change-4854b3f9b6cb5776937ab0695fff1435"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4854b3f9b6cb5776937ab0695fff1435">¶</a></span><p>Fixed compatibility with Jython 2.5b1.</p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.3"> -<h3>0.2.3<a class="headerlink" href="#change-0.2.3" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.3<a class="headerlink" href="#change-0.2.3" title="Permalink to this headline">¶</a></h3> Released: Sun Nov 23 2008<ul class="simple"> -<li><p id="change-0.2.3-0"><span class="target" id="change-37bce8b359a8e44e7b91c12652eee2b8"></span><p>the <%namespacename:defname> syntax described at +<li><p class="caption" id="change-0.2.3-0"><span class="target" id="change-37bce8b359a8e44e7b91c12652eee2b8"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-37bce8b359a8e44e7b91c12652eee2b8">¶</a></span><p>the <%namespacename:defname> syntax described at <a class="reference external" href="http://techspot.zzzeek.org/?p=28">http://techspot.zzzeek.org/?p=28</a> has now been added as a built in syntax, and is recommended as a more modern syntax versus <%call expr=”expression”>. @@ -1399,44 +1769,44 @@ nested. Many examples of the new syntax are in the “Calling a def with embedded content” section of the docs.</p> -<a class="changeset-link headerlink reference internal" href="#change-37bce8b359a8e44e7b91c12652eee2b8">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-1"><span class="target" id="change-35a6c7b85a04372530f2be1805959799"></span><p>added support for Jython 2.5.</p> -<a class="changeset-link headerlink reference internal" href="#change-35a6c7b85a04372530f2be1805959799">¶</a><p></p> +<li><p class="caption" id="change-0.2.3-1"><span class="target" id="change-35a6c7b85a04372530f2be1805959799"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-35a6c7b85a04372530f2be1805959799">¶</a></span><p>added support for Jython 2.5.</p> +<p></p> </p> </li> -<li><p id="change-0.2.3-2"><span class="target" id="change-f8334ef0e1678c06e374ba1a0d3931cd"></span><p>cache module now uses Beaker’s CacheManager +<li><p class="caption" id="change-0.2.3-2"><span class="target" id="change-f8334ef0e1678c06e374ba1a0d3931cd"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f8334ef0e1678c06e374ba1a0d3931cd">¶</a></span><p>cache module now uses Beaker’s CacheManager object directly, so that all cache types are included. memcached is available as both “ext:memcached” and “memcached”, the latter for backwards compatibility.</p> -<a class="changeset-link headerlink reference internal" href="#change-f8334ef0e1678c06e374ba1a0d3931cd">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-3"><span class="target" id="change-ed3a6c17f2cbd83a593de4d2724a6a84"></span><p>added “cache” accessor to Template, Namespace. +<li><p class="caption" id="change-0.2.3-3"><span class="target" id="change-ed3a6c17f2cbd83a593de4d2724a6a84"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ed3a6c17f2cbd83a593de4d2724a6a84">¶</a></span><p>added “cache” accessor to Template, Namespace. e.g. ${local.cache.get(‘somekey’)} or template.cache.invalidate_body()</p> -<a class="changeset-link headerlink reference internal" href="#change-ed3a6c17f2cbd83a593de4d2724a6a84">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-4"><span class="target" id="change-70e586f7cde0ac7b344e8e8986c58b9a"></span><p>added “cache_enabled=True” flag to Template, +<li><p class="caption" id="change-0.2.3-4"><span class="target" id="change-70e586f7cde0ac7b344e8e8986c58b9a"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-70e586f7cde0ac7b344e8e8986c58b9a">¶</a></span><p>added “cache_enabled=True” flag to Template, TemplateLookup. Setting this to False causes cache operations to “pass through” and execute every time; this flag should be integrated in Pylons with its own cache_enabled configuration setting.</p> -<a class="changeset-link headerlink reference internal" href="#change-70e586f7cde0ac7b344e8e8986c58b9a">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-5"><span class="target" id="change-fe9e64fb24df2528a185b3317fce35fb"></span><p>the Cache object now supports invalidate_def(name), +<li><p class="caption" id="change-0.2.3-5"><span class="target" id="change-fe9e64fb24df2528a185b3317fce35fb"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-fe9e64fb24df2528a185b3317fce35fb">¶</a></span><p>the Cache object now supports invalidate_def(name), invalidate_body(), invalidate_closure(name), invalidate(key), which will remove the given key from the cache, if it exists. The cache arguments (i.e. storage type) are derived from whatever has been already persisted for that template.</p> -<a class="changeset-link headerlink reference internal" href="#change-fe9e64fb24df2528a185b3317fce35fb">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/92">#92</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/92">#92</a></p> </p> </li> -<li><p id="change-0.2.3-6"><span class="target" id="change-fc8e53f27e96f1442a8e85b52988d4c4"></span><p>For cache changes to work fully, Beaker 1.1 is required. +<li><p class="caption" id="change-0.2.3-6"><span class="target" id="change-fc8e53f27e96f1442a8e85b52988d4c4"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-fc8e53f27e96f1442a8e85b52988d4c4">¶</a></span><p>For cache changes to work fully, Beaker 1.1 is required. 1.0.1 and up will work as well with the exception of cache expiry. Note that Beaker 1.1 is <strong>required</strong> for applications which use dynamically generated keys, @@ -1444,96 +1814,96 @@ for each individual key, thus consuming all available memory for an arbitrarily large number of distinct keys.</p> -<a class="changeset-link headerlink reference internal" href="#change-fc8e53f27e96f1442a8e85b52988d4c4">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-7"><span class="target" id="change-6215a523e4a44009dd085141f89bb1ea"></span><p>fixed bug whereby an <%included> template with +<li><p class="caption" id="change-0.2.3-7"><span class="target" id="change-6215a523e4a44009dd085141f89bb1ea"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6215a523e4a44009dd085141f89bb1ea">¶</a></span><p>fixed bug whereby an <%included> template with <%page> args named the same as a __builtin__ would not honor the default value specified in <%page></p> -<a class="changeset-link headerlink reference internal" href="#change-6215a523e4a44009dd085141f89bb1ea">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/93">#93</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/93">#93</a></p> </p> </li> -<li><p id="change-0.2.3-8"><span class="target" id="change-c269853926ff7f52a94ddf94c705cff7"></span><p>fixed the html_error_template not handling tracebacks from +<li><p class="caption" id="change-0.2.3-8"><span class="target" id="change-c269853926ff7f52a94ddf94c705cff7"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c269853926ff7f52a94ddf94c705cff7">¶</a></span><p>fixed the html_error_template not handling tracebacks from normal .py files with a magic encoding comment</p> -<a class="changeset-link headerlink reference internal" href="#change-c269853926ff7f52a94ddf94c705cff7">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/88">#88</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/88">#88</a></p> </p> </li> -<li><p id="change-0.2.3-9"><span class="target" id="change-87c44d844a042343e22d55e2a2b8d4e9"></span><p>RichTraceback() now accepts an optional traceback object +<li><p class="caption" id="change-0.2.3-9"><span class="target" id="change-87c44d844a042343e22d55e2a2b8d4e9"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-87c44d844a042343e22d55e2a2b8d4e9">¶</a></span><p>RichTraceback() now accepts an optional traceback object to be used in place of sys.exc_info()[2]. html_error_template() and text_error_template() accept an optional render()-time argument “traceback” which is passed to the RichTraceback object.</p> -<a class="changeset-link headerlink reference internal" href="#change-87c44d844a042343e22d55e2a2b8d4e9">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-10"><span class="target" id="change-7a562520a57d62460f54fadac0d94100"></span><p>added ModuleTemplate class, which allows the construction +<li><p class="caption" id="change-0.2.3-10"><span class="target" id="change-7a562520a57d62460f54fadac0d94100"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7a562520a57d62460f54fadac0d94100">¶</a></span><p>added ModuleTemplate class, which allows the construction of a Template given a Python module generated by a previous Template. This allows Python modules alone to be used as templates with no compilation step. Source code and template source are optional but allow error reporting to work correctly.</p> -<a class="changeset-link headerlink reference internal" href="#change-7a562520a57d62460f54fadac0d94100">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.3-11"><span class="target" id="change-6e699add881ad62aa72c44efa3899ae5"></span><p>fixed Python 2.3 compat. in mako.pyparser</p> -<a class="changeset-link headerlink reference internal" href="#change-6e699add881ad62aa72c44efa3899ae5">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/90">#90</a></p> +<li><p class="caption" id="change-0.2.3-11"><span class="target" id="change-6e699add881ad62aa72c44efa3899ae5"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6e699add881ad62aa72c44efa3899ae5">¶</a></span><p>fixed Python 2.3 compat. in mako.pyparser</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/90">#90</a></p> </p> </li> -<li><p id="change-0.2.3-12"><span class="target" id="change-54c464fa5c94b0aba86b2b99d13f9eb4"></span><p>fix Babel 0.9.3 compatibility; stripping comment tags is now +<li><p class="caption" id="change-0.2.3-12"><span class="target" id="change-54c464fa5c94b0aba86b2b99d13f9eb4"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-54c464fa5c94b0aba86b2b99d13f9eb4">¶</a></span><p>fix Babel 0.9.3 compatibility; stripping comment tags is now optional (and enabled by default).</p> -<a class="changeset-link headerlink reference internal" href="#change-54c464fa5c94b0aba86b2b99d13f9eb4">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.2"> -<h3>0.2.2<a class="headerlink" href="#change-0.2.2" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.2<a class="headerlink" href="#change-0.2.2" title="Permalink to this headline">¶</a></h3> Released: Mon Jun 23 2008<ul class="simple"> -<li><p id="change-0.2.2-0"><span class="target" id="change-df54b04a766bd7511f1b92e438573fdf"></span><p>cached blocks now use the current context when rendering +<li><p class="caption" id="change-0.2.2-0"><span class="target" id="change-df54b04a766bd7511f1b92e438573fdf"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-df54b04a766bd7511f1b92e438573fdf">¶</a></span><p>cached blocks now use the current context when rendering an expired section, instead of the original context passed in</p> -<a class="changeset-link headerlink reference internal" href="#change-df54b04a766bd7511f1b92e438573fdf">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/87">#87</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/87">#87</a></p> </p> </li> -<li><p id="change-0.2.2-1"><span class="target" id="change-c6f8379cfe314e3a5a202e256699d586"></span><p>fixed a critical issue regarding caching, whereby +<li><p class="caption" id="change-0.2.2-1"><span class="target" id="change-c6f8379cfe314e3a5a202e256699d586"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c6f8379cfe314e3a5a202e256699d586">¶</a></span><p>fixed a critical issue regarding caching, whereby a cached block would raise an error when called within a cache-refresh operation that was initiated after the initiating template had completed rendering.</p> -<a class="changeset-link headerlink reference internal" href="#change-c6f8379cfe314e3a5a202e256699d586">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.1"> -<h3>0.2.1<a class="headerlink" href="#change-0.2.1" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.1<a class="headerlink" href="#change-0.2.1" title="Permalink to this headline">¶</a></h3> Released: Mon Jun 16 2008<ul class="simple"> -<li><p id="change-0.2.1-0"><span class="target" id="change-908eed7e4807846bda8b7883b98f4a02"></span><p>fixed bug where ‘output_encoding’ parameter would prevent +<li><p class="caption" id="change-0.2.1-0"><span class="target" id="change-908eed7e4807846bda8b7883b98f4a02"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-908eed7e4807846bda8b7883b98f4a02">¶</a></span><p>fixed bug where ‘output_encoding’ parameter would prevent render_unicode() from returning a unicode object.</p> -<a class="changeset-link headerlink reference internal" href="#change-908eed7e4807846bda8b7883b98f4a02">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.1-1"><span class="target" id="change-765658fae385e8c30cafd7372f7da000"></span><p>bumped magic number, which forces template recompile for +<li><p class="caption" id="change-0.2.1-1"><span class="target" id="change-765658fae385e8c30cafd7372f7da000"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-765658fae385e8c30cafd7372f7da000">¶</a></span><p>bumped magic number, which forces template recompile for this version (fixes incompatible compile symbols from 0.1 series).</p> -<a class="changeset-link headerlink reference internal" href="#change-765658fae385e8c30cafd7372f7da000">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.1-2"><span class="target" id="change-00ae3ce99ec2767e28b645a85815d1f9"></span><p>added a few docs for cache options, specifically those that +<li><p class="caption" id="change-0.2.1-2"><span class="target" id="change-00ae3ce99ec2767e28b645a85815d1f9"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-00ae3ce99ec2767e28b645a85815d1f9">¶</a></span><p>added a few docs for cache options, specifically those that help with memcached.</p> -<a class="changeset-link headerlink reference internal" href="#change-00ae3ce99ec2767e28b645a85815d1f9">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.2.0"> -<h3>0.2.0<a class="headerlink" href="#change-0.2.0" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.2.0<a class="headerlink" href="#change-0.2.0" title="Permalink to this headline">¶</a></h3> Released: Tue Jun 3 2008<ul class="simple"> -<li><p id="change-0.2.0-0"><span class="target" id="change-7df2aeab716d6fcf91429566949d3297"></span><p>Speed improvements (as though we needed them, but people +<li><p class="caption" id="change-0.2.0-0"><span class="target" id="change-7df2aeab716d6fcf91429566949d3297"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7df2aeab716d6fcf91429566949d3297">¶</a></span><p>Speed improvements (as though we needed them, but people contributed and there you go):</p> -<a class="changeset-link headerlink reference internal" href="#change-7df2aeab716d6fcf91429566949d3297">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.0-1"><span class="target" id="change-d9c6b2b32a4d7d52614f9557a59dd57d"></span><p>added “bytestring passthru” mode, via +<li><p class="caption" id="change-0.2.0-1"><span class="target" id="change-d9c6b2b32a4d7d52614f9557a59dd57d"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d9c6b2b32a4d7d52614f9557a59dd57d">¶</a></span><p>added “bytestring passthru” mode, via <cite>disable_unicode=True</cite> argument passed to Template or TemplateLookup. All unicode-awareness and filtering is turned off, and template modules are generated with @@ -1544,496 +1914,496 @@ characters are present. When enabled, speed improvement around 10-20%. (courtesy anonymous guest)</p> -<a class="changeset-link headerlink reference internal" href="#change-d9c6b2b32a4d7d52614f9557a59dd57d">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/77">#77</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/77">#77</a></p> </p> </li> -<li><p id="change-0.2.0-2"><span class="target" id="change-1e1d8d3bf89815e481535914ac54e954"></span><p>inlined the “write” function of Context into a local +<li><p class="caption" id="change-0.2.0-2"><span class="target" id="change-1e1d8d3bf89815e481535914ac54e954"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1e1d8d3bf89815e481535914ac54e954">¶</a></span><p>inlined the “write” function of Context into a local template variable. This affords a 12-30% speedup in template render time. (idea courtesy same anonymous guest)</p> -<a class="changeset-link headerlink reference internal" href="#change-1e1d8d3bf89815e481535914ac54e954">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/76">#76</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/76">#76</a></p> </p> </li> -<li><p id="change-0.2.0-3"><span class="target" id="change-4425ad7ea582f24d81e9ca7ef4f92e6e"></span><p>New Features, API changes:</p> -<a class="changeset-link headerlink reference internal" href="#change-4425ad7ea582f24d81e9ca7ef4f92e6e">¶</a><p></p> +<li><p class="caption" id="change-0.2.0-3"><span class="target" id="change-4425ad7ea582f24d81e9ca7ef4f92e6e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4425ad7ea582f24d81e9ca7ef4f92e6e">¶</a></span><p>New Features, API changes:</p> +<p></p> </p> </li> -<li><p id="change-0.2.0-4"><span class="target" id="change-9da04566e35e386418120e4d29572595"></span><p>added “attr” accessor to namespaces. Returns +<li><p class="caption" id="change-0.2.0-4"><span class="target" id="change-9da04566e35e386418120e4d29572595"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-9da04566e35e386418120e4d29572595">¶</a></span><p>added “attr” accessor to namespaces. Returns attributes configured as module level attributes, i.e. within <%! %> sections. i.e.:</p> -<p># somefile.html -<%!</p> -<blockquote> -<div><p>foo = 27</p> -</div></blockquote> -<p>%></p> -<p># some other template -<%namespace name=”myns” file=”somefile.html”/> -${myns.attr.foo}</p> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span># somefile.html +<%! + foo = 27 +%> + +# some other template +<%namespace name="myns" file="somefile.html"/> +${myns.attr.foo}</pre></div> +</div> <p>The slight backwards incompatibility here is, you can’t have namespace defs named “attr” since the “attr” descriptor will occlude it.</p> -<a class="changeset-link headerlink reference internal" href="#change-9da04566e35e386418120e4d29572595">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/62">#62</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/62">#62</a></p> </p> </li> -<li><p id="change-0.2.0-5"><span class="target" id="change-47006dc7aa8160f70e0ed126113f0f5a"></span><p>cache_key argument can now render arguments passed +<li><p class="caption" id="change-0.2.0-5"><span class="target" id="change-47006dc7aa8160f70e0ed126113f0f5a"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-47006dc7aa8160f70e0ed126113f0f5a">¶</a></span><p>cache_key argument can now render arguments passed directly to the %page or %def, i.e. <%def name=”foo(x)” cached=”True” cache_key=”${x}”/></p> -<a class="changeset-link headerlink reference internal" href="#change-47006dc7aa8160f70e0ed126113f0f5a">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/78">#78</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/78">#78</a></p> </p> </li> -<li><p id="change-0.2.0-6"><span class="target" id="change-d5e0803b1807eb8f0128d3ccd973525f"></span><p>some functions on Context are now private: +<li><p class="caption" id="change-0.2.0-6"><span class="target" id="change-d5e0803b1807eb8f0128d3ccd973525f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d5e0803b1807eb8f0128d3ccd973525f">¶</a></span><p>some functions on Context are now private: _push_buffer(), _pop_buffer(), caller_stack._push_frame(), caller_stack._pop_frame().</p> -<a class="changeset-link headerlink reference internal" href="#change-d5e0803b1807eb8f0128d3ccd973525f">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.0-7"><span class="target" id="change-c53f2fb7206af6bed4a266fc8e39da44"></span><p>added a runner script “mako-render” which renders +<li><p class="caption" id="change-0.2.0-7"><span class="target" id="change-c53f2fb7206af6bed4a266fc8e39da44"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c53f2fb7206af6bed4a266fc8e39da44">¶</a></span><p>added a runner script “mako-render” which renders standard input as a template to stdout</p> -<a class="changeset-link headerlink reference internal" href="#change-c53f2fb7206af6bed4a266fc8e39da44">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/56">#56</a>, <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/81">#81</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/56">#56</a>, <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/81">#81</a></p> </p> </li> -<li><p id="change-0.2.0-8"><span class="target" id="change-1cf0feb7e1a86092b97d375978dba60d"><strong>[bugfixes] </strong></span><p>can now use most names from __builtins__ as variable +<li><p class="caption" id="change-0.2.0-8"><span class="target" id="change-1cf0feb7e1a86092b97d375978dba60d"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1cf0feb7e1a86092b97d375978dba60d">¶</a></span><p>can now use most names from __builtins__ as variable names without explicit declaration (i.e. ‘id’, ‘exception’, ‘range’, etc.)</p> -<a class="changeset-link headerlink reference internal" href="#change-1cf0feb7e1a86092b97d375978dba60d">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/83">#83</a>, <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/84">#84</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/83">#83</a>, <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/84">#84</a></p> </p> </li> -<li><p id="change-0.2.0-9"><span class="target" id="change-b42dffceb4d5586db34c320d5368a1a0"><strong>[bugfixes] </strong></span><p>can also use builtin names as local variable names +<li><p class="caption" id="change-0.2.0-9"><span class="target" id="change-b42dffceb4d5586db34c320d5368a1a0"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b42dffceb4d5586db34c320d5368a1a0">¶</a></span><p>can also use builtin names as local variable names (i.e. dict, locals) (came from fix for)</p> -<a class="changeset-link headerlink reference internal" href="#change-b42dffceb4d5586db34c320d5368a1a0">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/84">#84</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/84">#84</a></p> </p> </li> -<li><p id="change-0.2.0-10"><span class="target" id="change-66d96bea88684ee0d97467bfe1ccbd28"><strong>[bugfixes] </strong></span><p>fixed bug in python generation when variable names are +<li><p class="caption" id="change-0.2.0-10"><span class="target" id="change-66d96bea88684ee0d97467bfe1ccbd28"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-66d96bea88684ee0d97467bfe1ccbd28">¶</a></span><p>fixed bug in python generation when variable names are used with identifiers like “else”, “finally”, etc. inside them</p> -<a class="changeset-link headerlink reference internal" href="#change-66d96bea88684ee0d97467bfe1ccbd28">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/68">#68</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/68">#68</a></p> </p> </li> -<li><p id="change-0.2.0-11"><span class="target" id="change-7482fbd47334f3c223597fc27ed61291"><strong>[bugfixes] </strong></span><p>fixed codegen bug which occurred when using <%page> +<li><p class="caption" id="change-0.2.0-11"><span class="target" id="change-7482fbd47334f3c223597fc27ed61291"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7482fbd47334f3c223597fc27ed61291">¶</a></span><p>fixed codegen bug which occurred when using <%page> level caching, combined with an expression-based cache_key, combined with the usage of <%namespace import=”*”/> - fixed lexer exceptions not cleaning up temporary files, which could lead to a maximum number of file descriptors used in the process</p> -<a class="changeset-link headerlink reference internal" href="#change-7482fbd47334f3c223597fc27ed61291">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/69">#69</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/69">#69</a></p> </p> </li> -<li><p id="change-0.2.0-12"><span class="target" id="change-f7edc331eeedd9d0e4e390279db7f1c6"><strong>[bugfixes] </strong></span><p>fixed issue with inline format_exceptions that was +<li><p class="caption" id="change-0.2.0-12"><span class="target" id="change-f7edc331eeedd9d0e4e390279db7f1c6"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f7edc331eeedd9d0e4e390279db7f1c6">¶</a></span><p>fixed issue with inline format_exceptions that was producing blank exception pages when an inheriting template is present</p> -<a class="changeset-link headerlink reference internal" href="#change-f7edc331eeedd9d0e4e390279db7f1c6">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/71">#71</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/71">#71</a></p> </p> </li> -<li><p id="change-0.2.0-13"><span class="target" id="change-c380b62194e7806f2ba96a72cf35f4a5"><strong>[bugfixes] </strong></span><p>format_exceptions will apply the encoding options of +<li><p class="caption" id="change-0.2.0-13"><span class="target" id="change-c380b62194e7806f2ba96a72cf35f4a5"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-c380b62194e7806f2ba96a72cf35f4a5">¶</a></span><p>format_exceptions will apply the encoding options of html_error_template() to the buffered output</p> -<a class="changeset-link headerlink reference internal" href="#change-c380b62194e7806f2ba96a72cf35f4a5">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.2.0-14"><span class="target" id="change-aaa77e397a4d5a128ee8ead89aca6552"><strong>[bugfixes] </strong></span><p>rewrote the “whitespace adjuster” function to work +<li><p class="caption" id="change-0.2.0-14"><span class="target" id="change-aaa77e397a4d5a128ee8ead89aca6552"><strong>[bugfixes]</strong> <a class="changelog-reference headerlink reference internal" href="#change-aaa77e397a4d5a128ee8ead89aca6552">¶</a></span><p>rewrote the “whitespace adjuster” function to work with more elaborate combinations of quotes and comments</p> -<a class="changeset-link headerlink reference internal" href="#change-aaa77e397a4d5a128ee8ead89aca6552">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/75">#75</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/75">#75</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.10"> -<h3>0.1.10<a class="headerlink" href="#change-0.1.10" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.10<a class="headerlink" href="#change-0.1.10" title="Permalink to this headline">¶</a></h3> no release date<ul class="simple"> -<li><p id="change-0.1.10-0"><span class="target" id="change-35446d7c963081d4cb4420f1a2b68beb"></span><p>fixed propagation of ‘caller’ such that nested %def calls +<li><p class="caption" id="change-0.1.10-0"><span class="target" id="change-35446d7c963081d4cb4420f1a2b68beb"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-35446d7c963081d4cb4420f1a2b68beb">¶</a></span><p>fixed propagation of ‘caller’ such that nested %def calls within a <%call> tag’s argument list propigates ‘caller’ to the %call function itself (propigates to the inner calls too, this is a slight side effect which previously existed anyway)</p> -<a class="changeset-link headerlink reference internal" href="#change-35446d7c963081d4cb4420f1a2b68beb">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.10-1"><span class="target" id="change-60935107d31e2d12b8725bfa98a4e15e"></span><p>fixed bug where local.get_namespace() could put an +<li><p class="caption" id="change-0.1.10-1"><span class="target" id="change-60935107d31e2d12b8725bfa98a4e15e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-60935107d31e2d12b8725bfa98a4e15e">¶</a></span><p>fixed bug where local.get_namespace() could put an incorrect “self” in the current context</p> -<a class="changeset-link headerlink reference internal" href="#change-60935107d31e2d12b8725bfa98a4e15e">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.10-2"><span class="target" id="change-a03b9e4773bb4ad04e67baf857946095"></span><p>fixed another namespace bug where the namespace functions +<li><p class="caption" id="change-0.1.10-2"><span class="target" id="change-a03b9e4773bb4ad04e67baf857946095"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-a03b9e4773bb4ad04e67baf857946095">¶</a></span><p>fixed another namespace bug where the namespace functions did not have access to the correct context containing their ‘self’ and ‘parent’</p> -<a class="changeset-link headerlink reference internal" href="#change-a03b9e4773bb4ad04e67baf857946095">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.9"> -<h3>0.1.9<a class="headerlink" href="#change-0.1.9" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.9<a class="headerlink" href="#change-0.1.9" title="Permalink to this headline">¶</a></h3> no release date<ul class="simple"> -<li><p id="change-0.1.9-0"><span class="target" id="change-b6be8d8f9ba7a78451926e2e5a00168a"></span><p>filters.Decode filter can also accept a non-basestring +<li><p class="caption" id="change-0.1.9-0"><span class="target" id="change-b6be8d8f9ba7a78451926e2e5a00168a"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b6be8d8f9ba7a78451926e2e5a00168a">¶</a></span><p>filters.Decode filter can also accept a non-basestring object and will call str() + unicode() on it</p> -<a class="changeset-link headerlink reference internal" href="#change-b6be8d8f9ba7a78451926e2e5a00168a">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/47">#47</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/47">#47</a></p> </p> </li> -<li><p id="change-0.1.9-1"><span class="target" id="change-80d0f355df4c2e0e2044d9b34ba8ffe6"></span><p>comments can be placed at the end of control lines, +<li><p class="caption" id="change-0.1.9-1"><span class="target" id="change-80d0f355df4c2e0e2044d9b34ba8ffe6"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-80d0f355df4c2e0e2044d9b34ba8ffe6">¶</a></span><p>comments can be placed at the end of control lines, i.e. if foo: # a comment,, thanks to Paul Colomiets</p> -<a class="changeset-link headerlink reference internal" href="#change-80d0f355df4c2e0e2044d9b34ba8ffe6">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/53">#53</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/53">#53</a></p> </p> </li> -<li><p id="change-0.1.9-2"><span class="target" id="change-4a1a251233e66deb83ebbca806c75e7e"></span><p>fixed expressions and page tag arguments and with embedded +<li><p class="caption" id="change-0.1.9-2"><span class="target" id="change-4a1a251233e66deb83ebbca806c75e7e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-4a1a251233e66deb83ebbca806c75e7e">¶</a></span><p>fixed expressions and page tag arguments and with embedded newlines in CRLF templates, follow up to, thanks Eric Woroshow</p> -<a class="changeset-link headerlink reference internal" href="#change-4a1a251233e66deb83ebbca806c75e7e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/16">#16</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/16">#16</a></p> </p> </li> -<li><p id="change-0.1.9-3"><span class="target" id="change-b3479ae6d58bd0ac59439c4b81428d3e"></span><p>added an IOError catch for source file not found in RichTraceback +<li><p class="caption" id="change-0.1.9-3"><span class="target" id="change-b3479ae6d58bd0ac59439c4b81428d3e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b3479ae6d58bd0ac59439c4b81428d3e">¶</a></span><p>added an IOError catch for source file not found in RichTraceback exception reporter</p> -<a class="changeset-link headerlink reference internal" href="#change-b3479ae6d58bd0ac59439c4b81428d3e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/51">#51</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/51">#51</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.8"> -<h3>0.1.8<a class="headerlink" href="#change-0.1.8" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.8<a class="headerlink" href="#change-0.1.8" title="Permalink to this headline">¶</a></h3> Released: Tue Jun 26 2007<ul class="simple"> -<li><p id="change-0.1.8-0"><span class="target" id="change-bbc10b00b2959f71e6703161fe1a45a1"></span><p>variable names declared in render methods by internal +<li><p class="caption" id="change-0.1.8-0"><span class="target" id="change-bbc10b00b2959f71e6703161fe1a45a1"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-bbc10b00b2959f71e6703161fe1a45a1">¶</a></span><p>variable names declared in render methods by internal codegen prefixed by “__M_” to prevent name collisions with user code</p> -<a class="changeset-link headerlink reference internal" href="#change-bbc10b00b2959f71e6703161fe1a45a1">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.8-1"><span class="target" id="change-12a94b4bec51562504cc0951143d7b14"></span><p>added a Babel (<a class="reference external" href="http://babel.edgewall.org/">http://babel.edgewall.org/</a>) extractor entry +<li><p class="caption" id="change-0.1.8-1"><span class="target" id="change-12a94b4bec51562504cc0951143d7b14"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-12a94b4bec51562504cc0951143d7b14">¶</a></span><p>added a Babel (<a class="reference external" href="http://babel.edgewall.org/">http://babel.edgewall.org/</a>) extractor entry point, allowing extraction of gettext messages directly from mako templates via Babel</p> -<a class="changeset-link headerlink reference internal" href="#change-12a94b4bec51562504cc0951143d7b14">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/45">#45</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/45">#45</a></p> </p> </li> -<li><p id="change-0.1.8-2"><span class="target" id="change-ff313c4aec5d1b008cf8253396b514d6"></span><p>fix to turbogears plugin to work with dot-separated names +<li><p class="caption" id="change-0.1.8-2"><span class="target" id="change-ff313c4aec5d1b008cf8253396b514d6"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ff313c4aec5d1b008cf8253396b514d6">¶</a></span><p>fix to turbogears plugin to work with dot-separated names (i.e. load_template(‘foo.bar’)). also takes file extension as a keyword argument (default is ‘mak’).</p> -<a class="changeset-link headerlink reference internal" href="#change-ff313c4aec5d1b008cf8253396b514d6">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.8-3"><span class="target" id="change-7f4b2edc94747c2be57aebfd1f725cf9"></span><p>more tg fix: fixed, allowing string-based +<li><p class="caption" id="change-0.1.8-3"><span class="target" id="change-7f4b2edc94747c2be57aebfd1f725cf9"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7f4b2edc94747c2be57aebfd1f725cf9">¶</a></span><p>more tg fix: fixed, allowing string-based templates with tgplugin even if non-compatible args were sent</p> -<a class="changeset-link headerlink reference internal" href="#change-7f4b2edc94747c2be57aebfd1f725cf9">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/35">#35</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/35">#35</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.7"> -<h3>0.1.7<a class="headerlink" href="#change-0.1.7" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.7<a class="headerlink" href="#change-0.1.7" title="Permalink to this headline">¶</a></h3> Released: Wed Jun 13 2007<ul class="simple"> -<li><p id="change-0.1.7-0"><span class="target" id="change-f9d399621cbe00065331cffcfd726aaf"></span><p>one small fix to the unit tests to support python 2.3</p> -<a class="changeset-link headerlink reference internal" href="#change-f9d399621cbe00065331cffcfd726aaf">¶</a><p></p> +<li><p class="caption" id="change-0.1.7-0"><span class="target" id="change-f9d399621cbe00065331cffcfd726aaf"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f9d399621cbe00065331cffcfd726aaf">¶</a></span><p>one small fix to the unit tests to support python 2.3</p> +<p></p> </p> </li> -<li><p id="change-0.1.7-1"><span class="target" id="change-d54e6f740ac7e3c9302f434352c6ad24"></span><p>a slight hack to how cache.py detects Beaker’s memcached, +<li><p class="caption" id="change-0.1.7-1"><span class="target" id="change-d54e6f740ac7e3c9302f434352c6ad24"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d54e6f740ac7e3c9302f434352c6ad24">¶</a></span><p>a slight hack to how cache.py detects Beaker’s memcached, works around unexplained import behavior observed on some python 2.3 installations</p> -<a class="changeset-link headerlink reference internal" href="#change-d54e6f740ac7e3c9302f434352c6ad24">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.6"> -<h3>0.1.6<a class="headerlink" href="#change-0.1.6" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.6<a class="headerlink" href="#change-0.1.6" title="Permalink to this headline">¶</a></h3> Released: Fri May 18 2007<ul class="simple"> -<li><p id="change-0.1.6-0"><span class="target" id="change-52836ef58904a858efff55a21272a3aa"></span><p>caching is now supplied directly by Beaker, which has +<li><p class="caption" id="change-0.1.6-0"><span class="target" id="change-52836ef58904a858efff55a21272a3aa"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-52836ef58904a858efff55a21272a3aa">¶</a></span><p>caching is now supplied directly by Beaker, which has all of MyghtyUtils merged into it now. The latest Beaker (0.7.1) also fixes a bug related to how Mako was using the cache API.</p> -<a class="changeset-link headerlink reference internal" href="#change-52836ef58904a858efff55a21272a3aa">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.6-1"><span class="target" id="change-7bc90d84523c2290a3350c133e269c20"></span><p>fix to module_directory path generation when the path is “./”</p> -<a class="changeset-link headerlink reference internal" href="#change-7bc90d84523c2290a3350c133e269c20">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/34">#34</a></p> +<li><p class="caption" id="change-0.1.6-1"><span class="target" id="change-7bc90d84523c2290a3350c133e269c20"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7bc90d84523c2290a3350c133e269c20">¶</a></span><p>fix to module_directory path generation when the path is “./”</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/34">#34</a></p> </p> </li> -<li><p id="change-0.1.6-2"><span class="target" id="change-ea6d95d606ab7dd8f3b3f8b49bc0ca99"></span><p>TGPlugin passes options to string-based templates</p> -<a class="changeset-link headerlink reference internal" href="#change-ea6d95d606ab7dd8f3b3f8b49bc0ca99">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/35">#35</a></p> +<li><p class="caption" id="change-0.1.6-2"><span class="target" id="change-ea6d95d606ab7dd8f3b3f8b49bc0ca99"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ea6d95d606ab7dd8f3b3f8b49bc0ca99">¶</a></span><p>TGPlugin passes options to string-based templates</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/35">#35</a></p> </p> </li> -<li><p id="change-0.1.6-3"><span class="target" id="change-31e1248422bcd0c78c13b47b458a9085"></span><p>added an explicit stack frame step to template runtime, which +<li><p class="caption" id="change-0.1.6-3"><span class="target" id="change-31e1248422bcd0c78c13b47b458a9085"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-31e1248422bcd0c78c13b47b458a9085">¶</a></span><p>added an explicit stack frame step to template runtime, which allows much simpler and hopefully bug-free tracking of ‘caller’, fixes</p> -<a class="changeset-link headerlink reference internal" href="#change-31e1248422bcd0c78c13b47b458a9085">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/28">#28</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/28">#28</a></p> </p> </li> -<li><p id="change-0.1.6-4"><span class="target" id="change-54a970a9cf864a6c262da7b7d9216109"></span><p>if plain Python defs are used with <%call>, a decorator +<li><p class="caption" id="change-0.1.6-4"><span class="target" id="change-54a970a9cf864a6c262da7b7d9216109"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-54a970a9cf864a6c262da7b7d9216109">¶</a></span><p>if plain Python defs are used with <%call>, a decorator @runtime.supports_callable exists to ensure that the “caller” stack is properly handled for the def.</p> -<a class="changeset-link headerlink reference internal" href="#change-54a970a9cf864a6c262da7b7d9216109">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.6-5"><span class="target" id="change-d2cd0326db0e6586eabcce097caf31ff"></span><p>fix to RichTraceback and exception reporting to get template +<li><p class="caption" id="change-0.1.6-5"><span class="target" id="change-d2cd0326db0e6586eabcce097caf31ff"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d2cd0326db0e6586eabcce097caf31ff">¶</a></span><p>fix to RichTraceback and exception reporting to get template source code as a unicode object</p> -<a class="changeset-link headerlink reference internal" href="#change-d2cd0326db0e6586eabcce097caf31ff">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/37">#37</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/37">#37</a></p> </p> </li> -<li><p id="change-0.1.6-6"><span class="target" id="change-dc0199630744815964c1e6174ea78785"></span><p>html_error_template includes options “full=True”, “css=True” +<li><p class="caption" id="change-0.1.6-6"><span class="target" id="change-dc0199630744815964c1e6174ea78785"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-dc0199630744815964c1e6174ea78785">¶</a></span><p>html_error_template includes options “full=True”, “css=True” which control generation of HTML tags, CSS</p> -<a class="changeset-link headerlink reference internal" href="#change-dc0199630744815964c1e6174ea78785">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/39">#39</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/39">#39</a></p> </p> </li> -<li><p id="change-0.1.6-7"><span class="target" id="change-b0a96b76069cee8cd44ba31774b27fa2"></span><p>added the ‘encoding_errors’ parameter to Template/TemplateLookup +<li><p class="caption" id="change-0.1.6-7"><span class="target" id="change-b0a96b76069cee8cd44ba31774b27fa2"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b0a96b76069cee8cd44ba31774b27fa2">¶</a></span><p>added the ‘encoding_errors’ parameter to Template/TemplateLookup for specifying the error handler associated with encoding to ‘output_encoding’</p> -<a class="changeset-link headerlink reference internal" href="#change-b0a96b76069cee8cd44ba31774b27fa2">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/40">#40</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/40">#40</a></p> </p> </li> -<li><p id="change-0.1.6-8"><span class="target" id="change-528e7eeb36e454ad6679969c443b951c"></span><p>the Template returned by html_error_template now defaults to +<li><p class="caption" id="change-0.1.6-8"><span class="target" id="change-528e7eeb36e454ad6679969c443b951c"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-528e7eeb36e454ad6679969c443b951c">¶</a></span><p>the Template returned by html_error_template now defaults to output_encoding=sys.getdefaultencoding(), encoding_errors=’htmlentityreplace’</p> -<a class="changeset-link headerlink reference internal" href="#change-528e7eeb36e454ad6679969c443b951c">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/37">#37</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/37">#37</a></p> </p> </li> -<li><p id="change-0.1.6-9"><span class="target" id="change-87df4540a9078340f98f18122437d6dd"></span><p>control lines, i.e. % lines, support backslashes to continue long +<li><p class="caption" id="change-0.1.6-9"><span class="target" id="change-87df4540a9078340f98f18122437d6dd"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-87df4540a9078340f98f18122437d6dd">¶</a></span><p>control lines, i.e. % lines, support backslashes to continue long lines (#32)</p> -<a class="changeset-link headerlink reference internal" href="#change-87df4540a9078340f98f18122437d6dd">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.6-10"><span class="target" id="change-5a582713c17cb4654879f3adb098f00f"></span><p>fixed codegen bug when defining <%def> within <%call> within <%call></p> -<a class="changeset-link headerlink reference internal" href="#change-5a582713c17cb4654879f3adb098f00f">¶</a><p></p> +<li><p class="caption" id="change-0.1.6-10"><span class="target" id="change-5a582713c17cb4654879f3adb098f00f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5a582713c17cb4654879f3adb098f00f">¶</a></span><p>fixed codegen bug when defining <%def> within <%call> within <%call></p> +<p></p> </p> </li> -<li><p id="change-0.1.6-11"><span class="target" id="change-e80dc8f529838d0f39320706a515d3fa"></span><p>leading utf-8 BOM in template files is honored according to pep-0263</p> -<a class="changeset-link headerlink reference internal" href="#change-e80dc8f529838d0f39320706a515d3fa">¶</a><p></p> +<li><p class="caption" id="change-0.1.6-11"><span class="target" id="change-e80dc8f529838d0f39320706a515d3fa"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e80dc8f529838d0f39320706a515d3fa">¶</a></span><p>leading utf-8 BOM in template files is honored according to pep-0263</p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.5"> -<h3>0.1.5<a class="headerlink" href="#change-0.1.5" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.5<a class="headerlink" href="#change-0.1.5" title="Permalink to this headline">¶</a></h3> Released: Sat Mar 31 2007<ul class="simple"> -<li><p id="change-0.1.5-0"><span class="target" id="change-f55f1eaaa360047ad0dbf07496beae9c"></span><p>AST expression generation - added in just about everything +<li><p class="caption" id="change-0.1.5-0"><span class="target" id="change-f55f1eaaa360047ad0dbf07496beae9c"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f55f1eaaa360047ad0dbf07496beae9c">¶</a></span><p>AST expression generation - added in just about everything expression-wise from the AST module</p> -<a class="changeset-link headerlink reference internal" href="#change-f55f1eaaa360047ad0dbf07496beae9c">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/26">#26</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/26">#26</a></p> </p> </li> -<li><p id="change-0.1.5-1"><span class="target" id="change-038f363f37ffb6f6e1d81aaeb32d371d"></span><p>AST parsing, properly detects imports of the form “import foo.bar”</p> -<a class="changeset-link headerlink reference internal" href="#change-038f363f37ffb6f6e1d81aaeb32d371d">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/27">#27</a></p> +<li><p class="caption" id="change-0.1.5-1"><span class="target" id="change-038f363f37ffb6f6e1d81aaeb32d371d"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-038f363f37ffb6f6e1d81aaeb32d371d">¶</a></span><p>AST parsing, properly detects imports of the form “import foo.bar”</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/27">#27</a></p> </p> </li> -<li><p id="change-0.1.5-2"><span class="target" id="change-fe4577a3f1111e2f31098302811ed765"></span><p>fix to lexing of <%docs> tag nested in other tags</p> -<a class="changeset-link headerlink reference internal" href="#change-fe4577a3f1111e2f31098302811ed765">¶</a><p></p> +<li><p class="caption" id="change-0.1.5-2"><span class="target" id="change-fe4577a3f1111e2f31098302811ed765"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-fe4577a3f1111e2f31098302811ed765">¶</a></span><p>fix to lexing of <%docs> tag nested in other tags</p> +<p></p> </p> </li> -<li><p id="change-0.1.5-3"><span class="target" id="change-895781e7f1f9e56da8e1f7d84a2d75e8"></span><p>fix to context-arguments inside of <%include> tag which broke +<li><p class="caption" id="change-0.1.5-3"><span class="target" id="change-895781e7f1f9e56da8e1f7d84a2d75e8"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-895781e7f1f9e56da8e1f7d84a2d75e8">¶</a></span><p>fix to context-arguments inside of <%include> tag which broke during 0.1.4</p> -<a class="changeset-link headerlink reference internal" href="#change-895781e7f1f9e56da8e1f7d84a2d75e8">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/29">#29</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/29">#29</a></p> </p> </li> -<li><p id="change-0.1.5-4"><span class="target" id="change-f4a4e7c2e333277389fa0febf1b94548"></span><p>added “n” filter, disables <em>all</em> filters normally applied to an expression +<li><p class="caption" id="change-0.1.5-4"><span class="target" id="change-f4a4e7c2e333277389fa0febf1b94548"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f4a4e7c2e333277389fa0febf1b94548">¶</a></span><p>added “n” filter, disables <em>all</em> filters normally applied to an expression via <%page> or default_filters (but not those within the filter)</p> -<a class="changeset-link headerlink reference internal" href="#change-f4a4e7c2e333277389fa0febf1b94548">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.5-5"><span class="target" id="change-1373f4756af28d08dc3d0c42b55ba89f"></span><p>added buffer_filters argument, defines filters applied to the return value +<li><p class="caption" id="change-0.1.5-5"><span class="target" id="change-1373f4756af28d08dc3d0c42b55ba89f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-1373f4756af28d08dc3d0c42b55ba89f">¶</a></span><p>added buffer_filters argument, defines filters applied to the return value of buffered/cached/filtered %defs, after all filters defined with the %def itself have been applied. allows the creation of default expression filters that let the output of return-valued %defs “opt out” of that filtering via passing special attributes or objects.</p> -<a class="changeset-link headerlink reference internal" href="#change-1373f4756af28d08dc3d0c42b55ba89f">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.4"> -<h3>0.1.4<a class="headerlink" href="#change-0.1.4" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.4<a class="headerlink" href="#change-0.1.4" title="Permalink to this headline">¶</a></h3> Released: Sat Mar 10 2007<ul class="simple"> -<li><p id="change-0.1.4-0"><span class="target" id="change-d9a3f08eba0431ad7fcc2c4a44ebbae6"></span><p>got defs-within-defs to be cacheable</p> -<a class="changeset-link headerlink reference internal" href="#change-d9a3f08eba0431ad7fcc2c4a44ebbae6">¶</a><p></p> +<li><p class="caption" id="change-0.1.4-0"><span class="target" id="change-d9a3f08eba0431ad7fcc2c4a44ebbae6"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d9a3f08eba0431ad7fcc2c4a44ebbae6">¶</a></span><p>got defs-within-defs to be cacheable</p> +<p></p> </p> </li> -<li><p id="change-0.1.4-1"><span class="target" id="change-810513a0fe251b003785e47c73c05d6b"></span><p>fixes to code parsing/whitespace adjusting where plain python comments +<li><p class="caption" id="change-0.1.4-1"><span class="target" id="change-810513a0fe251b003785e47c73c05d6b"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-810513a0fe251b003785e47c73c05d6b">¶</a></span><p>fixes to code parsing/whitespace adjusting where plain python comments may contain quote characters</p> -<a class="changeset-link headerlink reference internal" href="#change-810513a0fe251b003785e47c73c05d6b">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/23">#23</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/23">#23</a></p> </p> </li> -<li><p id="change-0.1.4-2"><span class="target" id="change-02205b506bd613a4038f90d3894ff1e4"></span><p>fix to variable scoping for identifiers only referenced within +<li><p class="caption" id="change-0.1.4-2"><span class="target" id="change-02205b506bd613a4038f90d3894ff1e4"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-02205b506bd613a4038f90d3894ff1e4">¶</a></span><p>fix to variable scoping for identifiers only referenced within functions</p> -<a class="changeset-link headerlink reference internal" href="#change-02205b506bd613a4038f90d3894ff1e4">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.4-3"><span class="target" id="change-dffdf2c7b62fa47b54cac838b32b5a15"></span><p>added a path normalization step to lookup so URIs like +<li><p class="caption" id="change-0.1.4-3"><span class="target" id="change-dffdf2c7b62fa47b54cac838b32b5a15"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-dffdf2c7b62fa47b54cac838b32b5a15">¶</a></span><p>added a path normalization step to lookup so URIs like “/foo/bar/../etc/../foo” pre-process the “..” tokens before checking the filesystem</p> -<a class="changeset-link headerlink reference internal" href="#change-dffdf2c7b62fa47b54cac838b32b5a15">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.4-4"><span class="target" id="change-2a6fb9feefccb0dc5a6a53f4a1145389"></span><p>fixed/improved “caller” semantics so that undefined caller is +<li><p class="caption" id="change-0.1.4-4"><span class="target" id="change-2a6fb9feefccb0dc5a6a53f4a1145389"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-2a6fb9feefccb0dc5a6a53f4a1145389">¶</a></span><p>fixed/improved “caller” semantics so that undefined caller is “UNDEFINED”, propigates __nonzero__ method so it evaulates to False if not present, True otherwise. this way you can say % if caller:n ${caller.body()}n% endif</p> -<a class="changeset-link headerlink reference internal" href="#change-2a6fb9feefccb0dc5a6a53f4a1145389">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.4-5"><span class="target" id="change-7969cae88e43d5ccd928a0e231e9d242"></span><p><%include> has an “args” attribute that can pass arguments to the +<li><p class="caption" id="change-0.1.4-5"><span class="target" id="change-7969cae88e43d5ccd928a0e231e9d242"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-7969cae88e43d5ccd928a0e231e9d242">¶</a></span><p><%include> has an “args” attribute that can pass arguments to the called template (keyword arguments only, must be declared in that page’s <%page> tag.)</p> -<a class="changeset-link headerlink reference internal" href="#change-7969cae88e43d5ccd928a0e231e9d242">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.4-6"><span class="target" id="change-4b7deb2ea46de8d9db7b502ced7728dd"></span><p><%include> plus arguments is also programmatically available via -self.include_file(<filename>, <a href="#id9"><span class="problematic" id="id10">**</span></a>kwargs)</p> -<a class="changeset-link headerlink reference internal" href="#change-4b7deb2ea46de8d9db7b502ced7728dd">¶</a><p></p> +<li><p class="caption" id="change-0.1.4-6"><span class="target" id="change-f4e1140bace372e2766d176ebdbafe3f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-f4e1140bace372e2766d176ebdbafe3f">¶</a></span><p><%include> plus arguments is also programmatically available via +self.include_file(<filename>, **kwargs)</p> +<p></p> </p> </li> -<li><p id="change-0.1.4-7"><span class="target" id="change-5e3d31c7ecde9769cc0daf0a545e50da"></span><p>further escaping added for multibyte expressions in %def, %call +<li><p class="caption" id="change-0.1.4-7"><span class="target" id="change-5e3d31c7ecde9769cc0daf0a545e50da"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5e3d31c7ecde9769cc0daf0a545e50da">¶</a></span><p>further escaping added for multibyte expressions in %def, %call attributes</p> -<a class="changeset-link headerlink reference internal" href="#change-5e3d31c7ecde9769cc0daf0a545e50da">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/24">#24</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/24">#24</a></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.3"> -<h3>0.1.3<a class="headerlink" href="#change-0.1.3" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.3<a class="headerlink" href="#change-0.1.3" title="Permalink to this headline">¶</a></h3> Released: Wed Feb 21 2007<ul class="simple"> -<li><p id="change-0.1.3-0"><span class="target" id="change-18db551453b5679b3f20ea5bdb7bdc52"></span><p><strong>*Small Syntax Change*</strong> - the single line comment character is now +<li><p class="caption" id="change-0.1.3-0"><span class="target" id="change-18db551453b5679b3f20ea5bdb7bdc52"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-18db551453b5679b3f20ea5bdb7bdc52">¶</a></span><p><strong>*Small Syntax Change*</strong> - the single line comment character is now <em>two</em> hash signs, i.e. “## this is a comment”. This avoids a common collection with CSS selectors.</p> -<a class="changeset-link headerlink reference internal" href="#change-18db551453b5679b3f20ea5bdb7bdc52">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.3-1"><span class="target" id="change-e30c3dbf8c63dae51878e95465b46c4b"></span><p>the magic “coding” comment (i.e. # coding:utf-8) will still work with +<li><p class="caption" id="change-0.1.3-1"><span class="target" id="change-e30c3dbf8c63dae51878e95465b46c4b"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e30c3dbf8c63dae51878e95465b46c4b">¶</a></span><p>the magic “coding” comment (i.e. # coding:utf-8) will still work with either one “#” sign or two for now; two is preferred going forward, i.e. ## coding:<someencoding>.</p> -<a class="changeset-link headerlink reference internal" href="#change-e30c3dbf8c63dae51878e95465b46c4b">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.3-2"><span class="target" id="change-722a3aa892f188f6c474fbe157b52980"></span><p>new multiline comment form: “<%doc> a comment </%doc>”</p> -<a class="changeset-link headerlink reference internal" href="#change-722a3aa892f188f6c474fbe157b52980">¶</a><p></p> +<li><p class="caption" id="change-0.1.3-2"><span class="target" id="change-722a3aa892f188f6c474fbe157b52980"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-722a3aa892f188f6c474fbe157b52980">¶</a></span><p>new multiline comment form: “<%doc> a comment </%doc>”</p> +<p></p> </p> </li> -<li><p id="change-0.1.3-3"><span class="target" id="change-d38fba282e33819ce79a8f8f93bfd42c"></span><p>UNDEFINED evaluates to False</p> -<a class="changeset-link headerlink reference internal" href="#change-d38fba282e33819ce79a8f8f93bfd42c">¶</a><p></p> +<li><p class="caption" id="change-0.1.3-3"><span class="target" id="change-d38fba282e33819ce79a8f8f93bfd42c"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d38fba282e33819ce79a8f8f93bfd42c">¶</a></span><p>UNDEFINED evaluates to False</p> +<p></p> </p> </li> -<li><p id="change-0.1.3-4"><span class="target" id="change-921044895d61328452e3a335bad34172"></span><p>improvement to scoping of “caller” variable when using <%call> tag</p> -<a class="changeset-link headerlink reference internal" href="#change-921044895d61328452e3a335bad34172">¶</a><p></p> +<li><p class="caption" id="change-0.1.3-4"><span class="target" id="change-921044895d61328452e3a335bad34172"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-921044895d61328452e3a335bad34172">¶</a></span><p>improvement to scoping of “caller” variable when using <%call> tag</p> +<p></p> </p> </li> -<li><p id="change-0.1.3-5"><span class="target" id="change-8be7ad08f79e900b80f8c291c23e7fe1"></span><p>added lexer error for unclosed control-line (%) line</p> -<a class="changeset-link headerlink reference internal" href="#change-8be7ad08f79e900b80f8c291c23e7fe1">¶</a><p></p> +<li><p class="caption" id="change-0.1.3-5"><span class="target" id="change-8be7ad08f79e900b80f8c291c23e7fe1"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-8be7ad08f79e900b80f8c291c23e7fe1">¶</a></span><p>added lexer error for unclosed control-line (%) line</p> +<p></p> </p> </li> -<li><p id="change-0.1.3-6"><span class="target" id="change-85b846c5476142b1c2506c5a32d50817"></span><p>added “preprocessor” argument to Template, TemplateLookup - is a single +<li><p class="caption" id="change-0.1.3-6"><span class="target" id="change-85b846c5476142b1c2506c5a32d50817"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-85b846c5476142b1c2506c5a32d50817">¶</a></span><p>added “preprocessor” argument to Template, TemplateLookup - is a single callable or list of callables which will be applied to the template text before lexing. given the text as an argument, returns the new text.</p> -<a class="changeset-link headerlink reference internal" href="#change-85b846c5476142b1c2506c5a32d50817">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.3-7"><span class="target" id="change-43d0af8d5e881c09c61799065df23349"></span><p>added mako.ext.preprocessors package, contains one preprocessor so far: +<li><p class="caption" id="change-0.1.3-7"><span class="target" id="change-43d0af8d5e881c09c61799065df23349"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-43d0af8d5e881c09c61799065df23349">¶</a></span><p>added mako.ext.preprocessors package, contains one preprocessor so far: ‘convert_comments’, which will convert single # comments to the new ## format</p> -<a class="changeset-link headerlink reference internal" href="#change-43d0af8d5e881c09c61799065df23349">¶</a><p></p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.2"> -<h3>0.1.2<a class="headerlink" href="#change-0.1.2" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.2<a class="headerlink" href="#change-0.1.2" title="Permalink to this headline">¶</a></h3> Released: Thu Feb 1 2007<ul class="simple"> -<li><p id="change-0.1.2-0"><span class="target" id="change-e5e97c09505aa0d25c29ce1e158d4a8f"></span><p>fix to parsing of code/expression blocks to insure that non-ascii +<li><p class="caption" id="change-0.1.2-0"><span class="target" id="change-e5e97c09505aa0d25c29ce1e158d4a8f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e5e97c09505aa0d25c29ce1e158d4a8f">¶</a></span><p>fix to parsing of code/expression blocks to insure that non-ascii characters, combined with a template that indicates a non-standard encoding, are expanded into backslash-escaped glyphs before being AST parsed</p> -<a class="changeset-link headerlink reference internal" href="#change-e5e97c09505aa0d25c29ce1e158d4a8f">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/11">#11</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/11">#11</a></p> </p> </li> -<li><p id="change-0.1.2-1"><span class="target" id="change-3ff8d6c650379a6f712a25b5d9f0f67f"></span><p>all template lexing converts the template to unicode first, to +<li><p class="caption" id="change-0.1.2-1"><span class="target" id="change-3ff8d6c650379a6f712a25b5d9f0f67f"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-3ff8d6c650379a6f712a25b5d9f0f67f">¶</a></span><p>all template lexing converts the template to unicode first, to immediately catch any encoding issues and ensure internal unicode representation.</p> -<a class="changeset-link headerlink reference internal" href="#change-3ff8d6c650379a6f712a25b5d9f0f67f">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.2-2"><span class="target" id="change-0b29735786156418071800fe54aa64cd"></span><p>added module_filename argument to Template to allow specification of a +<li><p class="caption" id="change-0.1.2-2"><span class="target" id="change-0b29735786156418071800fe54aa64cd"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-0b29735786156418071800fe54aa64cd">¶</a></span><p>added module_filename argument to Template to allow specification of a specific module file</p> -<a class="changeset-link headerlink reference internal" href="#change-0b29735786156418071800fe54aa64cd">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.2-3"><span class="target" id="change-6904da36fbdded623dc4b3ee751d5674"></span><p>added modulename_callable to TemplateLookup to allow a function to +<li><p class="caption" id="change-0.1.2-3"><span class="target" id="change-6904da36fbdded623dc4b3ee751d5674"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-6904da36fbdded623dc4b3ee751d5674">¶</a></span><p>added modulename_callable to TemplateLookup to allow a function to determine module filenames (takes filename, uri arguments). used for</p> -<a class="changeset-link headerlink reference internal" href="#change-6904da36fbdded623dc4b3ee751d5674">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/14">#14</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/14">#14</a></p> </p> </li> -<li><p id="change-0.1.2-4"><span class="target" id="change-ecf4eb2962f40391b75f8ce8f2a94a08"></span><p>added optional input_encoding flag to Template, to allow sending a +<li><p class="caption" id="change-0.1.2-4"><span class="target" id="change-ecf4eb2962f40391b75f8ce8f2a94a08"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-ecf4eb2962f40391b75f8ce8f2a94a08">¶</a></span><p>added optional input_encoding flag to Template, to allow sending a unicode() object with no magic encoding comment</p> -<a class="changeset-link headerlink reference internal" href="#change-ecf4eb2962f40391b75f8ce8f2a94a08">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.2-5"><span class="target" id="change-5ea31cc5e58c79c774aaa9458928f827"></span><p>“expression_filter” argument in <%page> applies only to expressions</p> -<a class="changeset-link headerlink reference internal" href="#change-5ea31cc5e58c79c774aaa9458928f827">¶</a><p></p> +<li><p class="caption" id="change-0.1.2-5"><span class="target" id="change-5ea31cc5e58c79c774aaa9458928f827"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5ea31cc5e58c79c774aaa9458928f827">¶</a></span><p>”expression_filter” argument in <%page> applies only to expressions</p> +<p></p> </p> </li> -<li><p id="change-0.1.2-6"><span class="target" id="change-84beefcbcdc568675b6e3fefd7940957"><strong>[“unicode”] </strong></span><p>added “default_filters” argument to Template, TemplateLookup. applies only +<li><p class="caption" id="change-0.1.2-6"><span class="target" id="change-84beefcbcdc568675b6e3fefd7940957"><strong>[“unicode”]</strong> <a class="changelog-reference headerlink reference internal" href="#change-84beefcbcdc568675b6e3fefd7940957">¶</a></span><p>added “default_filters” argument to Template, TemplateLookup. applies only to expressions, gets prepended to “expression_filter” arg from <%page>. defaults to, so that all expressions get stringified into u’’ by default (this is what Mako already does). By setting to [], expressions are passed through raw.</p> -<a class="changeset-link headerlink reference internal" href="#change-84beefcbcdc568675b6e3fefd7940957">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.2-7"><span class="target" id="change-fd580f1d839dc719fa1f0563b46ba474"></span><p>added “imports” argument to Template, TemplateLookup. so you can predefine +<li><p class="caption" id="change-0.1.2-7"><span class="target" id="change-fd580f1d839dc719fa1f0563b46ba474"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-fd580f1d839dc719fa1f0563b46ba474">¶</a></span><p>added “imports” argument to Template, TemplateLookup. so you can predefine a list of import statements at the top of the template. can be used in conjunction with default_filters.</p> -<a class="changeset-link headerlink reference internal" href="#change-fd580f1d839dc719fa1f0563b46ba474">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.2-8"><span class="target" id="change-817d592b540ba64129e24055c5f8ec27"></span><p>support for CRLF templates…whoops ! welcome to all the windows users.</p> -<a class="changeset-link headerlink reference internal" href="#change-817d592b540ba64129e24055c5f8ec27">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/16">#16</a></p> +<li><p class="caption" id="change-0.1.2-8"><span class="target" id="change-817d592b540ba64129e24055c5f8ec27"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-817d592b540ba64129e24055c5f8ec27">¶</a></span><p>support for CRLF templates…whoops ! welcome to all the windows users.</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/16">#16</a></p> </p> </li> -<li><p id="change-0.1.2-9"><span class="target" id="change-5976a1e5691f501b38fc485209ec52a1"></span><p>small fix to local variable propigation for locals that are conditionally +<li><p class="caption" id="change-0.1.2-9"><span class="target" id="change-5976a1e5691f501b38fc485209ec52a1"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-5976a1e5691f501b38fc485209ec52a1">¶</a></span><p>small fix to local variable propigation for locals that are conditionally declared</p> -<a class="changeset-link headerlink reference internal" href="#change-5976a1e5691f501b38fc485209ec52a1">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.2-10"><span class="target" id="change-e51de8d14422e4b2b7fb4d583f5fb5f3"></span><p>got “top level” def calls to work, i.e. template.get_def(“somedef”).render()</p> -<a class="changeset-link headerlink reference internal" href="#change-e51de8d14422e4b2b7fb4d583f5fb5f3">¶</a><p></p> +<li><p class="caption" id="change-0.1.2-10"><span class="target" id="change-e51de8d14422e4b2b7fb4d583f5fb5f3"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e51de8d14422e4b2b7fb4d583f5fb5f3">¶</a></span><p>got “top level” def calls to work, i.e. template.get_def(“somedef”).render()</p> +<p></p> </p> </li> </ul> </div> <div class="section" id="change-0.1.1"> -<h3>0.1.1<a class="headerlink" href="#change-0.1.1" title="Permalink to this headline">¶</a></h3> +<h3 class="release-version">0.1.1<a class="headerlink" href="#change-0.1.1" title="Permalink to this headline">¶</a></h3> Released: Sun Jan 14 2007<ul class="simple"> -<li><p id="change-0.1.1-0"><span class="target" id="change-05b7c1f3eb0cb4630b5ebbd1a172f5d5"></span><p>buffet plugin supports string-based templates, allows ToscaWidgets to work</p> -<a class="changeset-link headerlink reference internal" href="#change-05b7c1f3eb0cb4630b5ebbd1a172f5d5">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/8">#8</a></p> +<li><p class="caption" id="change-0.1.1-0"><span class="target" id="change-05b7c1f3eb0cb4630b5ebbd1a172f5d5"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-05b7c1f3eb0cb4630b5ebbd1a172f5d5">¶</a></span><p>buffet plugin supports string-based templates, allows ToscaWidgets to work</p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/8">#8</a></p> </p> </li> -<li><p id="change-0.1.1-1"><span class="target" id="change-20940aacb7e79ba6e20a4826ed237c0b"></span><p>AST parsing fixes: fixed TryExcept identifier parsing</p> -<a class="changeset-link headerlink reference internal" href="#change-20940aacb7e79ba6e20a4826ed237c0b">¶</a><p></p> +<li><p class="caption" id="change-0.1.1-1"><span class="target" id="change-20940aacb7e79ba6e20a4826ed237c0b"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-20940aacb7e79ba6e20a4826ed237c0b">¶</a></span><p>AST parsing fixes: fixed TryExcept identifier parsing</p> +<p></p> </p> </li> -<li><p id="change-0.1.1-2"><span class="target" id="change-eb9efa2f093687fd2d4f5f7ac4e51c3c"></span><p>removed textmate tmbundle from contrib and into separate SVN location; +<li><p class="caption" id="change-0.1.1-2"><span class="target" id="change-eb9efa2f093687fd2d4f5f7ac4e51c3c"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-eb9efa2f093687fd2d4f5f7ac4e51c3c">¶</a></span><p>removed textmate tmbundle from contrib and into separate SVN location; windows users cant handle those files, setuptools not very good at “pruning” certain directories</p> -<a class="changeset-link headerlink reference internal" href="#change-eb9efa2f093687fd2d4f5f7ac4e51c3c">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.1-3"><span class="target" id="change-e1142489a6eb32082650995d95b37a71"></span><p>fix so that “cache_timeout” parameter is propigated</p> -<a class="changeset-link headerlink reference internal" href="#change-e1142489a6eb32082650995d95b37a71">¶</a><p></p> +<li><p class="caption" id="change-0.1.1-3"><span class="target" id="change-e1142489a6eb32082650995d95b37a71"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-e1142489a6eb32082650995d95b37a71">¶</a></span><p>fix so that “cache_timeout” parameter is propigated</p> +<p></p> </p> </li> -<li><p id="change-0.1.1-4"><span class="target" id="change-603cfb5b4987686ea04bebe62aa32b24"></span><p>fix to expression filters so that string conversion (actually unicode) +<li><p class="caption" id="change-0.1.1-4"><span class="target" id="change-603cfb5b4987686ea04bebe62aa32b24"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-603cfb5b4987686ea04bebe62aa32b24">¶</a></span><p>fix to expression filters so that string conversion (actually unicode) properly occurs before filtering</p> -<a class="changeset-link headerlink reference internal" href="#change-603cfb5b4987686ea04bebe62aa32b24">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.1-5"><span class="target" id="change-b07fbe08a504a4fa5f2d9827be99693a"></span><p>better error message when a lookup is attempted with a template that has no +<li><p class="caption" id="change-0.1.1-5"><span class="target" id="change-b07fbe08a504a4fa5f2d9827be99693a"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-b07fbe08a504a4fa5f2d9827be99693a">¶</a></span><p>better error message when a lookup is attempted with a template that has no lookup</p> -<a class="changeset-link headerlink reference internal" href="#change-b07fbe08a504a4fa5f2d9827be99693a">¶</a><p></p> +<p></p> </p> </li> -<li><p id="change-0.1.1-6"><span class="target" id="change-bf10710d0a3d4e00b23e4c12739df8d8"></span><p>implemented “module” attribute for namespace</p> -<a class="changeset-link headerlink reference internal" href="#change-bf10710d0a3d4e00b23e4c12739df8d8">¶</a><p></p> +<li><p class="caption" id="change-0.1.1-6"><span class="target" id="change-bf10710d0a3d4e00b23e4c12739df8d8"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-bf10710d0a3d4e00b23e4c12739df8d8">¶</a></span><p>implemented “module” attribute for namespace</p> +<p></p> </p> </li> -<li><p id="change-0.1.1-7"><span class="target" id="change-d2a20975eda94230da878d7b2bc53081"></span><p>fix to code generation to correctly track multiple defs with the same name</p> -<a class="changeset-link headerlink reference internal" href="#change-d2a20975eda94230da878d7b2bc53081">¶</a><p></p> +<li><p class="caption" id="change-0.1.1-7"><span class="target" id="change-d2a20975eda94230da878d7b2bc53081"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-d2a20975eda94230da878d7b2bc53081">¶</a></span><p>fix to code generation to correctly track multiple defs with the same name</p> +<p></p> </p> </li> -<li><p id="change-0.1.1-8"><span class="target" id="change-8e234744095c72fc80b927b7a27b3d4e"></span><p>“directories” can be passed to TemplateLookup as a scalar in which case it +<li><p class="caption" id="change-0.1.1-8"><span class="target" id="change-8e234744095c72fc80b927b7a27b3d4e"><strong>[no_tags]</strong> <a class="changelog-reference headerlink reference internal" href="#change-8e234744095c72fc80b927b7a27b3d4e">¶</a></span><p>”directories” can be passed to TemplateLookup as a scalar in which case it gets converted to a list</p> -<a class="changeset-link headerlink reference internal" href="#change-8e234744095c72fc80b927b7a27b3d4e">¶</a><p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/9">#9</a></p> +<p>References: <a class="reference external" href="https://github.com/sqlalchemy/mako/issues/9">#9</a></p> </p> </li> </ul> @@ -2051,7 +2421,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -2066,7 +2436,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -2078,7 +2448,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/defs.html b/third_party/mako/doc/defs.html index eaaf969..4f9775a 100644 --- a/third_party/mako/doc/defs.html +++ b/third_party/mako/doc/defs.html
@@ -12,7 +12,7 @@ Defs and Blocks — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="The Mako Runtime Environment" href="runtime.html" /> <link rel="prev" title="Syntax" href="syntax.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Defs and Blocks @@ -244,23 +244,23 @@ <div class="section" id="calling-defs-programmatically"> <h3>Calling Defs Programmatically<a class="headerlink" href="#calling-defs-programmatically" title="Permalink to this headline">¶</a></h3> <p>You can call defs programmatically from any <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object -using the <a class="reference internal" href="usage.html#mako.template.Template.get_def" title="mako.template.Template.get_def"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_def()</span></code></a> method, which returns a <a class="reference internal" href="usage.html#mako.template.DefTemplate" title="mako.template.DefTemplate"><code class="xref py py-class docutils literal notranslate"><span class="pre">DefTemplate</span></code></a> +using the <a class="reference internal" href="usage.html#mako.template.Template.get_def" title="mako.template.Template.get_def"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.get_def()</span></code></a> method, which returns a <a class="reference internal" href="usage.html#mako.template.DefTemplate" title="mako.template.DefTemplate"><code class="xref py py-class docutils literal notranslate"><span class="pre">DefTemplate</span></code></a> object. This is a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> subclass which the parent <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> creates, and is usable like any other template:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> <span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"""</span> <span class="s2"> <</span><span class="si">%d</span><span class="s2">ef name="hi(name)"></span> -<span class="s2"> hi ${name}!</span> +<span class="s2"> hi $</span><span class="si">{name}</span><span class="s2">!</span> <span class="s2"> </</span><span class="si">%d</span><span class="s2">ef></span> <span class="s2"> <</span><span class="si">%d</span><span class="s2">ef name="bye(name)"></span> -<span class="s2"> bye ${name}!</span> +<span class="s2"> bye $</span><span class="si">{name}</span><span class="s2">!</span> <span class="s2"> </</span><span class="si">%d</span><span class="s2">ef></span> <span class="s2">"""</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">get_def</span><span class="p">(</span><span class="s2">"hi"</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"ed"</span><span class="p">))</span> -<span class="k">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">get_def</span><span class="p">(</span><span class="s2">"bye"</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"ed"</span><span class="p">))</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">get_def</span><span class="p">(</span><span class="s2">"hi"</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"ed"</span><span class="p">))</span> +<span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">get_def</span><span class="p">(</span><span class="s2">"bye"</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"ed"</span><span class="p">))</span></pre></div> </div> </div> <div class="section" id="defs-within-defs"> @@ -672,7 +672,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -687,7 +687,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -699,7 +699,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/filtering.html b/third_party/mako/doc/filtering.html index ee1119c..f2aa0290 100644 --- a/third_party/mako/doc/filtering.html +++ b/third_party/mako/doc/filtering.html
@@ -12,7 +12,7 @@ Filtering and Buffering — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="The Unicode Chapter" href="unicode.html" /> <link rel="prev" title="Inheritance" href="inheritance.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Filtering and Buffering @@ -256,7 +256,7 @@ <span class="kn">from</span> <span class="nn">mypackage</span> <span class="kn">import</span> <span class="n">myfilter</span> <span class="k">def</span> <span class="nf">render_body</span><span class="p">(</span><span class="n">context</span><span class="p">):</span> - <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">myfilter</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="s2">"some text"</span><span class="p">)))</span></pre></div> + <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">myfilter</span><span class="p">(</span><span class="n">unicode</span><span class="p">(</span><span class="s2">"some text"</span><span class="p">)))</span></pre></div> </div> </div> <div class="section" id="turning-off-filtering-with-the-n-filter"> @@ -361,10 +361,10 @@ calling the target function, after setting up a buffered environment. To send arguments to the function, just send them to <code class="docutils literal notranslate"><span class="pre">capture</span></code> instead:</p> -<div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="n">capture</span><span class="p">(</span><span class="n">somedef</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="s1">'hi'</span><span class="p">,</span> <span class="n">use_paging</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span></pre></div> +<div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="n">capture</span><span class="p">(</span><span class="n">somedef</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="s1">'hi'</span><span class="p">,</span> <span class="n">use_paging</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span></pre></div> </div> <p>The above call is equivalent to the unbuffered call:</p> -<div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="n">somedef</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="s1">'hi'</span><span class="p">,</span> <span class="n">use_paging</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span></pre></div> +<div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="n">somedef</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="s1">'hi'</span><span class="p">,</span> <span class="n">use_paging</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span></pre></div> </div> </div> <div class="section" id="decorating"> @@ -437,7 +437,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -452,7 +452,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -464,7 +464,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/genindex.html b/third_party/mako/doc/genindex.html index 135395a8..26cad55 100644 --- a/third_party/mako/doc/genindex.html +++ b/third_party/mako/doc/genindex.html
@@ -9,7 +9,7 @@ <title> - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -29,7 +29,7 @@ <link rel="index" title="Index" href="#" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <!-- end layout.mako headers --> @@ -51,7 +51,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -63,7 +63,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -81,7 +81,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Index @@ -226,7 +226,7 @@ <dt> - <a href="namespaces.html#mako.runtime.Namespace.cache">cache() (mako.runtime.Namespace property)</a> + <a href="namespaces.html#mako.runtime.Namespace.cache">cache (mako.runtime.Namespace attribute)</a> </dt> @@ -300,7 +300,7 @@ <dt> - <a href="usage.html#mako.template.Template.code">code() (mako.template.Template property)</a> + <a href="usage.html#mako.template.Template.code">code (mako.template.Template attribute)</a> </dt> @@ -438,23 +438,13 @@ <dt> - <a href="namespaces.html#mako.runtime.Namespace.filename">filename (mako.runtime.Namespace attribute)</a> + <a href="namespaces.html#mako.runtime.ModuleNamespace.filename">filename (mako.runtime.ModuleNamespace attribute)</a> </dt> <dd><dl> - <dt><a href="usage.html#mako.template.Template.params.filename">(mako.template.Template parameter)</a> + <dt><a href="namespaces.html#mako.runtime.Namespace.filename">(mako.runtime.Namespace attribute)</a> </dt> - </dl></dd> - - - - -<dt> - <a href="namespaces.html#mako.runtime.ModuleNamespace.filename">filename() (mako.runtime.ModuleNamespace property)</a> -</dt> - - <dd><dl> - <dt><a href="namespaces.html#mako.runtime.TemplateNamespace.filename">(mako.runtime.TemplateNamespace property)</a> + <dt><a href="namespaces.html#mako.runtime.TemplateNamespace.filename">(mako.runtime.TemplateNamespace attribute)</a> </dt> </dl></dd> @@ -726,7 +716,7 @@ <dt> - <a href="runtime.html#mako.runtime.Context.kwargs">kwargs() (mako.runtime.Context property)</a> + <a href="runtime.html#mako.runtime.Context.kwargs">kwargs (mako.runtime.Context attribute)</a> </dt> @@ -764,9 +754,13 @@ <dt> - <a href="usage.html#mako.template.Template.params.lookup">lookup (mako.template.Template parameter)</a> + <a href="runtime.html#mako.runtime.Context.lookup">lookup (mako.runtime.Context attribute)</a> </dt> + <dd><dl> + <dt><a href="usage.html#mako.template.Template.params.lookup">(mako.template.Template parameter)</a> + </dt> + </dl></dd> @@ -774,14 +768,6 @@ <dt> - <a href="runtime.html#mako.runtime.Context.lookup">lookup() (mako.runtime.Context property)</a> -</dt> - - - - - -<dt> <a href="runtime.html#mako.runtime.LoopContext">LoopContext (class in mako.runtime)</a> </dt> @@ -807,14 +793,10 @@ <a href="namespaces.html#mako.runtime.Namespace.module">module (mako.runtime.Namespace attribute)</a> </dt> - - - - -<dt> - <a href="namespaces.html#mako.runtime.TemplateNamespace.module">module() (mako.runtime.TemplateNamespace property)</a> -</dt> - + <dd><dl> + <dt><a href="namespaces.html#mako.runtime.TemplateNamespace.module">(mako.runtime.TemplateNamespace attribute)</a> + </dt> + </dl></dd> @@ -1059,14 +1041,10 @@ <a href="usage.html#mako.exceptions.RichTraceback.source">source (mako.exceptions.RichTraceback attribute)</a> </dt> - - - - -<dt> - <a href="usage.html#mako.template.Template.source">source() (mako.template.Template property)</a> -</dt> - + <dd><dl> + <dt><a href="usage.html#mako.template.Template.source">(mako.template.Template attribute)</a> + </dt> + </dl></dd> @@ -1190,14 +1168,6 @@ </dl></td><td width="33%" valign="top"><dl> - -<dt> - <a href="namespaces.html#mako.runtime.TemplateNamespace.uri">uri() (mako.runtime.TemplateNamespace property)</a> -</dt> - - - - <dt></dt></dl> </td></tr></table> <h2 id="V">V</h2> @@ -1255,7 +1225,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -1270,7 +1240,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -1282,7 +1252,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/index.html b/third_party/mako/doc/index.html index e391121..16bfed7 100644 --- a/third_party/mako/doc/index.html +++ b/third_party/mako/doc/index.html
@@ -9,7 +9,7 @@ <title> - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -29,7 +29,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="#" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="#" /> <link rel="next" title="Usage" href="usage.html" /> <!-- end layout.mako headers --> @@ -52,7 +52,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -64,7 +64,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -85,7 +85,7 @@ </div> <div id="docs-navigation-banner"> - <a href="#">Mako 1.0.14 Documentation</a> + <a href="#">Mako 1.1.4 Documentation</a> <h2> @@ -182,10 +182,11 @@ </ul> </li> <li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog</a><ul> -<li class="toctree-l2"><a class="reference internal" href="changelog.html#id1">1.0</a></li> -<li class="toctree-l2"><a class="reference internal" href="changelog.html#id2">0.9</a></li> -<li class="toctree-l2"><a class="reference internal" href="changelog.html#id3">0.8</a></li> -<li class="toctree-l2"><a class="reference internal" href="changelog.html#id4">0.7</a></li> +<li class="toctree-l2"><a class="reference internal" href="changelog.html#id1">1.1</a></li> +<li class="toctree-l2"><a class="reference internal" href="changelog.html#id2">1.0</a></li> +<li class="toctree-l2"><a class="reference internal" href="changelog.html#id3">0.9</a></li> +<li class="toctree-l2"><a class="reference internal" href="changelog.html#id4">0.8</a></li> +<li class="toctree-l2"><a class="reference internal" href="changelog.html#id5">0.7</a></li> <li class="toctree-l2"><a class="reference internal" href="changelog.html#older-versions">Older Versions</a></li> </ul> </li> @@ -210,7 +211,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -225,7 +226,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -237,7 +238,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/inheritance.html b/third_party/mako/doc/inheritance.html index 0d4c109..7b922c1 100644 --- a/third_party/mako/doc/inheritance.html +++ b/third_party/mako/doc/inheritance.html
@@ -12,7 +12,7 @@ Inheritance — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Filtering and Buffering" href="filtering.html" /> <link rel="prev" title="Namespaces" href="namespaces.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Inheritance @@ -666,7 +666,7 @@ </div> <div class="section" id="inheritable-attributes"> <span id="inheritance-attr"></span><h2>Inheritable Attributes<a class="headerlink" href="#inheritable-attributes" title="Permalink to this headline">¶</a></h2> -<p>The <a class="reference internal" href="namespaces.html#mako.runtime.Namespace.attr" title="mako.runtime.Namespace.attr"><code class="xref py py-attr docutils literal notranslate"><span class="pre">attr</span></code></a> accessor of the <a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> object +<p>The <a class="reference internal" href="namespaces.html#mako.runtime.Namespace.attr" title="mako.runtime.Namespace.attr"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Namespace.attr</span></code></a> accessor of the <a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> object allows access to module level variables declared in a template. By accessing <code class="docutils literal notranslate"><span class="pre">self.attr</span></code>, you can access regular attributes from the inheritance chain as declared in <code class="docutils literal notranslate"><span class="pre"><%!</span> <span class="pre">%></span></code> sections. Such as:</p> @@ -712,7 +712,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -727,7 +727,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -739,7 +739,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/namespaces.html b/third_party/mako/doc/namespaces.html index 8ce234d..c41f6b1f 100644 --- a/third_party/mako/doc/namespaces.html +++ b/third_party/mako/doc/namespaces.html
@@ -12,7 +12,7 @@ Namespaces — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Inheritance" href="inheritance.html" /> <link rel="prev" title="The Mako Runtime Environment" href="runtime.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Namespaces @@ -335,14 +335,14 @@ receive all other keyword arguments. If <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code> or similar is not present, the argument <code class="docutils literal notranslate"><span class="pre">**pageargs</span></code> gets tacked on by Mako. When the template is called as a top-level template (i.e. -via <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a>) or via the <code class="docutils literal notranslate"><span class="pre"><%include></span></code> tag, the +via <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a>) or via the <code class="docutils literal notranslate"><span class="pre"><%include></span></code> tag, the values for these arguments will be pulled from the <code class="docutils literal notranslate"><span class="pre">Context</span></code>. In all other cases, i.e. via calling the <code class="docutils literal notranslate"><span class="pre">body()</span></code> method, the arguments are taken as ordinary arguments from the method call. So above, the body might be called as:</p> <div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">someval</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span> <span class="n">delta</span><span class="o">=</span><span class="mi">7</span><span class="p">)</span><span class="cp">}</span><span class="x"></span></pre></div> </div> -<p>The <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> object also supplies a <code class="xref py py-attr docutils literal notranslate"><span class="pre">kwargs</span></code> +<p>The <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> object also supplies a <a class="reference internal" href="runtime.html#mako.runtime.Context.kwargs" title="mako.runtime.Context.kwargs"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Context.kwargs</span></code></a> accessor, for cases when you’d like to pass along the top level context arguments to a <code class="docutils literal notranslate"><span class="pre">body()</span></code> callable:</p> <div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">(</span><span class="o">**</span><span class="n">context</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span><span class="cp">}</span><span class="x"></span></pre></div> @@ -521,9 +521,39 @@ </div> <div class="section" id="api-reference"> <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2> -<dl class="class"> +<table class="longtable docutils"> +<colgroup> +<col style="width: 10%" /> +<col style="width: 90%" /> +</colgroup> +<thead> +<tr class="row-odd"><th class="head">Object Name</th> +<th class="head">Description</th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.capture"><code class="sig-name descname">capture</code></a>(context, callable_, *args, **kwargs)</p></td> +<td><p>Execute the given template def, capturing the output into +a buffer.</p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.ModuleNamespace"><code class="sig-name descname">ModuleNamespace</code></a></p></td> +<td><p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a></p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.Namespace"><code class="sig-name descname">Namespace</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.supports_caller"><code class="sig-name descname">supports_caller</code></a>(func)</p></td> +<td><p>Apply a caller_stack compatibility decorator to a plain +Python function.</p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.TemplateNamespace"><code class="sig-name descname">TemplateNamespace</code></a></p></td> +<td><p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a></p></td> +</tr> +</tbody> +</table> +<dl class="py class"> <dt id="mako.runtime.Namespace"> -<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">Namespace</code><span class="sig-paren">(</span><em class="sig-param">name</em>, <em class="sig-param">context</em>, <em class="sig-param">callables=None</em>, <em class="sig-param">inherits=None</em>, <em class="sig-param">populate_self=True</em>, <em class="sig-param">calling_uri=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">Namespace</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">context</span></em>, <em class="sig-param"><span class="n">callables</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inherits</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">populate_self</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">calling_uri</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>Provides access to collections of rendering methods, which can be local, from other templates, or from imported modules.</p> @@ -533,9 +563,9 @@ </div> <p><a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> also contains several built-in attributes described here.</p> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.attr"> -<code class="sig-name descname">attr</code><a class="headerlink" href="#mako.runtime.Namespace.attr" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">attr</code><a class="headerlink" href="#mako.runtime.Namespace.attr" title="Permalink to this definition">¶</a></dt> <dd><p>Access module level attributes by name.</p> <p>This accessor allows templates to supply “scalar” attributes which are particularly handy in inheritance @@ -547,17 +577,17 @@ </div> </dd></dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.cache"> -<em class="property">property </em><code class="sig-name descname">cache</code><a class="headerlink" href="#mako.runtime.Namespace.cache" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">cache</code><a class="headerlink" href="#mako.runtime.Namespace.cache" title="Permalink to this definition">¶</a></dt> <dd><p>Return the <a class="reference internal" href="caching.html#mako.cache.Cache" title="mako.cache.Cache"><code class="xref py py-class docutils literal notranslate"><span class="pre">Cache</span></code></a> object referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> object’s <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.context"> -<code class="sig-name descname">context</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.context" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">context</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.context" title="Permalink to this definition">¶</a></dt> <dd><p>The <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> object for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>.</p> <p>Namespaces are often created with copies of contexts that contain slightly different data, particularly in inheritance @@ -566,9 +596,9 @@ one-another.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.filename"> -<code class="sig-name descname">filename</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.filename" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">filename</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.filename" title="Permalink to this definition">¶</a></dt> <dd><p>The path of the filesystem file used for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>’s module or template.</p> <p>If this is a pure module-based @@ -577,9 +607,9 @@ template file location.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Namespace.get_cached"> -<code class="sig-name descname">get_cached</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.get_cached" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">get_cached</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kwargs</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.get_cached" title="Permalink to this definition">¶</a></dt> <dd><p>Return a value from the <a class="reference internal" href="caching.html#mako.cache.Cache" title="mako.cache.Cache"><code class="xref py py-class docutils literal notranslate"><span class="pre">Cache</span></code></a> referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> object’s <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>.</p> <p>The advantage to this method versus direct access to the @@ -589,9 +619,9 @@ by <code class="docutils literal notranslate"><span class="pre"><%page></span></code>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Namespace.get_namespace"> -<code class="sig-name descname">get_namespace</code><span class="sig-paren">(</span><em class="sig-param">uri</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.get_namespace" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">get_namespace</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.get_namespace" title="Permalink to this definition">¶</a></dt> <dd><p>Return a <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> corresponding to the given <code class="docutils literal notranslate"><span class="pre">uri</span></code>.</p> <p>If the given <code class="docutils literal notranslate"><span class="pre">uri</span></code> is a relative URI (i.e. it does not contain a leading slash <code class="docutils literal notranslate"><span class="pre">/</span></code>), the <code class="docutils literal notranslate"><span class="pre">uri</span></code> is adjusted to @@ -609,39 +639,39 @@ namespace.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Namespace.get_template"> -<code class="sig-name descname">get_template</code><span class="sig-paren">(</span><em class="sig-param">uri</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.get_template" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">get_template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.get_template" title="Permalink to this definition">¶</a></dt> <dd><p>Return a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> from the given <code class="docutils literal notranslate"><span class="pre">uri</span></code>.</p> <p>The <code class="docutils literal notranslate"><span class="pre">uri</span></code> resolution is relative to the <code class="docutils literal notranslate"><span class="pre">uri</span></code> of this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> object’s <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Namespace.include_file"> -<code class="sig-name descname">include_file</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.include_file" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">include_file</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kwargs</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Namespace.include_file" title="Permalink to this definition">¶</a></dt> <dd><p>Include a file at the given <code class="docutils literal notranslate"><span class="pre">uri</span></code>.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.module"> -<code class="sig-name descname">module</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.module" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">module</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.module" title="Permalink to this definition">¶</a></dt> <dd><p>The Python module referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>.</p> <p>If the namespace references a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>, then this module is the equivalent of <code class="docutils literal notranslate"><span class="pre">template.module</span></code>, i.e. the generated module for the template.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.template"> -<code class="sig-name descname">template</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.template" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">template</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.template" title="Permalink to this definition">¶</a></dt> <dd><p>The <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>, if any.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.runtime.Namespace.uri"> -<code class="sig-name descname">uri</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.uri" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Namespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Namespace.</span></code></a><code class="sig-name descname">uri</code><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.uri" title="Permalink to this definition">¶</a></dt> <dd><p>The URI for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>’s template.</p> <p>I.e. whatever was sent to <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TemplateLookup.get_template()</span></code></a>.</p> <p>This is the equivalent of <code class="xref py py-attr docutils literal notranslate"><span class="pre">Template.uri</span></code>.</p> @@ -649,31 +679,34 @@ </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.runtime.TemplateNamespace"> -<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">TemplateNamespace</code><span class="sig-paren">(</span><em class="sig-param">name</em>, <em class="sig-param">context</em>, <em class="sig-param">template=None</em>, <em class="sig-param">templateuri=None</em>, <em class="sig-param">callables=None</em>, <em class="sig-param">inherits=None</em>, <em class="sig-param">populate_self=True</em>, <em class="sig-param">calling_uri=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.TemplateNamespace" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">TemplateNamespace</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">context</span></em>, <em class="sig-param"><span class="n">template</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">templateuri</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">callables</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inherits</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">populate_self</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">calling_uri</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.TemplateNamespace" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a></p> -<p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a></p> <p>A <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> specific to a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> instance.</p> -<dl class="method"> +<div class="class-bases docutils container"> +<p><strong>Class signature</strong></p> +<p>class <a class="reference internal" href="#mako.runtime.TemplateNamespace" title="mako.runtime.TemplateNamespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.TemplateNamespace</span></code></a> (<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a>)</p> +</div> +<dl class="py attribute"> <dt id="mako.runtime.TemplateNamespace.filename"> -<em class="property">property </em><code class="sig-name descname">filename</code><a class="headerlink" href="#mako.runtime.TemplateNamespace.filename" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.TemplateNamespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.TemplateNamespace.</span></code></a><code class="sig-name descname">filename</code><a class="headerlink" href="#mako.runtime.TemplateNamespace.filename" title="Permalink to this definition">¶</a></dt> <dd><p>The path of the filesystem file used for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>’s module or template.</p> </dd></dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.runtime.TemplateNamespace.module"> -<em class="property">property </em><code class="sig-name descname">module</code><a class="headerlink" href="#mako.runtime.TemplateNamespace.module" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.TemplateNamespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.TemplateNamespace.</span></code></a><code class="sig-name descname">module</code><a class="headerlink" href="#mako.runtime.TemplateNamespace.module" title="Permalink to this definition">¶</a></dt> <dd><p>The Python module referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>.</p> <p>If the namespace references a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>, then this module is the equivalent of <code class="docutils literal notranslate"><span class="pre">template.module</span></code>, i.e. the generated module for the template.</p> </dd></dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.runtime.TemplateNamespace.uri"> -<em class="property">property </em><code class="sig-name descname">uri</code><a class="headerlink" href="#mako.runtime.TemplateNamespace.uri" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.TemplateNamespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.TemplateNamespace.</span></code></a><code class="sig-name descname">uri</code><a class="headerlink" href="#mako.runtime.TemplateNamespace.uri" title="Permalink to this definition">¶</a></dt> <dd><p>The URI for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>’s template.</p> <p>I.e. whatever was sent to <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TemplateLookup.get_template()</span></code></a>.</p> <p>This is the equivalent of <code class="xref py py-attr docutils literal notranslate"><span class="pre">Template.uri</span></code>.</p> @@ -681,32 +714,35 @@ </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.runtime.ModuleNamespace"> -<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">ModuleNamespace</code><span class="sig-paren">(</span><em class="sig-param">name</em>, <em class="sig-param">context</em>, <em class="sig-param">module</em>, <em class="sig-param">callables=None</em>, <em class="sig-param">inherits=None</em>, <em class="sig-param">populate_self=True</em>, <em class="sig-param">calling_uri=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.ModuleNamespace" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">ModuleNamespace</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">context</span></em>, <em class="sig-param"><span class="n">module</span></em>, <em class="sig-param"><span class="n">callables</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inherits</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">populate_self</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">calling_uri</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.ModuleNamespace" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a></p> -<p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a></p> <p>A <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a> specific to a Python module instance.</p> -<dl class="method"> +<div class="class-bases docutils container"> +<p><strong>Class signature</strong></p> +<p>class <a class="reference internal" href="#mako.runtime.ModuleNamespace" title="mako.runtime.ModuleNamespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.ModuleNamespace</span></code></a> (<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a>)</p> +</div> +<dl class="py attribute"> <dt id="mako.runtime.ModuleNamespace.filename"> -<em class="property">property </em><code class="sig-name descname">filename</code><a class="headerlink" href="#mako.runtime.ModuleNamespace.filename" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.ModuleNamespace"><code class="docutils literal notranslate"><span class="pre">mako.runtime.ModuleNamespace.</span></code></a><code class="sig-name descname">filename</code><a class="headerlink" href="#mako.runtime.ModuleNamespace.filename" title="Permalink to this definition">¶</a></dt> <dd><p>The path of the filesystem file used for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>’s module or template.</p> </dd></dl> </dd></dl> -<dl class="function"> +<dl class="py function"> <dt id="mako.runtime.supports_caller"> -<code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">supports_caller</code><span class="sig-paren">(</span><em class="sig-param">func</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.supports_caller" title="Permalink to this definition">¶</a></dt> +<em class="property">function </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">supports_caller</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">func</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.supports_caller" title="Permalink to this definition">¶</a></dt> <dd><p>Apply a caller_stack compatibility decorator to a plain Python function.</p> <p>See the example in <a class="reference internal" href="#namespaces-python-modules"><span class="std std-ref">Namespaces from Regular Python Modules</span></a>.</p> </dd></dl> -<dl class="function"> +<dl class="py function"> <dt id="mako.runtime.capture"> -<code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">capture</code><span class="sig-paren">(</span><em class="sig-param">context</em>, <em class="sig-param">callable_</em>, <em class="sig-param">*args</em>, <em class="sig-param">**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.capture" title="Permalink to this definition">¶</a></dt> +<em class="property">function </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">capture</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">context</span></em>, <em class="sig-param"><span class="n">callable_</span></em>, <em class="sig-param"><span class="o">*</span><span class="n">args</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kwargs</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.capture" title="Permalink to this definition">¶</a></dt> <dd><p>Execute the given template def, capturing the output into a buffer.</p> <p>See the example in <a class="reference internal" href="#namespaces-python-modules"><span class="std std-ref">Namespaces from Regular Python Modules</span></a>.</p> @@ -727,7 +763,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -742,7 +778,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -754,7 +790,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/runtime.html b/third_party/mako/doc/runtime.html index 86905c2..40f2b29 100644 --- a/third_party/mako/doc/runtime.html +++ b/third_party/mako/doc/runtime.html
@@ -12,7 +12,7 @@ The Mako Runtime Environment — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Namespaces" href="namespaces.html" /> <link rel="prev" title="Defs and Blocks" href="defs.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » The Mako Runtime Environment @@ -177,12 +177,12 @@ file-like object such as Python’s <code class="docutils literal notranslate"><span class="pre">StringIO</span></code> or similar, and the other a dictionary of variables that can be freely referenced within a template; this dictionary is a combination -of the arguments sent to the <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> function and +of the arguments sent to the <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> function and some built-in variables provided by Mako’s runtime environment.</p> <div class="section" id="the-buffer"> <h3>The Buffer<a class="headerlink" href="#the-buffer" title="Permalink to this headline">¶</a></h3> <p>The buffer is stored within the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>, and writing -to it is achieved by calling the <a class="reference internal" href="#mako.runtime.Context.write" title="mako.runtime.Context.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a> method +to it is achieved by calling the <a class="reference internal" href="#mako.runtime.Context.write" title="mako.runtime.Context.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Context.write()</span></code></a> method – in a template this looks like <code class="docutils literal notranslate"><span class="pre">context.write('some</span> <span class="pre">string')</span></code>. You usually don’t need to care about this, as all text within a template, as well as all expressions provided by <code class="docutils literal notranslate"><span class="pre">${}</span></code>, automatically send @@ -232,7 +232,7 @@ to the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a>. This will cause any non-present variables to raise an immediate <code class="docutils literal notranslate"><span class="pre">NameError</span></code> which includes the name of the variable in its message -when <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> is called – <code class="docutils literal notranslate"><span class="pre">UNDEFINED</span></code> is not used.</p> +when <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> is called – <code class="docutils literal notranslate"><span class="pre">UNDEFINED</span></code> is not used.</p> <div class="versionadded"> <p><span class="versionmodified added">New in version 0.3.6.</span></p> </div> @@ -260,7 +260,7 @@ </ul> <p>Another facet of the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> is that its dictionary of variables is <strong>immutable</strong>. Whatever is set when -<a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> is called is what stays. Of course, since +<a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> is called is what stays. Of course, since its Python, you can hack around this and change values in the context’s internal dictionary, but this will probably will not work as well as you’d think. The reason for this is that Mako in @@ -456,10 +456,10 @@ to make use of the new system.</p> <p>First, the <code class="docutils literal notranslate"><span class="pre">enable_loop=False</span></code> flag is passed to either the <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> or <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object in use:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s1">'/docs'</span><span class="p">],</span> <span class="n">enable_loop</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s1">'/docs'</span><span class="p">],</span> <span class="n">enable_loop</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span></pre></div> </div> <p>or:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"some template"</span><span class="p">,</span> <span class="n">enable_loop</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"some template"</span><span class="p">,</span> <span class="n">enable_loop</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span></pre></div> </div> <p>An individual template can make usage of the feature when <code class="docutils literal notranslate"><span class="pre">enable_loop</span></code> is set to <code class="docutils literal notranslate"><span class="pre">False</span></code> by switching it back on within the <code class="docutils literal notranslate"><span class="pre"><%page></span></code> tag:</p> @@ -541,29 +541,51 @@ </div> <div class="section" id="api-reference"> <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2> -<dl class="class"> +<table class="longtable docutils"> +<colgroup> +<col style="width: 10%" /> +<col style="width: 90%" /> +</colgroup> +<thead> +<tr class="row-odd"><th class="head">Object Name</th> +<th class="head">Description</th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.Context"><code class="sig-name descname">Context</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.LoopContext"><code class="sig-name descname">LoopContext</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.runtime.Undefined"><code class="sig-name descname">Undefined</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +</tbody> +</table> +<dl class="py class"> <dt id="mako.runtime.Context"> -<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">Context</code><span class="sig-paren">(</span><em class="sig-param">buffer</em>, <em class="sig-param">**data</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">Context</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">buffer</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">data</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>Provides runtime namespace, output buffer, and various callstacks for templates.</p> <p>See <a class="reference internal" href="#"><span class="std std-ref">The Mako Runtime Environment</span></a> for detail on the usage of <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Context.get"> -<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param">key</em>, <em class="sig-param">default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.get" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">key</span></em>, <em class="sig-param"><span class="n">default</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.get" title="Permalink to this definition">¶</a></dt> <dd><p>Return a value from this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Context.keys"> -<code class="sig-name descname">keys</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.keys" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">keys</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.keys" title="Permalink to this definition">¶</a></dt> <dd><p>Return a list of all names established in this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.runtime.Context.kwargs"> -<em class="property">property </em><code class="sig-name descname">kwargs</code><a class="headerlink" href="#mako.runtime.Context.kwargs" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">kwargs</code><a class="headerlink" href="#mako.runtime.Context.kwargs" title="Permalink to this definition">¶</a></dt> <dd><p>Return the dictionary of top level keyword arguments associated with this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> <p>This dictionary only includes the top-level arguments passed to @@ -574,51 +596,51 @@ a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> accepts arguments via its <code class="docutils literal notranslate"><span class="pre"><%page></span></code> tag, which are normally expected to be passed via <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a>, except the template is being called in an inheritance context, -using the <code class="docutils literal notranslate"><span class="pre">body()</span></code> method. <code class="xref py py-attr docutils literal notranslate"><span class="pre">Context.kwargs</span></code> can then be +using the <code class="docutils literal notranslate"><span class="pre">body()</span></code> method. <a class="reference internal" href="#mako.runtime.Context.kwargs" title="mako.runtime.Context.kwargs"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Context.kwargs</span></code></a> can then be used to propagate these arguments to the inheriting template:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>${next.body(**context.kwargs)}</pre></div> </div> </dd></dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.runtime.Context.lookup"> -<em class="property">property </em><code class="sig-name descname">lookup</code><a class="headerlink" href="#mako.runtime.Context.lookup" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">lookup</code><a class="headerlink" href="#mako.runtime.Context.lookup" title="Permalink to this definition">¶</a></dt> <dd><p>Return the <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> associated with this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Context.pop_caller"> -<code class="sig-name descname">pop_caller</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.pop_caller" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">pop_caller</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.pop_caller" title="Permalink to this definition">¶</a></dt> <dd><p>Pop a <code class="docutils literal notranslate"><span class="pre">caller</span></code> callable onto the callstack for this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Context.push_caller"> -<code class="sig-name descname">push_caller</code><span class="sig-paren">(</span><em class="sig-param">caller</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.push_caller" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">push_caller</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">caller</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.push_caller" title="Permalink to this definition">¶</a></dt> <dd><p>Push a <code class="docutils literal notranslate"><span class="pre">caller</span></code> callable onto the callstack for this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Context.write"> -<code class="sig-name descname">write</code><span class="sig-paren">(</span><em class="sig-param">string</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.write" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">write</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">string</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.write" title="Permalink to this definition">¶</a></dt> <dd><p>Write a string to this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> object’s underlying output buffer.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.Context.writer"> -<code class="sig-name descname">writer</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.writer" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.Context"><code class="docutils literal notranslate"><span class="pre">mako.runtime.Context.</span></code></a><code class="sig-name descname">writer</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.Context.writer" title="Permalink to this definition">¶</a></dt> <dd><p>Return the current writer function.</p> </dd></dl> </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.runtime.LoopContext"> -<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">LoopContext</code><span class="sig-paren">(</span><em class="sig-param">iterable</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.LoopContext" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">LoopContext</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">iterable</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.LoopContext" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>A magic loop variable. Automatically accessible in any <code class="docutils literal notranslate"><span class="pre">%</span> <span class="pre">for</span></code> block.</p> @@ -640,15 +662,15 @@ <dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">odd</span></code> -> <cite>bool</cite></dt><dd><p><code class="docutils literal notranslate"><span class="pre">True</span></code> when <code class="docutils literal notranslate"><span class="pre">index</span></code> is odd.</p> </dd> </dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.runtime.LoopContext.cycle"> -<code class="sig-name descname">cycle</code><span class="sig-paren">(</span><em class="sig-param">*values</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.LoopContext.cycle" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.runtime.LoopContext"><code class="docutils literal notranslate"><span class="pre">mako.runtime.LoopContext.</span></code></a><code class="sig-name descname">cycle</code><span class="sig-paren">(</span><em class="sig-param"><span class="o">*</span><span class="n">values</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.runtime.LoopContext.cycle" title="Permalink to this definition">¶</a></dt> <dd><p>Cycle through values as the loop progresses.</p> </dd></dl> </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.runtime.Undefined"> <em class="property">class </em><code class="sig-prename descclassname">mako.runtime.</code><code class="sig-name descname">Undefined</code><a class="headerlink" href="#mako.runtime.Undefined" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> @@ -673,7 +695,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -688,7 +710,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -700,7 +722,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/search.html b/third_party/mako/doc/search.html index 1bc0c60..56ef5d6b 100644 --- a/third_party/mako/doc/search.html +++ b/third_party/mako/doc/search.html
@@ -12,7 +12,7 @@ Search — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="#" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <!-- end layout.mako headers --> @@ -54,7 +54,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -66,7 +66,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -84,7 +84,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Search @@ -120,7 +120,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -138,7 +138,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -150,7 +150,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <script type="text/javascript" src="_static/searchtools.js"></script> <!-- end iterate through sphinx environment script_files --> @@ -158,9 +157,7 @@ <script type="text/javascript" src="_static/init.js"></script> - <script type="text/javascript"> - jQuery(function() { Search.loadIndex("searchindex.js"); }); - </script> + <script type="text/javascript" src="searchindex.js" defer></script> </body> </html>
diff --git a/third_party/mako/doc/searchindex.js b/third_party/mako/doc/searchindex.js index 370fda7..23e99bb 100644 --- a/third_party/mako/doc/searchindex.js +++ b/third_party/mako/doc/searchindex.js
@@ -1 +1 @@ -Search.setIndex({docnames:["caching","changelog","defs","filtering","index","inheritance","namespaces","runtime","syntax","unicode","usage"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:56},filenames:["caching.rst","changelog.rst","defs.rst","filtering.rst","index.rst","inheritance.rst","namespaces.rst","runtime.rst","syntax.rst","unicode.rst","usage.rst"],objects:{"mako.cache":{Cache:[0,0,1,""],CacheImpl:[0,0,1,""],register_plugin:[0,4,1,""]},"mako.cache.Cache":{get:[0,1,1,""],get_or_create:[0,1,1,""],id:[0,3,1,""],impl:[0,3,1,""],invalidate:[0,1,1,""],invalidate_body:[0,1,1,""],invalidate_closure:[0,1,1,""],invalidate_def:[0,1,1,""],put:[0,1,1,""],set:[0,1,1,""],starttime:[0,3,1,""]},"mako.cache.Cache.get.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.Cache.invalidate.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.Cache.set.params":{"**kw":[0,2,1,""],key:[0,2,1,""],value:[0,2,1,""]},"mako.cache.CacheImpl":{get:[0,1,1,""],get_or_create:[0,1,1,""],invalidate:[0,1,1,""],pass_context:[0,3,1,""],set:[0,1,1,""]},"mako.cache.CacheImpl.get.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.CacheImpl.get_or_create.params":{"**kw":[0,2,1,""],creation_function:[0,2,1,""],key:[0,2,1,""]},"mako.cache.CacheImpl.invalidate.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.CacheImpl.set.params":{"**kw":[0,2,1,""],key:[0,2,1,""],value:[0,2,1,""]},"mako.exceptions":{RichTraceback:[10,0,1,""],html_error_template:[10,4,1,""],text_error_template:[10,4,1,""]},"mako.exceptions.RichTraceback":{error:[10,3,1,""],lineno:[10,3,1,""],message:[10,3,1,""],records:[10,3,1,""],reverse_records:[10,3,1,""],reverse_traceback:[10,3,1,""],source:[10,3,1,""]},"mako.ext.beaker_cache":{BeakerCacheImpl:[0,0,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl":{get:[0,1,1,""],get_or_create:[0,1,1,""],invalidate:[0,1,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl.get.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl.get_or_create.params":{"**kw":[0,2,1,""],creation_function:[0,2,1,""],key:[0,2,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl.invalidate.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.lookup":{TemplateCollection:[10,0,1,""],TemplateLookup:[10,0,1,""]},"mako.lookup.TemplateCollection":{adjust_uri:[10,1,1,""],filename_to_uri:[10,1,1,""],get_template:[10,1,1,""],has_template:[10,1,1,""]},"mako.lookup.TemplateCollection.get_template.params":{relativeto:[10,2,1,""],uri:[10,2,1,""]},"mako.lookup.TemplateCollection.has_template.params":{uri:[10,2,1,""]},"mako.lookup.TemplateLookup":{adjust_uri:[10,1,1,""],filename_to_uri:[10,1,1,""],get_template:[10,1,1,""],put_string:[10,1,1,""],put_template:[10,1,1,""]},"mako.lookup.TemplateLookup.params":{collection_size:[10,2,1,""],directories:[10,2,1,""],filesystem_checks:[10,2,1,""],modulename_callable:[10,2,1,""]},"mako.runtime":{Context:[7,0,1,""],LoopContext:[7,0,1,""],ModuleNamespace:[6,0,1,""],Namespace:[6,0,1,""],TemplateNamespace:[6,0,1,""],Undefined:[7,0,1,""],capture:[6,4,1,""],supports_caller:[6,4,1,""]},"mako.runtime.Context":{get:[7,1,1,""],keys:[7,1,1,""],kwargs:[7,1,1,""],lookup:[7,1,1,""],pop_caller:[7,1,1,""],push_caller:[7,1,1,""],write:[7,1,1,""],writer:[7,1,1,""]},"mako.runtime.LoopContext":{cycle:[7,1,1,""]},"mako.runtime.ModuleNamespace":{filename:[6,1,1,""]},"mako.runtime.Namespace":{attr:[6,3,1,""],cache:[6,1,1,""],context:[6,3,1,""],filename:[6,3,1,""],get_cached:[6,1,1,""],get_namespace:[6,1,1,""],get_template:[6,1,1,""],include_file:[6,1,1,""],module:[6,3,1,""],template:[6,3,1,""],uri:[6,3,1,""]},"mako.runtime.TemplateNamespace":{filename:[6,1,1,""],module:[6,1,1,""],uri:[6,1,1,""]},"mako.template":{DefTemplate:[10,0,1,""],Template:[10,0,1,""]},"mako.template.DefTemplate":{get_def:[10,1,1,""]},"mako.template.Template":{code:[10,1,1,""],get_def:[10,1,1,""],list_defs:[10,1,1,""],render:[10,1,1,""],render_context:[10,1,1,""],render_unicode:[10,1,1,""],source:[10,1,1,""]},"mako.template.Template.params":{buffer_filters:[10,2,1,""],bytestring_passthrough:[10,2,1,""],cache_args:[10,2,1,""],cache_dir:[10,2,1,""],cache_enabled:[10,2,1,""],cache_impl:[10,2,1,""],cache_type:[10,2,1,""],cache_url:[10,2,1,""],default_filters:[10,2,1,""],disable_unicode:[10,2,1,""],enable_loop:[10,2,1,""],encoding_errors:[10,2,1,""],error_handler:[10,2,1,""],filename:[10,2,1,""],format_exceptions:[10,2,1,""],future_imports:[10,2,1,""],imports:[10,2,1,""],include_error_handler:[10,2,1,""],input_encoding:[10,2,1,""],lexer_cls:[10,2,1,""],lookup:[10,2,1,""],module_directory:[10,2,1,""],module_filename:[10,2,1,""],module_writer:[10,2,1,""],output_encoding:[10,2,1,""],preprocessor:[10,2,1,""],strict_undefined:[10,2,1,""],text:[10,2,1,""],uri:[10,2,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","parameter","Python parameter"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"]},objtypes:{"0":"py:class","1":"py:method","2":"py:parameter","3":"py:attribute","4":"py:function"},terms:{"2to3":1,"5b1":1,"abstract":10,"boolean":10,"break":1,"byte":[1,9,10],"case":[0,1,2,3,5,6,7,8,9,10],"catch":1,"class":[0,1,2,5,6,7,9,10],"default":[0,1,2,3,5,6,7,8,9,10],"dr\u00f4le":9,"export":[2,5,8],"f\u00e9rotin":1,"final":[1,3,5,9],"function":[0,1,2,3,5,6,7,8,9,10],"import":[0,1,2,3,6,7,8,9,10],"int":7,"long":[1,7,8],"new":[0,1,2,3,5,7,8,10],"pla\u00eet":9,"r\u00e9veill\u00e9":9,"return":[0,1,2,3,6,7,8,9,10],"short":0,"static":[4,5],"super":[0,5,6,9],"switch":7,"throw":[0,7],"true":[0,1,2,3,6,7,8,10],"try":[1,3,7,8,9,10],"var":1,"while":[1,2,3,5,8,10],Added:[1,10],And:5,But:[2,4,6,10],For:[0,1,2,3,5,6,7,9,10],Its:2,One:[0,3,5,7,10],Such:[0,2,3,5],That:[1,5,9],The:[0,1,2,4,5,10],Then:2,There:[0,2,6,9],These:[0,6,8,10],Use:[5,8,10],Using:[1,4,6,7,8],Will:1,With:[0,2,7,10],__builtin__:1,__builtins__:1,__class__:[1,10],__file__:6,__future__:[1,10],__getattr__:1,__html__:1,__init__:0,__len__:7,__m_:1,__m_local:9,__name__:[0,1,10],__nonzero__:1,__str:9,__str__:7,__version__:1,_cach:0,_data:1,_my_cache_work:0,_pop_buff:1,_pop_fram:1,_push_buff:1,_push_fram:1,abil:[0,6,8,9,10],abl:7,about:[1,4,7,8,10],abov:[0,2,3,5,6,7,8,9,10],absolut:[1,2,9],accept:[0,1,3,6,7,8,9,10],access:[1,2,4,5,6,7,8,10],accessor:[0,1,5,6],accommod:1,accompani:10,accomplish:[0,8,10],accord:1,accordingli:10,account:[2,3],accountdata:2,accountnam:2,accumul:8,achiev:[2,5,7],acquir:[0,9],across:[0,7],act:[7,10],actual:[0,1,2,3,5,6,7,8,10],add:[2,3,5,10],added:[1,3,5,8],adding:3,addit:[0,1,2,3,5,6,8,10],addition:[1,5,9,10],address:[0,10],adjust:[1,6,8,10],adjust_uri:10,advanc:10,advantag:[5,6,9,10],affect:[1,7],afford:[1,10],after:[0,1,3,6,7,10],again:[2,7],against:[1,8,10],agre:5,akkerman:1,algorithm:1,all:[0,1,2,3,4,5,6,8,9,10],allow:[0,1,2,3,5,6,7,8,9,10],almost:[5,8],alon:1,along:[0,5,6],alor:9,alpha:1,alreadi:[1,5,7,10],also:[0,1,2,3,5,6,7,8,9,10],altern:[1,7,9,10],although:8,altogeth:1,alwai:[1,2,5,7,9],ani:[0,1,2,3,5,6,7,8,9,10],anonym:[0,1,2,8],anoth:[1,2,5,6,7,8,9,10],answer:1,anyth:[2,5,9],anywai:[1,10],anywher:[2,6,8],api:[1,3,4],appar:[1,3,6],appear:[1,3,7,8,10],append:10,appli:[1,2,3,6,7,8,9,10],applic:[1,3,7,8,10],approach:[5,7,9],appropri:1,approxim:10,apr:1,aptli:10,arbitrari:[0,8],arbitrarili:[1,2],area:[2,5,7,8,9],aren:[1,2,9],arg1:6,arg2:6,arg3:6,arg4:6,arg:[0,1,2,3,6,8,10],argpars:1,arguabl:9,argument:[1,4,6,7,8,9,10],around:[1,3,7,10],arrai:3,arrang:8,ascii:[1,9],ask:7,aspect:[8,9],assign:[1,2,7,8,10],associ:[0,1,7],assum:[9,10],ast:[1,9],atom:10,attach:6,attempt:[0,1,9],attr:[1,5],attribut:[0,1,2,3,4,6,7,8,10],attributeerror:1,aug:1,augment:[2,4],author:7,automat:[0,2,3,5,7,8,10],avail:[0,1,2,3,5,6,7,8,9,10],avoid:1,awai:5,awar:[1,7,9,10],babel:1,babelplugin:10,back:[1,5,7,9,10],backend:[1,6],background:9,backslash:[1,8],backward:[0,1],bar:[1,2,3,6,7,8,10],bare:1,base:[0,1,3,4,5,6,7,8],basemost:5,basestr:1,basi:[0,5,7],basic:[1,2,4,6,8,9],batch:3,batcheld:1,beaker:[1,10],beaker_cach:0,beakercacheimpl:0,bean:10,becam:1,becaus:[1,2,3,5,9],becom:[1,6,9,10],been:[0,1,3,6,9,10],befor:[0,1,3,5,6,8,9,10],began:7,begin:10,behav:2,behavior:[1,3,5,7,10],being:[0,1,2,5,7,8,9,10],bell:9,below:[1,2,5,9],ben:1,benchmark:1,best:8,better:[0,1,7],between:[1,2,5,6,7],beyond:[0,2],binari:9,bit:[1,2,7,10],bitwis:1,black:[1,7],blank:[1,7],block:[0,1,4,7],blunt:0,board:7,bodi:[0,1,2,4,5,7,8,10],bold:3,bom:1,bool:7,bot:7,both:[1,2,3,5,7,9,10],bottom:1,bottommost:5,bound:1,bracket:1,breakag:1,breakdown:5,brief:10,broke:1,broken:1,buf:[3,10],buffer:[1,4,6,8,10],buffer_filt:[1,10],buffet:1,bug:1,bugfix:1,build:[2,5,6],builder:1,buildtabl:2,built:[1,2,3,4,5,8,9,10],builtin:[1,9],bump:1,bunch:6,burden:9,bye:2,bytestr:[1,10],bytestring_passthrough:[1,10],cach:[1,2,3,4,6,7,8,10],cache_:[0,1],cache_arg:[0,1,10],cache_dir:[0,1,10],cache_en:[0,1,10],cache_impl:[0,1,10],cache_kei:[0,1],cache_region:0,cache_timeout:[0,1,2],cache_typ:[0,1,8,10],cache_url:[0,1,10],cache_xyz:0,cacheabl:1,cacheimpl:[0,1,10],cachemanag:[0,1],calcul:10,call:[0,1,3,4,5,7,9,10],call_my_object:9,callabl:[0,1,2,3,6,7,8,10],callable_:[6,10],caller:[1,2,3,6,7],caller_stack:[1,6,9],calling_uri:6,callstack:7,came:1,camp:1,can:[0,1,2,3,5,6,7,8,9,10],cannot:[1,2,9,10],cant:1,capabl:[0,1,10],captur:[1,3,6,7,10],care:[0,6,7,9],catalog:10,categori:6,caught:10,caus:[1,3,6,7,10],cazabon:1,central:[2,3,7,8],certain:[1,3,6,9,10],cfg:[1,10],cgi:[1,3,9],chain:[1,5,6,7,8],chang:[0,1,5,7,9],changelog:4,chapter:[2,3,4,5,10],charact:[1,8,9,10],characterist:8,charl:1,check:[1,5,7,8,9],checker:7,cheetah:9,chevalli:1,child:5,choos:9,chosen:0,clarifi:1,class_:5,classic:[6,8],clean:[0,1,10],cleaner:7,close:[1,2,6,8,10],closur:2,cmd:1,cmdline:1,code:[1,2,3,6,7,8,9,10],codebas:1,codec:[9,10],codegen:1,codi:1,coerc:9,col:2,collect:[0,1,6,7,9],collection_s:10,collis:1,colomiet:1,colon:[0,8],column:2,combin:[1,7],come:[0,2,5,8,9,10],comma:[2,3,10],command:[1,10],comment:[1,4,9,10],common:[1,4,5,6,9],commonli:[0,5,9],commun:[2,7],comp1:6,comp2:6,comp:6,compar:[9,10],compat:[0,1,6,10],compil:[0,1,7,8,10],compileexcept:1,complet:[1,5,6,10],complex:1,compliant:9,compon:[0,6,7],comprehens:1,concaten:[3,10],conceiv:7,concept:[2,8,10],condit:[1,2,5,8],condition:[1,6],configur:[0,1,5,6,10],conflict:0,conform:1,confus:[5,9],conjunct:[1,5,10],consid:[1,7,10],consist:8,consol:9,conson:7,constant:[1,7],construct:[0,1,2,5,6,8,9,10],constructor:1,consum:[0,1,8],contain:[0,1,2,6,8,9,10],content:[0,1,3,6,7,8,10],context:[0,1,2,3,4,5,6,9,10],contextu:2,contigu:8,continu:[1,8,9,10],contrast:[2,5,9],contrib:1,contribut:1,contriv:10,control:[1,2,3,4,5,7,10],convei:10,conveni:0,convent:[2,6],convers:[1,9],convert:[0,1,9,10],convert_com:1,copi:[1,6,7],core:1,correct:[1,6],correctli:[1,7],correspond:[0,5,6,7,10],corrupt:1,could:[1,5],couldn:1,count:[2,7,10],coupl:1,cours:[1,7],courtesi:1,cover:1,coverag:1,creat:[0,1,2,6,7,8,9,10],creation:[0,1,2,3,10],creation_funct:0,critic:1,crlf:1,cross:1,css:[1,6,10],cstringio:[1,9,10],ctx:10,current:[1,2,5,6,7,8,10],current_sect:8,custom:[1,2,3,5,6,8,9,10],dairiki:1,daniel:1,data:[0,1,2,3,6,7,9,10],databas:2,date:1,daverio:1,dbm:0,deal:[7,8,9],dealt:10,dec:1,decid:[7,8],decis:[5,7,9],declar:[1,2,3,4,5,8,10],decod:[1,3,9],decor:[1,4,6],decreas:6,deepli:2,def:[0,1,4,7,9,10],default_filt:[1,9,10],defin:[1,2,3,4,5,6,7,8,10],definit:[2,3,5,6],defnam:[1,2],deftempl:[2,10],delai:1,deliv:[1,3,6],delta:6,demarc:2,denot:8,depend:[1,4,8,10],deploy:1,deprec:[1,10],depth:7,derek:1,deriv:[0,1,3,9],describ:[1,2,3,5,6,7,8,9,10],descript:10,descriptor:1,design:3,desir:[1,6,9,10],despit:1,dessin:9,dest:10,destin:10,detail:[2,5,7,8,9,10],detect:1,determin:[0,1,9],determinist:3,develop:9,dict:[1,9],dictionari:[0,1,6,7,10],did:[1,5],differ:[0,1,2,5,6,7,10],differenti:7,dir:[0,1,10],direct:[0,2,6,8,10],directli:[0,1,2,3,6,8,10],directori:[0,1,3,7,9,10],dirnam:10,disabl:[0,1,3,4,7,10],disable_unicod:[1,3,10],disait:9,disallow:1,discard:3,discuss:1,disgard:9,displai:[1,10],disregard:10,distinct:[1,10],distinctli:5,distribut:10,distutil:10,div:[2,5,6,10],divis:10,do_something_speci:0,doc:[1,2,7,9,10],document:[0,1,5,8,9,10],doe:[1,2,5,6,7,8,9],doesn:[1,2,5,6,7],doing:[3,9],don:[0,1,2,5,7,9],done:[9,10],dot:1,doubli:1,down:[0,1,9],dragon:1,draw:3,drive:1,drop:[1,8],due:1,dumb:9,dump:[3,6,9],dure:[1,5,10],dyn:6,dynam:[1,5,8],each:[0,1,2,5,6,7,8,9,10],earli:[1,4],earlier:[0,9],eas:[3,7],easi:[3,7],easier:0,edgewal:1,eeve:1,effect:[0,1,2,3,6,10],egg:7,either:[0,1,5,7,8,9,10],elabor:1,elem:8,element:[1,2,5,7,8,9,10],elif:8,elimin:9,ell:9,els:[0,1,7,8,10],emac:1,email:8,emb:[6,8,9],embed:[1,6,7,8,10],emit:[1,8],empti:[1,3,8,9],enabl:[0,1,7,8,10],enable_loop:[1,7,10],enclos:[1,2,7],encod:[1,3,4],encoding_error:[1,9,10],encount:[1,5],end:[1,3,5,8],endfor:[2,6,7,8],endif:[1,2,6,7,8],endless:1,endwith:1,enforc:1,enorm:2,ensur:[0,1,6,9],entir:[2,3,4,5,6,8,10],entiti:[1,3],entri:[0,1,10],entrypoint:[0,1],enumer:7,environ:[1,3,4,8,10],epoch:0,equival:[0,2,3,6,8,9],eric:1,errant:1,error:[1,2,7,9,10],error_handl:[1,10],escap:[1,2,3,4,9],essenti:[0,6,9],establish:[1,7,10],etc:[0,1,2,6,7,8,10],eval:1,evalu:[1,2,6,8],evaul:1,even:[1,5,7,8,9],ever:[6,9],everi:[1,6,8],everyon:7,everyth:[1,7],exactli:[2,5],examin:6,exampl:[0,1,2,3,4,5,7,8,10],exc:1,exc_info:[1,10],exceed:7,except:[0,1,2,3,4,6,7,8],excerpt:10,exclus:10,exec:1,execut:[0,1,2,3,5,6,7,8,10],exist:[0,1,2,6,7,8,9,10],exit:[1,4],expand:1,expect:[1,2,5,7,8,9],experienc:7,expir:[0,1],expiri:1,explcitli:1,explicit:[0,1,2,6,7,8,9],explicitli:[1,5,6,7,9,10],expr:[1,2,6],express:[1,2,4,5,6,7,10],expression_filt:[1,3],ext:[0,1,10],extens:1,extern:[0,2,5],extra:[1,5,8],extract:[1,10],extractor:[1,10],facad:0,facet:7,facil:5,fact:[2,5,9],fail:1,failur:7,fake:8,fall:0,fals:[0,1,7,10],familiar:[2,8],far:[1,5,8,9,10],fashion:0,fast:10,fastencodingbuff:[1,9],faster:[1,9],featur:[0,1,5,7,8,10],feb:1,few:[1,7],field:10,file:[0,1,4,5,6,7,8],filehandl:[1,9],filenam:[0,1,6,10],filename_to_uri:10,filesystem:[0,1,6],filesystem_check:10,filter:[1,2,4,7,9,10],find:[7,8,10],finish:5,first:[0,1,3,5,6,7,8,9,10],five:[0,8],fix:[0,1,6,10],flag:[0,1,3,6,7,8,9,10],flexibl:[3,5,8],flip:2,flow:8,fly:9,follow:[1,2,5,6,7,8,10],foo:[1,2,3,6,7,8,9,10],footer:[5,8],forc:[1,10],form:[1,2,6,8],format:[1,2,3,6,8,9,10],format_except:[1,10],formatt:1,former:1,forward:1,found:[1,2,7,8],four:[6,8],fragment:1,frame:1,framework:4,francoi:10,free:[1,6],freeli:7,fri:1,frobnizzl:8,from:[0,1,3,4,5,7,9,10],frozenset:1,full:[1,8,10],fulli:[1,3,5,10],func:6,further:[1,8],futur:[6,8],future_import:[1,10],futures_import:10,fyi:1,gae:1,gagern:1,game:9,garbag:0,gather:9,gave:10,geisler:1,gener:[0,1,2,3,5,6,7,8,9,10],genshi:8,georg:1,get:[0,1,3,5,6,7,8,9,10],get_cach:6,get_def:[1,2,3,10],get_namespac:[1,6],get_or_cr:[0,1],get_resourc:8,get_templ:[0,6,9,10],getargspec:1,getattr:6,getdefaultencod:1,gettext:[1,10],getvalu:[3,10],github:1,give:[2,6],given:[0,1,2,3,5,6,7,10],global:[0,2,5,6,7],glyph:1,goal:[1,3],goe:8,going:[1,9],good:[0,1,8],got:1,graphic:9,great:[6,9],grei:5,group:[0,1,6],guess:[1,9],guest:1,guid:10,hack:[1,7],had:[1,9],hadn:1,haltner:1,ham:7,hand:5,handi:6,handl:[0,1,2,4,7,8],handler:[1,10],happen:[6,7,9],hard:[5,7,8,9],harland:1,has:[0,1,2,3,5,6,7,8,9,10],has_templ:10,hasattr:6,hash:1,hasn:1,have:[0,1,2,3,5,6,7,8,9,10],head:[2,5,6,10],header:[0,1,2,5,8,10],heavili:9,heck:[4,10],hello:[2,6,8,9,10],help:[0,1,9,10],helper:10,her:9,here:[0,1,3,5,6,7,8,9,10],highlight:[1,10],his:9,hit:[3,9],hold:6,home:1,honor:1,hopefulli:1,how:[1,2,6,7,8,10],howev:[1,2,5,6,9],href:[2,6],htdoc:10,html:[0,1,2,3,5,6,8,9,10],html_error_templ:[1,10],html_escap:1,htmlentitydef:3,htmlentityreplac:[1,10],http:1,huayi:1,hugo:1,hypothet:5,idea:[1,5,8],ideal:1,ident:[1,6,10],identifi:[0,1,8,10],ignor:[7,8],illus:9,illustr:[3,5,10],imag:[9,10],imaginez:9,imankulov:1,immedi:[1,5,7,8,9,10],immut:7,impl:0,implement:[0,1,2,5,10],impli:10,implic:9,implicit:[0,7],implicitli:1,improv:[1,8,9,10],incl:6,includ:[0,1,2,3,4,6,7,10],include_error_handl:[1,10],include_fil:[1,6],incom:9,incompat:1,incorrect:1,increas:10,indent:[1,8],index:[1,4,5,6,7,8,10],indic:[0,1,7,8],individu:[0,1,2,7,10],info:[1,10],inform:[1,6,8,9,10],inher:3,inherit:[0,1,2,4,7,10],initi:[1,2],inject:10,inlin:[1,5,7,8],inner:[1,2],input:[1,2,3,9],input_encod:[1,9,10],insensit:1,insert:[5,10],insid:[0,1,2,5,6,8,10],inspect:1,inspir:8,instal:[0,1],install_requir:1,instanc:[6,7,8,10],instead:[1,2,3,5,6,9,10],insur:1,integ:[0,2,9],integr:[0,1,4,5],intellig:9,intend:[1,3,6],intent:3,interact:[5,6,9],interchang:5,interest:10,interfac:0,intermedi:5,intermix:5,intern:[0,1,3,7,9,10],interpret:[1,2,9,10],interven:1,intric:1,intro:2,introduc:[2,5,6,7,8],invalid:[0,1],invalidate_bodi:[0,1],invalidate_closur:[0,1],invalidate_def:[0,1],invoc:5,invok:[2,5,8,10],involv:[1,5],ioerror:1,iou:7,isn:[1,7],issu:[1,2,9,10],item:[2,7,8],iter:[2,6],its:[0,1,2,3,5,6,7,8,9,10],itself:[0,1,2,3,5,6,7,8,9,10],jack:10,jan:1,javascript:6,jeff:1,jinja2:[1,2,8],jinja:1,jit:7,job:3,joe:8,john:2,join:9,jonathan:1,jot:7,jour:9,json:[1,3],jsp:8,jul:1,jun:1,just:[1,2,3,5,6,7,8,9,10],jut:7,jython:1,keep:2,kei:[0,1,5,6,7,9,10],keyerror:7,keyword:[1,2,5,6,7,8,9,10],kind:[0,3,5,6,7,8,9,10],know:[5,9],known:[1,2,6],kwarg:[0,1,6,7,10],lack:1,lacsap:1,lai:2,lambda:1,languag:[2,8,9],larg:[1,5],last:[1,7,10],last_modifi:1,later:[0,8],latest:1,latter:[1,9],laurent:1,layout:[1,2,5,6,10],layoutdata:2,lead:[1,3,6,7],learn:9,least:[6,10],left:[3,10],leftmost:3,legaci:[1,10],legacy_html_escap:1,legendari:1,len:8,less:[1,5,7,9],let:[1,2,5,7,10],level:[0,1,2,3,4,5,6,7,9,10],lever:9,leverag:8,lex:1,lexer:[1,8,9,10],lexer_cl:[1,10],lib:1,librari:[0,2,3,6,9,10],lieu:10,lift:5,lighter:1,like:[0,1,2,3,5,6,7,8,9,10],line:[1,5,8,9,10],lineno:10,lingua:1,link:[6,10],linkag:5,list:[0,1,2,3,5,7,8,9,10],list_def:[1,10],lister:2,liter:[1,3,6,9,10],littl:[1,2,7,10],live:0,load:[1,6,8,10],load_templ:1,loader:1,local:[0,1,2,3,7,8,10],locals_:1,locat:[1,6,7,9,10],lock:0,logic:[1,3],long_term:0,longer:1,look:[0,1,2,5,6,7,9,10],lookup:[0,1,7,9,10],loop:[1,2,4,10],loopcontext:7,lopez:1,lost:1,lot:[1,8],lower:1,made:[0,1,7],magamedov:1,magic:[1,7,9],mai:[0,1,3,6,7,8,9,10],main:[1,2,3,5,6,7,9,10],mainlayout:[2,5],mainli:[1,6],maintain:[0,1,10],major:[1,7,9],mak:1,make:[0,1,2,3,5,6,7,8,9,10],mako:[0,1,2,3,4,5,6,8,9,10],mako_cach:0,mako_modul:10,manag:[0,1,7],manfr:1,mani:[1,7,8],manner:3,manual:10,map:[1,10],mar:1,markedli:9,marker:[1,8],markupsaf:[1,3,9],martin:1,matter:5,maxim:[0,9],maximum:1,mayb:5,mean:[0,1,2,3,5,6,7,8,9,10],meant:5,mechan:[0,5,8],member:[7,8,10],memcach:[0,1],memori:[0,1,8,10],mention:9,merg:1,mess:1,messag:[1,7,10],met:2,metadata:[1,8],metaphor:5,method:[0,1,2,3,4,5,8,9,10],middl:[3,5,8],might:[5,6,7,8],migrat:[1,10],mimic:10,mini:7,minim:0,minor:10,minu:[0,1],minut:0,mirror:10,mis:1,miss:[1,3,7,10],mistak:5,mix:1,mkstemp:10,mode:[1,9],model:2,moder:10,modern:[0,1],modifi:[1,2,5,9,10],modul:[0,1,2,3,4,5,7,9,10],module_directori:[0,1,10],module_filenam:[1,10],module_writ:[1,10],modulenam:0,modulename_cal:[1,10],modulenamespac:6,modulepath:0,moduletempl:1,moi:9,moment:10,mon:1,monkeypatch:1,more:[0,1,2,3,5,6,7,8,9,10],most:[0,1,2,5,6,7,8,9,10],mostli:[0,1,6,7,10],mouton:9,move:10,msgid:10,msgstr:10,much:[1,2,5,8,9],multi:1,multibyt:[1,10],multilin:[1,8],multipl:[0,1,2,4,9],multithread:0,must:[0,1,2,5,6,9,10],mutual:10,my_tag:6,mycomp:0,mydef:2,myescap:3,myexpress:3,myfil:8,myfilt:[1,3],myfunc:8,myghti:9,myghtyutil:1,mylib:8,mylookup:[9,10],myn:1,mynamespac:[6,8],mypackag:3,myproj:10,mystuff:2,mystyl:6,mytag:6,mytempl:[0,1,9,10],mytmpl:10,name:[0,1,3,4,8,9,10],nameerror:[1,7,10],namespac:[0,1,2,3,4,7,10],namespace_nam:6,namespacenam:[1,2,8],nari:9,nativ:9,natur:3,necessarili:7,ned:1,need:[0,1,2,5,6,7,9,10],neither:0,nest:[0,1,2,3,4,7],nestabl:2,never:1,newer:[2,10],newli:0,newlin:[1,4],next:[0,2,3,4,6,7,8,9,10],nightmar:9,ninja:5,node:1,non:[1,7,8,9,10],none:[0,1,3,6,7,8,10],normal:[1,2,3,7,8,9,10],nose:1,note:[0,1,2,3,5,6,7,9,10],noth:5,notic:2,notimplementederror:10,notion:7,nov:1,now:[1,3,5,7,8,9],number:[0,1,2,3,7,8,10],numer:[3,8],nutshel:5,object:[0,1,2,3,5,6,7,8,9,10],objnam:0,observ:1,obsolet:1,obvious:5,occlud:1,occur:[0,1,2,10],oct:1,odd:[1,7],off:[0,1,2,5,6],offer:[8,9],often:[5,6],old:[1,7],older:[2,4,8],omit:1,onc:[2,5,7,8],one:[0,1,2,3,5,6,7,8,9,10],ongo:1,onli:[0,1,2,3,5,7,8,9,10],onto:[7,8],open:[5,8,9],oper:[1,2,3,6,7,8,9,10],opposit:5,opt:[0,1,10],optim:1,option:[0,1,6,7,8,9,10],optpars:1,order:[0,1,5,8,9,10],ordinari:6,org:1,organ:[5,6],orient:[2,5],origin:[0,1,3,6,7,9,10],other:[0,1,3,5,6,7,8,9,10],otherwis:[1,7,8,9,10],our:[0,1,2,5,10],out:[0,1,2,5,8,9,10],outer:2,output:[1,2,3,4,5,6,7,8,10],output_encod:[1,9,10],outputpath:10,outsid:[1,2,5,6,7,9],outward:10,over:[1,3,6,7],overhead:[1,9],overrid:[0,1,5,6,7,9,10],overridden:[0,2,5,6],overrod:5,overwritten:0,own:[0,1,2,3,5,6,7,8,9,10],pack:1,packag:[0,1,8],page:[0,1,3,4,5,6,7,10],pagearg:[1,2,6,7,9],pagecontrol:2,paradigm:5,param:8,paramet:[0,1,6,9,10],parent:[0,1,2,4,6,10],parenthes:1,pariti:7,pars:[1,8,9,10],parseabl:1,part:[0,1,5,6,7],parti:0,partial:[1,5],particip:5,particular:[0,1,5,6,7,10],particularli:[1,6],pass:[0,1,2,5,6,7,8,9,10],pass_context:[0,1],passthru:1,patch:1,path:[0,1,6,10],pathnam:1,pattern:10,paul:1,pbj:7,penalti:1,peopl:1,pep:[1,9],per:[0,1,5,7,8,9],percent:[1,8],percentag:10,perform:[1,3,6,9,10],perhap:[2,7,8],perl:8,perm:1,perman:1,permiss:[1,10],persist:[0,1],petit:9,phase:10,philosophi:7,picki:9,pinard:10,pipe:[1,3],pit:7,pkg_resourc:[0,1],place:[0,1,2,5,8,10],plai:[6,9],plain:[1,2,6,8,9,10],platform:10,pleas:8,plu:[1,10],plug:0,plugin:[1,4],point:[0,1,2,5,6,8,9,10],polymorph:8,pop:[0,3,7],pop_buff:3,pop_cal:7,pop_fram:9,popul:0,popular:10,populate_self:6,portabl:2,portion:[1,2],posit:6,possibl:[0,2,3,7],post:[2,10],post_pros:2,pot:7,potenti:5,pow:8,power:8,practic:[1,5],pre:[1,10],preambl:10,preced:[5,6,8,9,10],precompil:1,predefin:1,prefer:[1,9],prefix:[0,1,7],prep:7,prepend:1,preprocessor:[1,10],presenc:1,present:[0,1,2,5,6,7,9,10],preserv:1,pretti:[8,9],prevent:[1,8],previou:[1,2,5,6,7,10],previous:[1,6,10],primari:10,primarili:7,print:[1,2,9,10],printabl:9,prior:[3,7,9],privat:1,probabl:[0,1,2,7,10],procedur:0,process:[0,1,5,8,9],produc:[1,2,3,4,6,7,8,9,10],product:10,program:[8,9],programat:10,programm:9,programmat:[1,3,4,6,7,9],progress:7,project:[1,10],propag:[1,7,8,10],proper:10,properli:[1,9],properti:[1,6,7,10],propig:1,provid:[0,1,2,3,5,6,7,8,10],proxi:6,prune:1,pull:[1,2,6,7,10],pullreq:1,pure:[1,6,8,9],purpos:[1,7,8,9,10],push:7,push_buff:3,push_cal:7,push_fram:9,put:[0,1,5,6,7],put_str:10,put_templ:10,py2:1,py2k:1,py3k:1,pybabel:10,pygment:1,pygmentplugin:10,pylon:[1,10],pypars:1,pyramid:1,pythagorean:8,python3:1,python:[1,2,3,4,5,7,9,10],quand:9,quick:[1,2,8],quickli:9,quot:[1,9],quote_plu:3,rais:[1,2,7,9,10],rang:[1,2,8],rather:[1,7],raw:[1,9,10],reach:[7,10],read:[7,8,9],readm:1,real:[1,8,10],realli:[1,9],ream:9,reason:[1,7,9],recal:5,receiv:[1,2,3,6,8],recent:[1,10],recogn:[5,6],recommend:[1,6],recompil:[0,1,10],record:[6,8,10],recurs:1,red:7,reduc:3,reduct:1,refactor:1,refer:[1,2,3,4,5,8,9],referenc:[1,2,5,6,7],reformat:1,refresh:1,regard:[1,9],regardless:[1,2,5,7],regener:[1,10],regexp:1,region:[0,1],regist:[0,1],register_plugin:[0,1],regress:1,regular:[1,2,3,4,5,8,9,10],rel:[1,6,10],relat:[0,1,9,10],relationship:6,relativeto:10,releas:[0,1,6,8],reli:1,reload:10,remain:[1,2,7],remot:[2,6],remov:[1,6,9],render:[0,1,2,3,4,6,7,8,9,10],render_:7,render_bodi:[3,7,9,10],render_context:10,render_mydef:7,render_unicod:[1,9,10],reopen:1,repair:1,replac:[0,1,3,9,10],report:[1,10],repres:[0,1,2,7,8,9,10],represent:[1,8,10],request:[0,1,6,7,10],requir:[0,1,2,3,6,8,9],requset:1,reserv:1,reserved_nam:1,reset:1,resolut:[5,6,10],resolv:[1,10],resourc:[1,5,10],respect:8,respons:[0,5,6,7],rest:[0,5,8],restrict:[1,2,5],result:[1,2,3,5,7,8,10],retriev:[0,1],revers:10,reverse_index:7,reverse_record:10,reverse_traceback:10,revis:10,rework:1,rewrot:1,richtraceback:[1,10],right:[1,2,3,7,8,9],role:6,roman:1,root:[1,10],roughli:8,routin:10,row:2,rudiment:[0,10],rule:[1,2,5],run:[1,5,6,7,9,10],run_wsgi:[1,10],runner:[1,10],runtim:[0,1,3,4,5,6,8,10],runtimeerror:1,safe:[7,9],sai:[1,2,4,5,7,10],sake:3,same:[0,1,2,5,6,7,8,9,10],sampl:10,sane:2,sat:1,scaffold:6,scalar:[1,6],scenario:[1,2,5,6,7,10],scheme:[1,2,6,7,9,10],scope:[0,1,2,5,6,7,8],scott:1,script:[1,6],search:[4,10],second:[0,2,3],section:[0,1,2,5,6,7,8,10],sectiona:5,secur:1,see:[0,1,2,6,7,8,9,10],seem:1,segment:9,select:5,selector:1,self:[0,1,2,5,7,8,10],semant:[1,2,5,8],semi:0,send:[1,3,5,6,7,9,10],sens:7,sent:[1,3,6,7,8],sep:1,separ:[0,1,2,3,5,10],sequenc:1,seri:[0,1,9,10],serious:5,serv:[8,9,10],serve_templ:10,server:[0,8,10],servic:[0,8,9],set:[0,1,3,6,7,8,9],setup:[0,1,5,10],setuptool:[0,1,10],sever:[1,6],shall:5,share:[1,2,7],sharp:2,shell:1,shop:7,short_term:0,should:[0,1,6,7,10],shouldn:7,shown:1,shutil:10,side:[1,2,3,8],sidebar:2,sign:[1,8],signatur:[1,2,6],signific:[7,8],silent:[1,7],similar:[2,3,5,6,7,8,9,10],similarli:[2,9],simpl:[0,2,7,8,10],simplecacheimpl:0,simpler:1,simplest:8,simpli:[3,5],simplic:3,simplifi:1,sinc:[1,2,5,6,7,9,10],singl:[0,1,2,3,5,8,9,10],singleton:7,skip:[1,10],slain:1,slash:[1,6,8],slight:1,slightli:[6,9],slim:0,slowdown:1,slower:9,small:[1,10],smoothli:5,some:[0,1,2,3,5,6,7,8,9,10],some_cal:1,some_condit:2,some_namespac:6,some_other_directori:1,some_tag:1,some_templ:[1,10],somedata:2,somedef:[0,1,2,3,6,8],someencod:1,somefil:[1,6],somefunct:6,somekei:[0,1],somemodul:1,someobject:6,sometempl:0,someth:[2,3,9],sometim:[1,5,8],somev:[6,7],somevalu:0,somewhat:[2,3],somewher:[7,9,10],sophist:5,sound:[5,8],sourc:[1,5,8,9,10],space:[0,1,2,8],spam:7,span:[2,5],special:[0,1,3,7,8,10],specif:[1,2,3,5,7,8,10],specifi:[0,1,3,4,5,7,10],speed:[1,3,9],speedup:1,sphinx:1,src:6,stack:[1,3,7,10],stacktrac:1,stage:10,stai:[0,7],stale:1,standalon:[1,10],standard:[0,1,9],start:[0,2],starttim:0,startup:1,state:[1,2,5,7,9],statement:[1,2,8,10],stdout:[1,10],step:[1,2,9,10],stick:[1,2,7,8,9],still:[1,2,5,9],stop:[7,8],stop_rend:[1,8],storag:[1,9],store:[0,1,3,7,9,10],str:[1,3,7,9,10],straight:[1,9,10],strategi:0,stream:[1,6,7,8,9,10],streamlin:5,strict:10,strict_undefin:[1,7,10],strictli:[1,9],string:[0,1,3,6,7,8,9,10],stringifi:1,stringio:[1,7,9,10],strip:[1,3],stripe:7,structur:[1,4,5,7],stuff:[6,8],style:[1,2,9],stylesheet:[6,10],sub:[2,8],subclass:[0,2,10],subcompon:2,subdef:2,subdirectori:1,subject:1,subsequ:0,substitut:[3,4,7,10],succe:1,success:10,suggest:1,suit:[1,5],summari:8,sun:1,supersed:[0,1],suppli:[1,6,8],support:[0,1,2,6,8,9,10],supports_cal:[1,6],suppos:[0,2],suppress:3,sure:[1,8],surpris:9,surround:[1,8],suspend:8,svn:1,swap:0,symbol:[1,8],synchron:1,synonym:[0,1,6],syntact:8,syntax:[1,2,3,4,10],sys:[1,10],system:[0,1,2,5,7,10],tabl:[1,2,7],tack:6,tag:[0,1,2,3,4,5,6,7,10],tagfilt:3,tailor:2,take:[1,2,3,5,6,8,9],taken:[0,1,6,10],target:[1,2,3],task:0,taylor:1,techniqu:7,techspot:1,tell:8,tempfil:[1,10],templat:[0,1,2,3,4,6],templatecollect:10,templatelookup:[0,1,3,4,6,7,9],templatelookupexcept:10,templatenam:10,templatenamespac:6,templatetext:[3,9],templateuri:6,temporari:1,temporarili:1,term:0,test:1,text:[0,1,2,3,6,7,9,10],text_error_templ:[1,10],textmat:1,textual:[3,5,10],tgplugin:1,than:[0,1,3,5,7,8,9],thank:1,thei:[1,2,3,5,7,8,9,10],them:[1,2,3,5,6,7,10],themselv:[0,2,5,6,7,8],theorem:8,therebi:6,therefor:[5,6,8,10],thereof:1,thi:[0,1,2,3,5,6,7,8,9,10],thing:[1,2,5,7,8,9],think:7,third:0,those:[0,1,2,6,7,8,10],though:[0,1,5,7,9],thread:0,threadsaf:0,three:[7,8],through:[1,6,7,9,10],throughout:[1,6,8],thrown:[0,10],thu:[1,10],time:[0,1,2,3,4,6,10],timeout:[0,1],timestamp:0,tinker:1,titl:[2,5,8],tmbundl:1,tmp:[3,10],togeth:[5,6],token:1,too:[1,3,5],tool:[0,1],toolbar:[5,8],top:[0,1,2,3,5,6,7,10],toplevellookupexcept:1,toplevelnotfound:10,topmost:[5,6,7,8],torborg:1,toscawidget:1,touch:1,toward:[2,5],trace:[1,10],traceback:[1,10],tracelin:10,track:[1,7],trail:3,transform:3,transit:7,translat:[1,10],transpar:7,travers:6,treat:[1,9],treatment:9,tri:[2,7,10],trim:[1,3,8],trofatt:1,tryexcept:1,tue:1,tupl:[1,10],turbogear:1,turn:[1,5,9],twist:2,two:[0,1,2,3,5,7,8,9,10],txt:[8,9,10],type:[0,1,2,3,6,7,8,9,10],typeerror:[1,7],typic:[0,10],ultim:[1,5,6],umask:1,unbound:10,unbuff:3,unclos:1,uncommon:1,uncondition:9,undeclar:[1,10],undefin:[1,2,7,8,10],under:[0,1,9,10],underli:[0,2,3,5,6,7,8,10],underneath:0,underscor:1,understand:[5,9],understood:0,une:9,unescap:1,unexplain:1,unicod:[1,3,4],uniniti:7,uniqu:[0,5,7],unit:1,univers:1,unknown:1,unless:[7,9],unlik:9,unnecessari:1,unreach:2,until:[1,10],unusu:10,updat:[1,10],upon:[0,1,2,3,5,10],uri:[1,6,8,10],url:[0,1,3,8,10],urllib:3,usabl:2,usag:[0,1,2,3,4,5,7],use:[0,1,2,3,5,6,7,8,9,10],use_pag:3,used:[0,1,2,3,5,6,7,8,9,10],useful:[2,3,5,6,7],usefulness:[2,6],user:[1,7,8,9,10],userbas:9,usernam:[2,8],uses:[1,3,8,9,10],using:[0,1,2,3,5,6,7,8,10],usual:[0,1,3,7,8,10],utf8:[3,9],utf:[1,3,9,10],util:10,valid:8,valu:[0,1,2,3,6,7,8,9,10],vanasco:1,variabl:[1,2,5,6,8,10],variant:[1,8],varieti:[0,6,8],variou:[1,3,6,7,8,9,10],vast:9,veri:[0,1,2,5,10],version:[0,2,3,4,5,7,8,9,10],versu:[1,6,10],via:[0,1,2,5,6,7,8,9,10],view:10,vincent:1,vladimir:1,voix:9,von:1,vou:9,vowel:7,wai:[0,1,2,3,4,5,7,8,9,10],walkthrough:2,want:[0,2,3,5,6,7,8,9],warn:1,wasn:[1,5,7],web:10,wed:1,weight:1,welcom:1,well:[0,1,2,3,5,6,7,8,9,10],were:[1,5,6,7,9],what:[1,2,4,6,7,8,9,10],whatev:[1,6,7,9,10],whatsoev:[1,9],wheel:1,when:[0,1,2,3,5,6,7,8,9,10],whenev:[5,9,10],where:[0,1,2,3,5,6,7,8,9,10],wherea:[2,7,8,9],wherebi:1,wherev:9,whether:[1,3,7,8],which:[0,1,2,3,5,6,7,8,9,10],white:[1,5],whitespac:[1,2,3,8],who:[1,9],whole:[1,2,3,5,6],whoop:1,why:7,wichert:1,wide:1,widget:2,window:1,wise:1,wish:[0,3,7],within:[0,1,3,5,6,7,8,9,10],without:[0,1,5,6,7],won:[5,7,10],wonder:8,word:[5,10],work:[0,1,2,3,5,6,7,9,10],world:[2,6,7,8,9,10],woroshow:1,would:[0,1,2,3,5,7,9,10],wouldn:[6,8],wrap:[1,2,4,8],wrapper:3,write:[1,3,6,7,8,9,10],writer:7,written:[1,5,8,10],wsgi:1,wsgiutil:10,x80:9,x99a:9,xa9:9,xa9veil:9,xb4le:9,xc3:9,xe2:9,xie:1,xml:[1,3,8,10],year:1,yes:5,yet:[0,1,6],ymmv:1,you:[0,1,2,3,5,6,7,8,9,10],your:[1,2,3,5,6,7,8],yourself:[9,10],yve:1,zebra:7,zer0:1,zero:1,zhang:1,zimport:1,zzzeek:1},titles:["Caching","Changelog","Defs and Blocks","Filtering and Buffering","Table of Contents","Inheritance","Namespaces","The Mako Runtime Environment","Syntax","The Unicode Chapter","Usage"],titleterms:{"static":6,"true":9,But:5,One:6,The:[3,6,7,8,9],Use:[6,7],Using:[0,2,5,10],about:5,access:0,accessor:7,all:7,api:[0,6,7,10],argument:[0,2,3],attr:6,attribut:5,augment:5,babel:10,backend:0,base:10,basic:10,beaker:0,block:[2,3,5,8],bodi:6,buffer:[3,7,9],built:[6,7],cach:0,call:[2,6,8],changelog:1,chapter:9,check:10,collect:10,comment:8,common:10,content:[2,4,5],context:[7,8],control:8,cycl:7,declar:6,decor:3,def:[2,3,5,6,8],default_filt:3,defin:9,defnam:8,depend:6,disabl:9,disable_unicod:9,doc:8,dogpil:0,earli:8,embed:2,encod:[9,10],entir:9,environ:7,escap:8,exampl:6,except:10,exit:8,express:[3,8,9],file:[2,9,10],filesystem:10,filter:[3,8],framework:10,from:[2,6,8],guidelin:0,handl:[9,10],heck:9,includ:[5,8],indic:4,inherit:[5,6,8],integr:10,iter:7,legaci:7,level:8,local:6,loop:[7,8],mako:7,method:[6,7],migrat:7,modul:[6,8],multipl:5,name:[2,5,6,7],namespac:[5,6,8],nest:5,newlin:8,next:5,nsname:8,off:3,older:1,other:2,output:9,page:[2,8],parent:[5,7],plugin:0,produc:5,programmat:[0,2],pygment:10,python:[6,8],refer:[0,6,7,10],regular:6,render:5,reserv:7,rule:9,runtim:7,sai:9,select:9,self:6,set:10,size:10,specif:[0,6],specifi:9,structur:8,substitut:8,syntax:8,tabl:4,tag:8,templat:[5,7,8,9,10],templatelookup:10,text:8,time:5,turn:3,two:6,unicod:[9,10],usag:[6,9,10],using:9,variabl:7,version:[1,6],wai:6,what:5,within:2,word:7,wrap:5,write:0,wsgi:10}}) \ No newline at end of file +Search.setIndex({docnames:["caching","changelog","defs","filtering","index","inheritance","namespaces","runtime","syntax","unicode","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["caching.rst","changelog.rst","defs.rst","filtering.rst","index.rst","inheritance.rst","namespaces.rst","runtime.rst","syntax.rst","unicode.rst","usage.rst"],objects:{"mako.cache":{Cache:[0,0,1,""],CacheImpl:[0,0,1,""],register_plugin:[0,4,1,""]},"mako.cache.Cache":{get:[0,1,1,""],get_or_create:[0,1,1,""],id:[0,3,1,""],impl:[0,3,1,""],invalidate:[0,1,1,""],invalidate_body:[0,1,1,""],invalidate_closure:[0,1,1,""],invalidate_def:[0,1,1,""],put:[0,1,1,""],set:[0,1,1,""],starttime:[0,3,1,""]},"mako.cache.Cache.get.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.Cache.invalidate.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.Cache.set.params":{"**kw":[0,2,1,""],key:[0,2,1,""],value:[0,2,1,""]},"mako.cache.CacheImpl":{get:[0,1,1,""],get_or_create:[0,1,1,""],invalidate:[0,1,1,""],pass_context:[0,3,1,""],set:[0,1,1,""]},"mako.cache.CacheImpl.get.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.CacheImpl.get_or_create.params":{"**kw":[0,2,1,""],creation_function:[0,2,1,""],key:[0,2,1,""]},"mako.cache.CacheImpl.invalidate.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.cache.CacheImpl.set.params":{"**kw":[0,2,1,""],key:[0,2,1,""],value:[0,2,1,""]},"mako.exceptions":{RichTraceback:[10,0,1,""],html_error_template:[10,4,1,""],text_error_template:[10,4,1,""]},"mako.exceptions.RichTraceback":{error:[10,3,1,""],lineno:[10,3,1,""],message:[10,3,1,""],records:[10,3,1,""],reverse_records:[10,3,1,""],reverse_traceback:[10,3,1,""],source:[10,3,1,""]},"mako.ext.beaker_cache":{BeakerCacheImpl:[0,0,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl":{get:[0,1,1,""],get_or_create:[0,1,1,""],invalidate:[0,1,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl.get.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl.get_or_create.params":{"**kw":[0,2,1,""],creation_function:[0,2,1,""],key:[0,2,1,""]},"mako.ext.beaker_cache.BeakerCacheImpl.invalidate.params":{"**kw":[0,2,1,""],key:[0,2,1,""]},"mako.lookup":{TemplateCollection:[10,0,1,""],TemplateLookup:[10,0,1,""]},"mako.lookup.TemplateCollection":{adjust_uri:[10,1,1,""],filename_to_uri:[10,1,1,""],get_template:[10,1,1,""],has_template:[10,1,1,""]},"mako.lookup.TemplateCollection.get_template.params":{relativeto:[10,2,1,""],uri:[10,2,1,""]},"mako.lookup.TemplateCollection.has_template.params":{uri:[10,2,1,""]},"mako.lookup.TemplateLookup":{adjust_uri:[10,1,1,""],filename_to_uri:[10,1,1,""],get_template:[10,1,1,""],put_string:[10,1,1,""],put_template:[10,1,1,""]},"mako.lookup.TemplateLookup.params":{collection_size:[10,2,1,""],directories:[10,2,1,""],filesystem_checks:[10,2,1,""],modulename_callable:[10,2,1,""]},"mako.runtime":{Context:[7,0,1,""],LoopContext:[7,0,1,""],ModuleNamespace:[6,0,1,""],Namespace:[6,0,1,""],TemplateNamespace:[6,0,1,""],Undefined:[7,0,1,""],capture:[6,4,1,""],supports_caller:[6,4,1,""]},"mako.runtime.Context":{get:[7,1,1,""],keys:[7,1,1,""],kwargs:[7,3,1,""],lookup:[7,3,1,""],pop_caller:[7,1,1,""],push_caller:[7,1,1,""],write:[7,1,1,""],writer:[7,1,1,""]},"mako.runtime.LoopContext":{cycle:[7,1,1,""]},"mako.runtime.ModuleNamespace":{filename:[6,3,1,""]},"mako.runtime.Namespace":{attr:[6,3,1,""],cache:[6,3,1,""],context:[6,3,1,""],filename:[6,3,1,""],get_cached:[6,1,1,""],get_namespace:[6,1,1,""],get_template:[6,1,1,""],include_file:[6,1,1,""],module:[6,3,1,""],template:[6,3,1,""],uri:[6,3,1,""]},"mako.runtime.TemplateNamespace":{filename:[6,3,1,""],module:[6,3,1,""],uri:[6,3,1,""]},"mako.template":{DefTemplate:[10,0,1,""],Template:[10,0,1,""]},"mako.template.DefTemplate":{get_def:[10,1,1,""]},"mako.template.Template":{code:[10,3,1,""],get_def:[10,1,1,""],list_defs:[10,1,1,""],render:[10,1,1,""],render_context:[10,1,1,""],render_unicode:[10,1,1,""],source:[10,3,1,""]},"mako.template.Template.params":{buffer_filters:[10,2,1,""],bytestring_passthrough:[10,2,1,""],cache_args:[10,2,1,""],cache_dir:[10,2,1,""],cache_enabled:[10,2,1,""],cache_impl:[10,2,1,""],cache_type:[10,2,1,""],cache_url:[10,2,1,""],default_filters:[10,2,1,""],disable_unicode:[10,2,1,""],enable_loop:[10,2,1,""],encoding_errors:[10,2,1,""],error_handler:[10,2,1,""],filename:[10,2,1,""],format_exceptions:[10,2,1,""],future_imports:[10,2,1,""],imports:[10,2,1,""],include_error_handler:[10,2,1,""],input_encoding:[10,2,1,""],lexer_cls:[10,2,1,""],lookup:[10,2,1,""],module_directory:[10,2,1,""],module_filename:[10,2,1,""],module_writer:[10,2,1,""],output_encoding:[10,2,1,""],preprocessor:[10,2,1,""],strict_undefined:[10,2,1,""],text:[10,2,1,""],uri:[10,2,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","parameter","Python parameter"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"]},objtypes:{"0":"py:class","1":"py:method","2":"py:parameter","3":"py:attribute","4":"py:function"},terms:{"0263":[1,9],"0750":1,"0775":1,"101":1,"102":1,"104":1,"108":1,"109":1,"110":1,"112":1,"11211":0,"116":1,"118":1,"119":1,"122":1,"123":[1,3],"125":1,"126":1,"127":[0,1],"128":[1,9],"129":1,"131":1,"132":1,"135":1,"137":1,"141":1,"142":1,"146":1,"147":1,"148":1,"151":1,"153":1,"154":1,"155":1,"156":1,"159":1,"164":1,"165":1,"1684":1,"169":1,"170":1,"173":1,"174":1,"175":1,"178":1,"180":1,"181":1,"182":1,"185":1,"186":1,"187":1,"190":1,"191":1,"192":1,"193":1,"2007":1,"2008":1,"2009":1,"201":1,"2010":1,"2011":1,"2012":1,"2013":1,"2014":1,"2015":1,"2016":1,"2017":1,"2019":1,"2020":1,"2021":1,"207":1,"208":1,"209":1,"212":1,"213":1,"214":1,"216":1,"219":1,"224":1,"225":1,"227":1,"236":1,"249":1,"250":1,"267":1,"271":1,"283":1,"287":1,"293":1,"295":1,"296":1,"2to3":1,"300":0,"301":1,"303":1,"304":1,"310":1,"328":1,"500":10,"5534":1,"5b1":1,"abstract":10,"bj\u00f6rn":1,"boolean":10,"break":1,"byte":[1,9,10],"case":[0,1,2,3,5,6,7,8,9,10],"catch":1,"class":[0,1,2,5,6,7,9,10],"default":[0,1,2,3,5,6,7,8,9,10],"dr\u00f4le":9,"export":[2,5,8],"f\u00e9rotin":1,"final":[1,3,5,9],"float":1,"function":[0,1,2,3,5,6,7,8,9,10],"import":[0,1,2,3,6,7,8,9,10],"int":7,"long":[1,7,8],"new":[0,1,2,3,5,7,8,10],"pla\u00eet":9,"r\u00e9veill\u00e9":9,"return":[0,1,2,3,6,7,8,9,10],"short":0,"static":[4,5],"super":[0,5,6,9],"switch":7,"throw":[0,7],"true":[0,1,2,3,6,7,8,10],"try":[1,3,7,8,9,10],"var":1,"while":[1,2,3,5,8,10],Added:[1,10],And:5,But:[2,4,6,10],For:[0,1,2,3,5,6,7,9,10],Its:2,One:[0,3,5,7,10],Such:[0,2,3,5],That:[1,5,9],The:[0,1,2,4,5,10],Then:2,There:[0,2,6,9],These:[0,6,8,10],Use:[5,8,10],Using:[1,4,6,7,8],Will:1,With:[0,2,7,10],__builtin__:1,__builtins__:1,__class__:[1,10],__file__:6,__future__:[1,10],__getattr__:1,__html__:1,__init__:0,__len__:7,__m_:1,__m_local:9,__name__:[0,1,10],__nonzero__:1,__str:9,__str__:7,__version__:1,_cach:0,_data:1,_my_cache_work:0,_pop_buff:1,_pop_fram:1,_push_buff:1,_push_fram:1,abil:[0,6,8,9,10],abl:7,about:[1,4,7,8,10],abov:[0,2,3,5,6,7,8,9,10],absolut:[1,2,9],accept:[0,1,3,6,7,8,9,10],access:[1,2,4,5,6,7,8,10],accessor:[0,1,5,6],accommod:1,accompani:10,accomplish:[0,8,10],accord:1,accordingli:10,account:[2,3],accountdata:2,accountnam:2,accumul:8,achiev:[2,5,7],acquir:[0,9],across:[0,7],act:[7,10],actual:[0,1,2,3,5,6,7,8,10],add:[2,3,5,10],added:[1,3,5,8],adding:3,addit:[0,1,2,3,5,6,8,10],addition:[1,5,9,10],address:[0,10],adjust:[1,6,8,10],adjust_uri:10,advanc:10,advantag:[5,6,9,10],affect:[1,7],afford:[1,10],after:[0,1,3,6,7,10],again:[2,7],against:[1,8,10],ago:[1,9],agre:5,akkerman:1,alemb:1,algorithm:1,all:[0,1,2,3,4,5,6,8,9,10],allow:[0,1,2,3,5,6,7,8,9,10],almost:[5,8],alon:1,along:[0,5,6],alor:9,alpha:1,alreadi:[1,5,7,10],also:[0,1,2,3,5,6,7,8,9,10],altern:[1,7,9,10],although:8,altogeth:1,alwai:[1,2,5,7,9],ani:[0,1,2,3,5,6,7,8,9,10],anonym:[0,1,2,8],anoth:[1,2,5,6,7,8,9,10],answer:1,anyth:[2,5,9],anywai:[1,10],anywher:[2,6,8],api:[1,3,4],appar:[1,3,6],appear:[1,3,7,8,10],append:10,appli:[1,2,3,6,7,8,9,10],applic:[1,3,7,8,10],approach:[5,7,9],appropri:1,approxim:10,apr:1,aptli:10,arbitrari:[0,8],arbitrarili:[1,2],area:[2,5,7,8,9],aren:[1,2,9],arg1:6,arg2:6,arg3:6,arg4:6,arg:[0,1,2,3,6,8,10],argpars:1,arguabl:9,argument:[1,4,6,7,8,9,10],around:[1,3,7,10],arrai:3,arrang:8,ascii:[1,9],ask:7,aspect:[8,9],assign:[1,2,7,8,10],associ:[0,1,7],assum:[9,10],ast:1,atom:10,attach:6,attempt:[0,1,9],attr:[1,5],attribut:[0,1,2,3,4,6,7,8,10],attributeerror:1,aug:1,augment:[2,4],author:7,automat:[0,2,3,5,7,8,10],avail:[0,1,2,3,5,6,7,8,9,10],avoid:1,awai:5,awar:[1,7,9,10],babel:1,babelplugin:10,back:[1,5,7,9,10],backend:[1,6],background:9,backslash:[1,8],backward:[0,1],bar:[1,2,3,6,7,8,10],bare:1,base:[0,1,3,4,5,6,7,8],basemost:5,basestr:1,basi:[0,5,7],basic:[1,2,4,6,8],batch:3,batcheld:1,beaker:[1,10],beaker_cach:0,beakercacheimpl:0,bean:10,becam:1,becaus:[1,2,3,5,9],becom:[1,6,9,10],been:[0,1,3,6,9,10],befor:[0,1,3,5,6,8,9,10],began:[1,7],begin:10,behav:2,behavior:[1,3,5,7,10],being:[0,1,2,5,7,8,9,10],bell:9,below:[1,2,5,9],ben:1,benchmark:1,best:8,better:[0,1,7],between:[1,2,5,6,7],beyond:[0,2],binari:9,bit:[1,2,7,10],bitwis:1,black:[1,7],blank:[1,7],block:[0,1,4,7],blunt:0,board:7,bodi:[0,1,2,4,5,7,8,10],bold:3,bom:1,bool:7,bot:7,both:[1,2,3,5,7,9,10],bottom:1,bottommost:5,bound:1,bracket:1,breakag:1,breakdown:5,brief:10,broke:1,broken:1,buf:[3,10],buffer:[1,4,6,8,10],buffer_filt:[1,10],buffet:1,bugfix:1,build:[1,2,5,6],builder:1,buildtabl:2,built:[1,2,3,4,5,8,9,10],builtin:[1,9],bump:1,bunch:6,burden:9,bye:2,bytestr:[1,10],bytestring_passthrough:[1,10],cach:[1,2,3,4,6,7,8,10],cache_:[0,1],cache_arg:[0,1,10],cache_dir:[0,1,10],cache_en:[0,1,10],cache_impl:[0,1,10],cache_kei:[0,1],cache_region:0,cache_timeout:[0,1,2],cache_typ:[0,1,8,10],cache_url:[0,1,10],cache_xyz:0,cacheabl:1,cacheimpl:[0,1,10],cachemanag:[0,1],calcul:10,call:[0,1,3,4,5,7,9,10],call_my_object:9,callabl:[0,1,2,3,6,7,8,10],callable_:[6,10],caller:[1,2,3,6,7],caller_stack:[1,6,9],calling_uri:6,callstack:7,came:1,camp:1,can:[0,1,2,3,5,6,7,8,9,10],cannot:[1,2,9,10],cant:1,capabl:[0,1,10],captur:[1,3,6,7,10],care:[0,6,7,9],catalog:10,categori:6,caught:10,caus:[1,3,6,7,10],cazabon:1,central:[2,3,7,8],centric:9,certain:[1,3,6,9,10],cfg:[1,10],cgi:[1,3,9],chain:[1,5,6,7,8],chang:[0,5,7,9],changelog:4,chapter:[2,3,4,5,10],charact:[1,8,9,10],characterist:8,charl:1,check:[1,5,7,8,9],checker:7,cheetah:9,chevalli:1,child:5,choos:9,chosen:0,christoph:1,clarifi:1,class_:5,classic:[6,8],clean:[0,1,10],cleaner:7,clock:1,close:[1,2,6,8,10],closur:2,cmd:1,cmdline:1,code:[1,2,3,6,7,8,9,10],codebas:1,codec:[9,10],codegen:1,codi:1,coerc:9,col:2,collect:[0,1,6,7,9],collection_s:10,collis:1,colomiet:1,colon:[0,8],column:2,com:1,combin:[1,7],come:[0,2,5,8,9,10],comma:[2,3,10],command:[1,10],comment:[1,4,9,10],common:[1,4,5,6,9],commonli:[0,5,9],commun:[2,7],comp1:6,comp2:6,comp:6,compar:[9,10],compat:[0,1,6,10],compil:[0,1,7,8,10],compileexcept:1,complet:[1,5,6,10],complex:1,compliant:9,compon:[0,6,7],comprehens:1,concaten:[3,10],conceiv:7,concept:[2,8,10],condit:[1,2,5,8],condition:[1,6],configur:[0,1,5,6,10],conflict:0,conform:1,confus:[5,9],conjunct:[1,5,10],consid:[1,7,10],consist:8,consol:9,conson:7,constant:[1,7],construct:[0,1,2,5,6,8,9,10],constructor:1,consum:[0,1,8],contain:[0,1,2,6,8,9,10],content:[0,1,3,6,7,8,10],context:[0,1,2,3,4,5,6,9,10],contextu:2,contigu:8,continu:[1,8,10],contrast:[2,5,9],contrib:1,contribut:1,contriv:10,control:[1,2,3,4,5,7,10],convei:10,conveni:0,convent:[2,6],convers:[1,9],convert:[0,1,9,10],convert_com:1,copi:[1,6,7],core:1,correct:[1,6],correctli:[1,7],correspond:[0,5,6,7,10],corrupt:1,could:[1,5],couldn:1,count:[2,7,10],coupl:1,cours:[1,7],courtesi:1,cover:1,coverag:1,creat:[0,1,2,6,7,8,9,10],creation:[0,1,2,3,10],creation_funct:0,critic:1,crlf:1,cross:1,css:[1,6,10],cstringio:[1,9,10],ctx:10,current:[1,2,5,6,7,8,10],current_sect:8,custom:[1,2,3,5,6,8,9,10],dahlgren:1,dairiki:1,daniel:1,data:[0,1,2,3,6,7,9,10],databas:2,date:1,daverio:1,dbm:0,deal:[7,8,9],dealt:10,dec:1,decid:[7,8],decis:[5,7,9],declar:[1,2,3,4,5,8,10],decod:[1,3,9],decor:[1,4,6],decreas:6,deepli:2,def:[0,1,4,7,9,10],default_filt:[1,9,10],default_tim:1,defin:[1,2,3,4,5,6,7,8,10],definit:[2,3,5,6],defnam:[1,2],deftempl:[2,10],delai:1,deliv:[1,3,6],delta:6,demarc:2,denot:8,depend:[1,4,8,10],deploy:1,deprec:[1,10],depth:7,derek:1,deriv:[0,1,3],describ:[1,2,3,5,6,7,8,9,10],descript:[0,6,7,10],descriptor:1,design:3,desir:[1,6,9,10],despit:1,dessin:9,dest:10,destin:10,detail:[2,5,7,8,9,10],detect:1,determin:[0,1,9],determinist:3,dev:1,develop:[1,9],dict:[1,9],dictionari:[0,1,6,7,10],did:[1,5],differ:[0,1,2,5,6,7,10],differenti:7,dir:[0,1,10],direct:[0,2,6,8,10],directli:[0,1,2,3,6,8,10],directori:[0,1,3,7,9,10],dirnam:10,disabl:[0,1,3,4,7,10],disable_unicod:[1,3,10],disait:9,disallow:1,discard:3,discuss:1,disgard:9,displai:[1,10],disregard:10,distinct:[1,10],distinctli:5,distribut:10,distutil:10,div:[2,5,6,10],divis:10,do_something_speci:0,doc:[1,2,7,9,10],document:[0,1,5,8,9,10],doe:[1,2,5,6,7,8,9],doesn:[1,2,5,6,7],doing:[3,9],don:[0,1,2,5,7,9],done:[9,10],dot:1,doubli:1,down:[0,1,9],dragon:1,draw:3,drive:1,drop:[1,8],due:1,dumb:9,dump:[3,6,9],dure:[1,5,10],dyn:6,dynam:[1,5,8],each:[0,1,2,5,6,7,8,9,10],earli:[1,4],earlier:[0,9],eas:[3,7],easi:[3,7],easier:0,edgewal:1,eeve:1,effect:[0,1,2,3,6,10],egg:7,either:[0,1,5,7,8,9,10],elabor:1,elem:8,element:[1,2,5,7,8,9,10],elif:8,elimin:9,ell:9,els:[0,1,7,8,10],elsewher:1,emac:1,email:8,emb:[6,8,9],embed:[1,6,7,8,10],emit:[1,8],empti:[1,3,8,9],enabl:[0,1,7,8,10],enable_loop:[1,7,10],enclos:[1,2,7],encod:[1,3,4],encoding_error:[1,9,10],encount:[1,5],end:[1,3,5,8],endfor:[2,6,7,8],endif:[1,2,6,7,8],endless:1,endwith:1,enforc:1,enorm:2,ensur:[0,1,6,9],entir:[2,3,4,5,6,8,10],entiti:[1,3],entri:[0,1,10],entrypoint:[0,1],enumer:7,environ:[1,3,4,8,10],epoch:0,equival:[0,2,3,6,8],eric:1,errant:1,error:[1,2,7,9,10],error_handl:[1,10],escap:[1,2,3,4,9],essenti:[0,6,9],establish:[1,7,10],etc:[0,1,2,6,7,8,10],eval:1,evalu:[1,2,6,8],evaul:1,even:[1,5,7,8,9],ever:[6,9],everi:[1,6,8],everyon:7,everyth:[1,7],exactli:[2,5],examin:6,exampl:[0,1,2,3,4,5,7,8,10],exc:1,exc_info:[1,10],exceed:7,except:[0,1,2,3,4,6,7,8],excerpt:10,exclus:10,exec:1,execut:[0,1,2,3,5,6,7,8,10],exist:[0,1,2,6,7,8,10],exit:[1,4],expand:1,expect:[1,2,5,7,8,9],experienc:7,expir:[0,1],expiri:1,explcitli:1,explicit:[0,1,2,6,7,8,9],explicitli:[1,5,6,7,9,10],expr:[1,2,6],express:[1,2,4,5,6,7,10],expression_filt:[1,3],ext:[0,1,10],extens:1,extern:[0,2,5],extra:[1,5,8],extract:[1,10],extractor:[1,10],facad:0,facet:7,facil:5,fact:[2,5,9],fail:1,failur:7,fake:8,fall:0,fals:[0,1,7,10],familiar:[2,8],far:[1,5,8,9,10],fashion:0,fast:10,fastencodingbuff:[1,9],faster:[1,9],favor:1,featur:[0,5,7,8,10],feb:1,few:[1,7],field:10,file:[0,1,4,5,6,7,8],filehandl:[1,9],filenam:[0,1,6,10],filename_to_uri:10,filesystem:[0,1,6],filesystem_check:10,filter:[1,2,4,7,9,10],find:[7,8,10],finish:5,first:[0,1,3,5,6,7,8,9,10],five:[0,8],fix:[0,1,6,10],flag:[0,1,3,6,7,8,9,10],flexibl:[3,5,8],flip:2,flow:8,fly:9,follow:[1,2,5,6,7,8,10],foo:[1,2,3,6,7,8,9,10],footer:[5,8],forc:[1,10],form:[1,2,6,8],format:[1,2,3,6,8,9,10],format_except:[1,10],formatt:1,former:1,forward:1,found:[1,2,7,8],four:[6,8],fragment:1,frame:1,framework:4,francoi:10,free:[1,6],freeli:7,fri:1,frobnizzl:8,from:[0,1,3,4,5,7,9,10],frozenset:1,full:[1,8,10],fulli:[1,3,5,10],func:6,further:[1,8],futur:[1,6,8],future_import:[1,10],futures_import:10,fyi:1,gae:1,gagern:1,game:9,garbag:0,gather:9,gave:10,geisler:1,gener:[0,1,2,3,5,6,7,8,9,10],genshi:8,georg:1,get:[0,1,3,5,6,7,8,9,10],get_cach:6,get_def:[1,2,3,10],get_namespac:[1,6],get_or_cr:[0,1],get_resourc:8,get_templ:[0,6,9,10],getargspec:1,getattr:6,getdefaultencod:1,getfullargspec:1,gettext:[1,10],getvalu:[3,10],github:1,give:[2,6],given:[0,1,2,3,5,6,7,10],global:[0,2,5,6,7],glyph:1,goal:[1,3],goe:8,going:[1,9],good:[0,1,8],got:1,graphic:9,great:[6,9],grei:5,group:[0,1,6],guess:[1,9],guest:1,guid:10,hack:[1,7],had:[1,9],hadn:1,haltner:1,ham:7,hand:5,handi:6,handl:[0,1,2,4,7,8],handler:[1,10],happen:[6,7,9],hard:[5,7,8,9],harland:1,has:[0,1,2,3,5,6,7,8,9,10],has_templ:10,hasattr:6,hash:1,hasn:1,have:[0,1,2,3,5,6,7,8,9,10],head:[1,2,5,6,10],header:[0,1,2,5,8,10],heavili:9,heck:[4,10],hello:[2,6,8,9,10],help:[0,1,9,10],helper:10,her:9,here:[0,1,3,5,6,7,8,9,10],higher:1,highlight:[1,10],his:9,hit:[3,9],hold:6,home:1,honor:1,hopefulli:1,how:[1,2,6,7,8,10],howev:[1,2,5,6,9],href:[2,6],htdoc:10,html:[0,1,2,3,5,6,8,9,10],html_error_templ:[1,10],html_escap:1,htmlentitydef:3,htmlentityreplac:[1,10],http:1,huayi:1,hugo:1,hypothet:5,idea:[1,5,8],ideal:1,ident:[1,6,10],identifi:[0,1,8,10],ignor:[7,8],illus:9,illustr:[3,5,10],imag:[9,10],imaginez:9,imankulov:1,immedi:[1,5,7,8,10],immut:7,impl:0,implement:[0,1,2,5,10],impli:10,implic:9,implicit:[0,7],implicitli:1,improv:[1,8,9,10],incl:6,includ:[0,1,2,3,4,6,7,10],include_error_handl:[1,10],include_fil:[1,6],incom:9,incompat:1,incorrect:1,increas:10,indent:[1,8],index:[1,4,5,6,7,8,10],indic:[0,1,7,8],individu:[0,1,2,7,10],info:[1,10],inform:[1,6,8,9,10],inher:3,inherit:[0,1,2,4,7,10],ini:1,initi:[1,2],inject:10,inlin:[1,5,7,8],inner:[1,2],input:[1,2,3,9],input_encod:[1,9,10],insensit:1,insert:[5,10],insid:[0,1,2,5,6,8,10],inspect:1,inspir:8,instal:[0,1],install_requir:1,instanc:[6,7,8,10],instead:[1,2,3,5,6,9,10],insur:1,integ:[0,2,9],integr:[0,1,4,5],intellig:9,intend:[1,3,6],intent:3,interact:[5,6,9],interchang:5,interest:10,interfac:0,intermedi:5,intermix:5,intern:[0,1,3,7,9,10],interpret:[1,2,9,10],interven:1,intric:1,intro:2,introduc:[1,2,5,6,7,8],invalid:[0,1],invalidate_bodi:[0,1],invalidate_closur:[0,1],invalidate_def:[0,1],invoc:5,invok:[2,5,8,10],involv:[1,5],ioerror:1,iou:7,isn:[1,7],issu:[1,2,9,10],item:[2,7,8],iter:[2,6],its:[0,1,2,3,5,6,7,8,9,10],itself:[0,1,2,3,5,6,7,8,9,10],jack:10,jan:1,javascript:6,jeff:1,jinja2:[1,2,8],jinja:1,jit:7,job:3,joe:8,john:2,join:9,jonathan:1,jot:7,jour:9,json:[1,3],jsp:8,jul:1,jun:1,just:[1,2,3,5,6,7,8,9,10],jut:7,jython:1,keep:2,kei:[0,1,5,6,7,9,10],keyerror:7,keyword:[1,2,5,6,7,8,9,10],kind:[0,3,5,6,7,8,9,10],know:[5,9],known:[1,2,6],kwarg:[0,1,6,7,10],lack:1,lacsap:1,lai:2,lambda:1,languag:[2,8,9],larg:[1,5],last:[1,7,10],last_modifi:1,later:[0,8],latest:1,latter:[1,9],laurent:1,layout:[1,2,5,6,10],layoutdata:2,lead:[1,3,6,7],learn:9,least:[6,10],left:[3,10],leftmost:3,legaci:[1,10],legacy_html_escap:1,legendari:1,len:8,less:[1,5,7,9],let:[1,2,5,7,10],level:[0,1,2,3,4,5,6,7,9,10],lever:9,leverag:8,lex:1,lexer:[1,8,10],lexer_cl:[1,10],lib:1,librari:[0,2,3,6,9,10],lieu:10,lift:5,lighter:1,like:[0,1,2,3,5,6,7,8,9,10],line:[1,5,8,9,10],lineno:10,lingua:1,link:[6,10],linkag:5,list:[0,1,2,3,5,7,8,9,10],list_def:[1,10],lister:2,liter:[1,3,6,9,10],littl:[1,2,7,10],live:0,load:[1,6,8,10],load_templ:1,loader:1,local:[0,1,2,3,7,8,10],locals_:1,locat:[1,6,7,9,10],lock:0,logic:[1,3],long_term:0,longer:1,look:[0,1,2,5,6,7,9,10],lookup:[0,1,7,9,10],loop:[1,2,4,10],loopcontext:7,lopez:1,lost:1,lot:[1,8],lower:1,made:[0,1,7],magamedov:1,magic:[1,7,9],mai:[0,1,3,6,7,8,9,10],main:[1,2,3,5,6,7,9,10],mainlayout:[2,5],mainli:[1,6],maintain:[0,1,10],major:[1,7,9],mak:1,make:[0,1,2,3,5,6,7,8,9,10],mako:[0,1,2,3,4,5,6,8,9,10],mako_cach:0,mako_modul:10,manag:[0,1,7],manfr:1,mani:[1,7,8,9],manner:3,manual:10,map:[1,10],mar:1,markedli:9,marker:[1,8],markupsaf:[1,3,9],martin:1,matter:5,maxim:[0,9],maximum:1,mayb:5,mean:[0,1,2,3,5,6,7,8,9,10],meant:5,mechan:[0,5,8],member:[7,8,10],memcach:[0,1],memori:[0,1,8,10],merg:1,mess:1,messag:[1,7,10],met:2,metadata:[1,8],metaphor:5,method:[0,1,2,3,4,5,8,9,10],microsecond:1,middl:[3,5,8],might:[5,6,7,8],migrat:[1,10],mimic:10,mini:7,minim:0,minor:10,minu:[0,1],minut:0,mirror:10,mis:1,miss:[1,3,7,10],mistak:5,mix:1,mkstemp:10,mode:[1,9],model:2,moder:10,modern:[0,1],modifi:[1,2,5,9,10],modul:[0,1,2,3,4,5,7,9,10],module_directori:[0,1,10],module_filenam:[1,10],module_writ:[1,10],modulenam:0,modulename_cal:[1,10],modulenamespac:6,modulepath:0,moduletempl:1,moi:9,moment:10,mon:1,monkeypatch:1,more:[0,1,2,3,5,6,7,8,9,10],most:[0,1,2,5,6,7,8,9,10],mostli:[0,1,6,7,10],mouton:9,move:10,msgid:10,msgstr:10,much:[1,2,5,8,9],multi:1,multibyt:[1,10],multilin:[1,8],multipl:[0,1,2,4,9],multithread:0,must:[0,1,2,5,6,9,10],mutual:10,my_tag:6,mycomp:0,mydef:2,myescap:3,myexpress:3,myfil:8,myfilt:[1,3],myfunc:8,myghti:9,myghtyutil:1,mylib:8,mylookup:[9,10],myn:1,mynamespac:[6,8],mypackag:3,myproj:10,mystuff:2,mystyl:6,mytag:6,mytempl:[0,1,9,10],mytmpl:10,name:[0,1,3,4,8,9,10],nameerror:[1,7,10],namespac:[0,1,2,3,4,7,10],namespace_nam:6,namespacenam:[1,2,8],nari:9,nativ:9,natur:3,necessarili:[1,7],ned:1,need:[0,1,2,5,6,7,9,10],neither:0,nest:[0,1,2,3,4,7],nestabl:2,never:1,newer:[2,10],newli:0,newlin:[1,4],next:[0,2,3,4,6,7,8,9,10],nightmar:9,ninja:5,no_tag:1,node:1,non:[1,7,8,9,10],none:[0,1,3,6,7,8,10],normal:[1,2,3,7,8,9,10],nose:1,note:[0,1,2,3,5,6,7,9,10],noth:5,notic:2,notimplementederror:10,notion:7,nov:1,now:[1,3,5,7,8,9],number:[0,1,2,3,7,8,10],numer:[3,8],nutshel:5,object:[0,1,2,3,5,6,7,8,9,10],objnam:0,observ:1,obsolet:1,obvious:5,occlud:1,occur:[0,1,2,10],oct:1,odd:[1,7],off:[0,1,2,5,6],offer:[8,9],often:[5,6],old:[1,7],older:[2,4,8],omit:1,onc:[2,5,7,8],one:[0,1,2,3,5,6,7,8,9,10],ongo:1,onli:[0,1,2,3,5,7,8,9,10],onto:[7,8],open:[5,8,9],oper:[1,2,3,6,7,8,9,10],opposit:5,opt:[0,1,10],optim:1,option:[0,1,6,7,8,9,10],optpars:1,order:[0,1,5,8,10],ordinari:6,org:1,organ:[5,6],orient:[2,5],origin:[0,1,3,6,7,9,10],other:[0,1,3,5,6,7,8,9,10],otherwis:[1,7,8,9,10],our:[0,1,2,5,10],out:[0,1,2,5,8,9,10],outer:2,output:[1,2,3,4,5,6,7,8,10],output_encod:[1,9,10],outputpath:10,outsid:[1,2,5,6,7],outward:10,over:[1,3,6,7],overhead:[1,9],overrid:[0,1,5,6,7,9,10],overridden:[0,2,5,6],overrod:5,overwritten:0,own:[0,1,2,3,5,6,7,8,9,10],pack:1,packag:[0,1,8],page:[0,1,3,4,5,6,7,10],pagearg:[1,2,6,7,9],pagecontrol:2,paradigm:5,param:8,paramet:[0,1,6,9,10],parent:[0,1,2,4,6,10],parenthes:1,pariti:7,pars:[1,8,9,10],parseabl:1,parser:1,part:[0,1,5,6,7],parti:0,partial:[1,5],particip:5,particular:[0,1,5,6,7,10],particularli:[1,6],pass:[0,1,2,5,6,7,8,9,10],pass_context:[0,1],passthru:1,patch:1,path:[0,1,6,10],pathnam:1,pattern:10,paul:1,pbj:7,penalti:1,peopl:1,pep:[1,9],per:[0,1,5,7,8,9],percent:[1,8],percentag:10,perform:[1,3,6,9,10],perhap:[2,7,8],perl:8,perm:1,perman:1,permiss:[1,10],persist:[0,1],petit:9,petr:1,phase:10,philosophi:7,pinard:10,pipe:[1,3],pit:7,pkg_resourc:[0,1],place:[0,1,2,5,8,10],plai:[6,9],plain:[1,2,6,8,9,10],platform:10,pleas:8,plu:[1,10],plug:0,plugin:[1,4],point:[0,1,2,5,6,8,9,10],polymorph:8,pop:[0,3,7],pop_buff:3,pop_cal:7,pop_fram:9,popul:0,popular:10,populate_self:6,portabl:2,portion:[1,2],posit:6,possibl:[0,2,3,7],post:[2,10],post_pros:2,pot:7,potenti:5,pow:8,power:8,practic:[1,5],pre:[1,10],preambl:10,preced:[5,6,8,9,10],precompil:1,predefin:1,prefer:[1,9],prefix:[0,1,7],prep:7,prepend:1,preprocessor:[1,10],presenc:1,present:[0,1,2,5,6,7,10],preserv:1,pretti:[8,9],prevent:[1,8],previou:[1,2,5,6,7,10],previous:[1,6,9,10],primari:10,primarili:7,print:[1,2,9,10],printabl:9,prior:[3,7,9],privat:1,probabl:[0,1,2,7,10],procedur:0,process:[0,1,5,8,9],produc:[1,2,3,4,6,7,8,9,10],product:10,program:[8,9],programat:10,programm:9,programmat:[1,3,4,6,7,9],progress:7,project:[1,10],propag:[1,7,8,10],proper:10,properli:[1,9],properti:[1,6,10],propig:1,provid:[0,1,2,3,5,6,7,8,10],proxi:6,prune:1,pull:[1,2,6,7,10],pullreq:1,pure:[1,6,8,9],purpos:[1,7,8,9,10],push:7,push_buff:3,push_cal:7,push_fram:9,put:[0,1,5,6,7],put_str:10,put_templ:10,py2:1,py2k:1,py3k:1,pybabel:10,pygment:1,pygmentplugin:10,pylon:[1,10],pypa:1,pypars:1,pypi:1,pyramid:1,pytest:1,pythagorean:8,python3:1,python:[1,2,3,4,5,7,9,10],quand:9,quick:[1,2,8],quickli:9,quot:[1,9],quote_plu:3,rais:[1,2,7,9,10],rang:[1,2,8],rather:[1,7],raw:[1,9,10],reach:[7,10],read:[7,8,9],readm:1,real:[1,8,10],realli:[1,9],ream:9,reason:[1,7,9],recal:5,receiv:[1,2,3,6,8],recent:[1,10],recogn:[5,6],recommend:[1,6],recompil:[0,1,10],record:[6,8,10],recurs:1,red:7,reduc:3,reduct:1,refactor:1,refer:[1,2,3,4,5,8,9],referenc:[1,2,5,6,7],reformat:1,refresh:1,regard:[1,9],regardless:[1,2,5,7],regener:[1,10],regexp:1,region:[0,1],regist:[0,1],register_plugin:[0,1],regress:1,regular:[1,2,3,4,5,8,9,10],reiter:1,rel:[1,6,10],relat:[0,1,10],relationship:6,relativeto:10,releas:[0,1,6,8],reli:1,reload:10,remain:[1,2,7],remot:[2,6],remov:[1,6,9],render:[0,1,2,3,4,6,7,8,9,10],render_:7,render_bodi:[3,7,9,10],render_context:10,render_mydef:7,render_unicod:[1,9,10],reopen:1,repair:1,replac:[0,1,3,9,10],report:[1,10],repres:[0,1,2,7,8,9,10],represent:[1,8,10],request:[0,1,6,7,10],requir:[0,1,2,3,6,8,9],requset:1,reserv:1,reserved_nam:1,reset:1,resolut:[5,6,10],resolv:[1,10],resourc:[1,5,10],respect:8,respons:[0,5,6,7],rest:[0,5,8],restrict:[1,2,5],result:[1,2,3,5,7,8,10],retriev:[0,1],revers:10,reverse_index:7,reverse_record:10,reverse_traceback:10,revis:10,rework:1,rewrot:1,richtraceback:[1,10],right:[1,2,3,7,8,9],role:6,roman:1,root:[1,10],roughli:8,routin:10,row:2,rudiment:[0,10],rule:[1,2,5],run:[1,5,6,7,9,10],run_wsgi:[1,10],runner:[1,10],runtim:[0,1,3,4,5,6,8,10],runtimeerror:1,safe:[7,9],sai:[1,2,4,5,7,10],sake:3,same:[0,1,2,5,6,7,8,9,10],sampl:10,sane:2,sat:1,scaffold:6,scalar:[1,6],scenario:[1,2,5,6,7,10],scheme:[1,2,6,7,9,10],scope:[0,1,2,5,6,7,8],scott:1,script:[1,6],search:[4,10],second:[0,2,3],section:[0,1,2,5,6,7,8,10],sectiona:5,secur:1,see:[0,1,2,6,7,8,9,10],seem:1,segment:9,select:[1,5],selector:1,self:[0,1,2,5,7,8,10],semant:[1,2,5,8],semi:0,send:[1,3,5,6,7,9,10],sens:7,sent:[1,3,6,7,8],sep:1,separ:[0,1,2,3,5,10],sequenc:1,seri:[0,1,9,10],serious:5,serv:[8,9,10],serve_templ:10,server:[0,8,10],servic:[0,8],set:[0,1,3,6,7,8,9],setup:[0,1,5,10],setuptool:[0,1,10],sever:[1,6],shall:5,share:[1,2,7],sharp:2,shell:1,shop:7,short_term:0,should:[0,1,6,7,10],shouldn:7,shown:1,shutil:10,side:[1,2,3,8],sidebar:2,sign:[1,8],signatur:[0,1,2,6,10],signific:[7,8],silent:[1,7],similar:[2,3,5,6,7,8,9,10],similarli:[2,9],simpl:[0,2,7,8,10],simplecacheimpl:0,simpler:1,simplest:8,simpli:[3,5],simplic:3,simplifi:1,sinc:[1,2,5,6,7,9,10],singl:[0,1,2,3,5,8,9,10],singleton:7,sinoroc:1,skip:[1,10],slain:1,slash:[1,6,8],slight:1,slightli:[6,9],slim:0,slowdown:1,slower:9,small:[1,10],smoothli:5,some:[0,1,2,3,5,6,7,8,9,10],some_cal:1,some_condit:2,some_namespac:6,some_other_directori:1,some_tag:1,some_templ:[1,10],somedata:2,somedef:[0,1,2,3,6,8],someencod:1,somefil:[1,6],somefunct:6,somekei:[0,1],somemodul:1,someobject:6,sometempl:0,someth:[2,3,9],sometim:[1,5,8],somev:[6,7],somevalu:0,somewhat:[2,3],somewher:[7,9,10],sophist:5,sound:[5,8],sourc:[1,5,8,9,10],space:[0,1,2,8],spam:7,span:[2,5],special:[0,1,3,7,8,10],specif:[1,2,3,5,7,8,10],specifi:[0,1,3,4,5,7,10],speed:[1,3,9],speedup:1,sphinx:1,sqlalchemi:1,src:6,stack:[1,3,7,10],stacktrac:1,stage:10,stai:[0,7],stale:1,standalon:[1,10],standard:[0,1,9],start:[0,2],starttim:0,startup:1,state:[1,2,5,7,9],statement:[1,2,8,10],stdout:[1,10],step:[1,2,9,10],stick:[1,2,7,8,9],still:[1,2,5,9],stop:[7,8],stop_rend:[1,8],storag:[1,9],store:[0,1,3,7,9,10],str:[1,3,7,9,10],straight:[1,9,10],strategi:0,stream:[1,6,7,8,9,10],streamlin:5,strict:10,strict_undefin:[1,7,10],strictli:[1,9],string:[0,1,3,6,7,8,9,10],stringifi:1,stringio:[1,7,9,10],strip:[1,3],stripe:7,structur:[1,4,5,7],stuff:[6,8],style:[1,2,9],stylesheet:[6,10],sub:[2,8],subclass:[0,2,10],subcompon:2,subdef:2,subdirectori:1,subject:1,subsequ:0,substitut:[3,4,7,10],succe:1,success:10,suggest:1,suit:[1,5],summari:8,sun:1,supersed:[0,1],suppli:[1,6,8],support:[0,1,2,6,8,9,10],supports_cal:[1,6],suppos:[0,2],suppress:3,sure:[1,8],surpris:9,surround:[1,8],suspend:8,svn:1,swap:0,symbol:[1,8],synchron:1,synonym:[0,1,6],syntact:8,syntax:[1,2,3,4,9,10],sys:[1,10],system:[0,1,2,5,7,10],tabl:[1,2,7],tack:6,tag:[0,1,2,3,4,5,6,7,10],tagfilt:3,tailor:2,take:[1,2,3,5,6,8,9],taken:[0,1,6,10],target:[1,2,3],task:0,taylor:1,techniqu:7,techspot:1,tell:8,tempfil:[1,10],templat:[0,1,2,3,4,6],templatecollect:10,templatelookup:[0,1,3,4,6,7,9],templatelookupexcept:10,templatenam:10,templatenamespac:6,templatetext:[3,9],templateuri:6,temporari:1,temporarili:1,term:0,test:1,text:[0,1,2,3,6,7,9,10],text_error_templ:[1,10],textmat:1,textual:[3,5,10],tgplugin:1,than:[0,1,3,5,7,8,9],thank:1,thei:[1,2,3,5,7,8,9,10],them:[1,2,3,5,6,7,10],themselv:[0,2,5,6,7,8],theorem:8,therebi:6,therefor:[5,6,8,10],thereof:1,thi:[0,1,2,3,5,6,7,8,9,10],thing:[1,2,5,7,8,9],think:7,third:0,those:[0,1,2,6,7,8,10],though:[0,1,5,7,9],thread:0,threadsaf:0,three:[7,8],through:[1,6,7,9,10],throughout:[1,6,8],thrown:[0,10],thu:[1,10],time:[0,1,2,3,4,6,10],timeit:1,timeout:[0,1],timestamp:[0,1],tinker:1,titl:[2,5,8],tmbundl:1,tmp:[3,10],togeth:[5,6],token:1,too:[1,3,5],tool:[0,1],toolbar:[5,8],top:[0,1,2,3,5,6,7,10],toplevellookupexcept:1,toplevelnotfound:10,topmost:[5,6,7,8],torborg:1,toscawidget:1,touch:1,toward:[1,2,5],tox:1,trace:[1,10],traceback:[1,10],tracelin:10,track:[1,7],trail:3,transform:3,transit:7,translat:[1,10],transpar:7,travers:6,treat:[1,9],treatment:9,tri:[2,7,10],trim:[1,3,8],trofatt:1,tryexcept:1,tue:1,tupl:[1,10],turbogear:1,turn:[1,5,9],twist:2,two:[0,1,2,3,5,7,8,9,10],txt:[8,9,10],type:[0,1,2,3,6,7,8,9,10],typeerror:[1,7],typic:[0,10],ultim:[1,5,6],umask:1,unbound:10,unbuff:3,unclos:1,uncommon:1,uncondition:9,undeclar:[1,10],undefin:[1,2,7,8,10],under:[0,1,9,10],underli:[0,2,3,5,6,7,8,10],underneath:0,underscor:1,understand:[5,9],understood:0,une:9,unescap:1,unexplain:1,unicod:[1,3,4],uniniti:7,uniqu:[0,5,7],unit:1,univers:1,unknown:1,unless:[7,9],unlik:9,unnecessari:1,unreach:2,until:[1,10],unusu:10,updat:[1,10],upon:[0,1,2,3,5,10],uri:[1,6,8,10],url:[0,1,3,8,10],urllib:3,usabl:2,usag:[0,1,2,3,4,5,7],use:[0,1,2,3,5,6,7,8,9,10],use_pag:3,used:[0,1,2,3,5,6,7,8,9,10],useful:[2,3,5,6,7],usefulness:[2,6],user:[1,7,8,9,10],userbas:9,usernam:[2,8],uses:[1,3,8,9,10],using:[0,1,2,3,5,6,7,8,10],usual:[0,1,3,7,8,10],utf8:[3,9],utf:[1,3,9,10],util:[1,10],valid:8,valu:[0,1,2,3,6,7,8,9,10],vanasco:1,variabl:[1,2,5,6,8,10],variant:[1,8],varieti:[0,6,8],variou:[1,3,6,7,8,9,10],vast:9,vendor:1,veri:[0,1,2,5,9,10],version:[0,2,3,4,5,7,8,9,10],versu:[1,6,10],via:[0,1,2,5,6,7,8,9,10],view:10,viktorin:1,vincent:1,vladimir:1,voix:9,von:1,vou:9,vowel:7,wai:[0,1,2,3,4,5,7,8,9,10],walkthrough:2,want:[0,2,3,5,6,7,8,9],warn:1,wasn:[1,5,7],web:10,wed:1,weight:1,welcom:1,well:[0,1,2,3,5,6,7,8,9,10],were:[1,5,6,7,9],what:[1,2,4,6,7,8,9,10],whatev:[1,6,7,9,10],whatsoev:[1,9],wheel:1,when:[0,1,2,3,5,6,7,8,9,10],whenev:[5,9,10],where:[0,1,2,3,5,6,7,8,9,10],wherea:[2,7,8,9],wherebi:1,wherev:9,whether:[1,3,7,8],which:[0,1,2,3,5,6,7,8,9,10],white:[1,5],whitespac:[1,2,3,8],who:[1,9],whole:[1,2,3,5,6],whoop:1,why:7,wichert:1,wide:1,widget:2,window:1,wise:1,wish:[0,3,7],within:[0,1,3,5,6,7,8,9,10],without:[0,1,5,6,7],won:[5,7,10],wonder:8,word:[5,10],work:[0,1,2,3,5,6,7,9,10],world:[2,6,7,8,9,10],woroshow:1,would:[0,1,2,3,5,7,9,10],wouldn:[6,8],wrap:[1,2,4,8],wrapper:3,write:[1,3,6,7,8,9,10],writer:7,written:[1,5,8,9,10],wsgi:1,wsgiutil:10,x80:9,x99a:9,xa9:9,xa9veil:9,xb4le:9,xc3:9,xe2:9,xie:1,xml:[1,3,8,10],year:[1,9],yes:5,yet:[0,1,6],ymmv:1,you:[0,1,2,3,5,6,7,8,9,10],your:[1,2,3,5,6,7,8],yourself:[9,10],yve:1,zebra:7,zer0:1,zero:1,zhang:1,zimport:1,zzzeek:1},titles:["Caching","Changelog","Defs and Blocks","Filtering and Buffering","Table of Contents","Inheritance","Namespaces","The Mako Runtime Environment","Syntax","The Unicode Chapter","Usage"],titleterms:{"static":6,"true":9,But:5,One:6,The:[3,6,7,8,9],Use:[6,7],Using:[0,2,5,10],about:5,access:0,accessor:7,all:7,api:[0,6,7,10],argument:[0,2,3],attr:6,attribut:5,augment:5,babel:10,backend:0,base:10,basic:10,beaker:0,block:[2,3,5,8],bodi:6,buffer:[3,7,9],bug:1,built:[6,7],cach:0,call:[2,6,8],chang:1,changelog:1,chapter:9,check:10,collect:10,comment:8,common:10,content:[2,4,5],context:[7,8],control:8,cycl:7,declar:6,decor:3,def:[2,3,5,6,8],default_filt:3,defin:9,defnam:8,depend:6,disabl:9,disable_unicod:9,doc:8,dogpil:0,earli:8,embed:2,encod:[9,10],entir:9,environ:7,escap:8,exampl:6,except:10,exit:8,express:[3,8,9],featur:1,file:[2,9,10],filesystem:10,filter:[3,8],framework:10,from:[2,6,8],guidelin:0,handl:[9,10],heck:9,includ:[5,8],indic:4,inherit:[5,6,8],integr:10,iter:7,legaci:7,level:8,local:6,loop:[7,8],mako:7,method:[6,7],migrat:7,misc:1,modul:[6,8],multipl:5,name:[2,5,6,7],namespac:[5,6,8],nest:5,newlin:8,next:5,nsname:8,off:3,older:1,other:2,output:9,page:[2,8],parent:[5,7],plugin:0,produc:5,programmat:[0,2],pygment:10,python:[6,8],refer:[0,6,7,10],regular:6,render:5,reserv:7,rule:9,runtim:7,sai:9,select:9,self:6,set:10,size:10,specif:[0,6],specifi:9,structur:8,substitut:8,syntax:8,tabl:4,tag:8,templat:[5,7,8,9,10],templatelookup:10,text:8,time:5,turn:3,two:6,unicod:[9,10],usag:[6,9,10],using:9,variabl:7,version:[1,6],wai:6,what:5,within:2,word:7,wrap:5,write:0,wsgi:10}}) \ No newline at end of file
diff --git a/third_party/mako/doc/syntax.html b/third_party/mako/doc/syntax.html index b1b95a27..da3bb31 100644 --- a/third_party/mako/doc/syntax.html +++ b/third_party/mako/doc/syntax.html
@@ -12,7 +12,7 @@ Syntax — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Defs and Blocks" href="defs.html" /> <link rel="prev" title="Usage" href="usage.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Syntax @@ -455,7 +455,7 @@ <div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">file=</span><span class="s">"functions.html"</span> <span class="na">import=</span><span class="s">"*"</span><span class="cp">/></span><span class="x"></span></pre></div> </div> <p>The underlying object generated by <code class="docutils literal notranslate"><span class="pre">%namespace</span></code>, an instance of -<a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.runtime.Namespace</span></code></a>, is a central construct used in +<a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><code class="xref py py-class docutils literal notranslate"><span class="pre">Namespace</span></code></a>, is a central construct used in templates to reference template-specific information such as the current URI, inheritance structures, and other things that are not as hard as they sound right here. Namespaces are described @@ -566,7 +566,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -581,7 +581,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -593,7 +593,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/unicode.html b/third_party/mako/doc/unicode.html index a1c208c..fdec1b1c 100644 --- a/third_party/mako/doc/unicode.html +++ b/third_party/mako/doc/unicode.html
@@ -12,7 +12,7 @@ The Unicode Chapter — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Caching" href="caching.html" /> <link rel="prev" title="Filtering and Buffering" href="filtering.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » The Unicode Chapter @@ -156,6 +156,11 @@ <div class="section" id="the-unicode-chapter"> <span id="unicode-toplevel"></span><h1>The Unicode Chapter<a class="headerlink" href="#the-unicode-chapter" title="Permalink to this headline">¶</a></h1> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>this chapter was written many years ago and is very Python-2 +centric. As of Mako 1.1.3, the default template encoding is <code class="docutils literal notranslate"><span class="pre">utf-8</span></code>.</p> +</div> <p>The Python language supports two ways of representing what we know as “strings”, i.e. series of characters. In Python 2, the two types are <code class="docutils literal notranslate"><span class="pre">string</span></code> and <code class="docutils literal notranslate"><span class="pre">unicode</span></code>, and in Python 3 they are @@ -220,7 +225,7 @@ usage of native, unicode strings.</p> <p>In normal Mako operation, all parsed template constructs and output streams are handled internally as Python <code class="docutils literal notranslate"><span class="pre">unicode</span></code> -objects. It’s only at the point of <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> that this unicode +objects. It’s only at the point of <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> that this unicode stream may be rendered into whatever the desired output encoding is. The implication here is that the template developer must :ensure that <a class="reference internal" href="#set-template-file-encoding"><span class="std std-ref">the encoding of all non-ASCII templates is explicit</span></a> (still required in Python 3), @@ -231,28 +236,19 @@ encoding</span></a> (still required in Python 3).</p> <div class="section" id="specifying-the-encoding-of-a-template-file"> <span id="set-template-file-encoding"></span><h2>Specifying the Encoding of a Template File<a class="headerlink" href="#specifying-the-encoding-of-a-template-file" title="Permalink to this headline">¶</a></h2> -<p>This is the most basic encoding-related setting, and it is -equivalent to Python’s “magic encoding comment”, as described in -<a class="reference external" href="http://www.python.org/dev/peps/pep-0263/">pep-0263</a>. Any -template that contains non-ASCII characters requires that this -comment be present so that Mako can decode to unicode (and also -make usage of Python’s AST parsing services). Mako’s lexer will -use this encoding in order to convert the template source into a -<code class="docutils literal notranslate"><span class="pre">unicode</span></code> object before continuing its parsing:</p> +<div class="versionchanged"> +<p><span class="versionmodified changed">Changed in version 1.1.3: </span>As of Mako 1.1.3, the default template encoding is “utf-8”. Previously, a +Python “magic encoding comment” was required for templates that were not +using ASCII.</p> +</div> +<p>Mako templates support Python’s “magic encoding comment” syntax +described in <a class="reference external" href="http://www.python.org/dev/peps/pep-0263/">pep-0263</a>:</p> <div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">## -*- coding: utf-8 -*-</span><span class="x"></span> <span class="x">Alors vous imaginez ma surprise, au lever du jour, quand</span> <span class="x">une drôle de petite voix m’a réveillé. Elle disait:</span> <span class="x"> « S’il vous plaît… dessine-moi un mouton! »</span></pre></div> </div> -<p>For the picky, the regular expression used is derived from that -of the above mentioned pep:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#.*coding[:=]\s*([-\w.]+).*\n</span></pre></div> -</div> -<p>The lexer will convert to unicode in all cases, so that if any -characters exist in the template that are outside of the -specified encoding (or the default of <code class="docutils literal notranslate"><span class="pre">ascii</span></code>), the error will -be immediate.</p> <p>As an alternative, the template encoding can be specified programmatically to either <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> via the <code class="docutils literal notranslate"><span class="pre">input_encoding</span></code> parameter:</p> @@ -270,7 +266,7 @@ <div class="highlight-mako notranslate"><div class="highlight"><pre><span></span><span class="cp">${</span><span class="s2">"hello world"</span><span class="cp">}</span><span class="x"></span></pre></div> </div> <p>looks something like this:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="s2">"hello world"</span><span class="p">))</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">unicode</span><span class="p">(</span><span class="s2">"hello world"</span><span class="p">))</span></pre></div> </div> <p>In Python 3, it’s just:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="s2">"hello world"</span><span class="p">))</span></pre></div> @@ -328,18 +324,18 @@ <span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s1">'/docs'</span><span class="p">],</span> <span class="n">output_encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="n">encoding_errors</span><span class="o">=</span><span class="s1">'replace'</span><span class="p">)</span> <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s2">"foo.txt"</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> -<p><a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> will return a <code class="docutils literal notranslate"><span class="pre">bytes</span></code> object in Python 3 if an output +<p><a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> will return a <code class="docutils literal notranslate"><span class="pre">bytes</span></code> object in Python 3 if an output encoding is specified. By default it performs no encoding and returns a native string.</p> -<p><a class="reference internal" href="usage.html#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render_unicode()</span></code></a> will return the template output as a Python +<p><a class="reference internal" href="usage.html#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render_unicode()</span></code></a> will return the template output as a Python <code class="docutils literal notranslate"><span class="pre">unicode</span></code> object (or <code class="docutils literal notranslate"><span class="pre">string</span></code> in Python 3):</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">())</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">())</span></pre></div> </div> <p>The above method disgards the output encoding keyword argument; you can encode yourself by saying:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="s1">'replace'</span><span class="p">))</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="s1">'replace'</span><span class="p">))</span></pre></div> </div> <div class="section" id="buffer-selection"> <h3>Buffer Selection<a class="headerlink" href="#buffer-selection" title="Permalink to this headline">¶</a></h3> @@ -347,7 +343,7 @@ internally, to maximize performance. Since the buffer is by far the most heavily used object in a render operation, it’s important!</p> -<p>When calling <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> on a template that does not specify any +<p>When calling <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> on a template that does not specify any output encoding (i.e. it’s <code class="docutils literal notranslate"><span class="pre">ascii</span></code>), Python’s <code class="docutils literal notranslate"><span class="pre">cStringIO</span></code> module, which cannot handle encoding of non-ASCII <code class="docutils literal notranslate"><span class="pre">unicode</span></code> objects (even though it can send raw byte-strings through), is used for @@ -373,8 +369,8 @@ <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># -*- coding:utf-8 -*-</span> <span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> -<span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"drôle de petite voix m’a réveillé."</span><span class="p">,</span> <span class="n">disable_unicode</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">input_encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">code</span><span class="p">)</span></pre></div> +<span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"drôle de petite voix m’a réveillé."</span><span class="p">,</span> <span class="n">disable_unicode</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">)</span> +<span class="nb">print</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">code</span><span class="p">)</span></pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">disable_unicode</span></code> mode is strictly a Python 2 thing. It is not supported at all in Python 3.</p> @@ -399,7 +395,7 @@ argument which normally defaults to <code class="docutils literal notranslate"><span class="pre">["unicode"]</span></code> now defaults to <code class="docutils literal notranslate"><span class="pre">["str"]</span></code> instead. Setting <code class="docutils literal notranslate"><span class="pre">default_filters</span></code> to the empty list <code class="docutils literal notranslate"><span class="pre">[]</span></code> can remove the overhead of the <code class="docutils literal notranslate"><span class="pre">str</span></code> call. Also, in this -mode you <strong>cannot</strong> safely call <a class="reference internal" href="usage.html#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render_unicode()</span></code></a> – you’ll get +mode you <strong>cannot</strong> safely call <a class="reference internal" href="usage.html#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render_unicode()</span></code></a> – you’ll get unicode/decode errors.</p> <p>The <code class="docutils literal notranslate"><span class="pre">h</span></code> filter (HTML escape) uses a less performant pure Python escape function in non-unicode mode. This because @@ -437,7 +433,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -452,7 +448,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -464,7 +460,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/doc/usage.html b/third_party/mako/doc/usage.html index 2b70629a..e1a0a6c4 100644 --- a/third_party/mako/doc/usage.html +++ b/third_party/mako/doc/usage.html
@@ -12,7 +12,7 @@ Usage — - Mako 1.0.14 Documentation + Mako 1.1.4 Documentation </title> @@ -32,7 +32,7 @@ <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="top" title="Mako 1.0.14 Documentation" href="index.html" /> + <link rel="top" title="Mako 1.1.4 Documentation" href="index.html" /> <link rel="next" title="Syntax" href="syntax.html" /> <link rel="prev" title="Table of Contents" href="index.html" /> <!-- end layout.mako headers --> @@ -56,7 +56,7 @@ <div id="docs-header"> - <h1>Mako 1.0.14 Documentation</h1> + <h1>Mako 1.1.4 Documentation</h1> <div id="docs-search"> Search: @@ -68,7 +68,7 @@ </div> <div id="docs-version-header"> - Release: <span class="version-num">1.0.14</span> + Release: <span class="version-num">1.1.4</span> </div> @@ -92,7 +92,7 @@ </div> <div id="docs-navigation-banner"> - <a href="index.html">Mako 1.0.14 Documentation</a> + <a href="index.html">Mako 1.1.4 Documentation</a> » Usage @@ -173,7 +173,7 @@ <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"hello world!"</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> <p>Above, the text argument to <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> is <strong>compiled</strong> into a Python module representation. This module contains a function @@ -184,27 +184,27 @@ returning its string contents.</p> <p>The code inside the <code class="docutils literal notranslate"><span class="pre">render_body()</span></code> function has access to a namespace of variables. You can specify these variables by -sending them as additional keyword arguments to the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> +sending them as additional keyword arguments to the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> method:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> -<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"hello, ${name}!"</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"jack"</span><span class="p">))</span></pre></div> +<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"hello, $</span><span class="si">{name}</span><span class="s2">!"</span><span class="p">)</span> +<span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"jack"</span><span class="p">))</span></pre></div> </div> -<p>The <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> method calls upon Mako to create a +<p>The <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> method calls upon Mako to create a <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> object, which stores all the variable names accessible to the template and also stores a buffer used to capture output. You can create this <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> yourself and have the template -render with it, using the <a class="reference internal" href="#mako.template.Template.render_context" title="mako.template.Template.render_context"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render_context()</span></code></a> method:</p> +render with it, using the <a class="reference internal" href="#mako.template.Template.render_context" title="mako.template.Template.render_context"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render_context()</span></code></a> method:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> <span class="kn">from</span> <span class="nn">mako.runtime</span> <span class="kn">import</span> <span class="n">Context</span> <span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span> -<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"hello, ${name}!"</span><span class="p">)</span> +<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">"hello, $</span><span class="si">{name}</span><span class="s2">!"</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span> <span class="n">ctx</span> <span class="o">=</span> <span class="n">Context</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">"jack"</span><span class="p">)</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_context</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">buf</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span></pre></div> </div> </div> <div class="section" id="using-file-based-templates"> @@ -214,7 +214,7 @@ <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s1">'/docs/mytmpl.txt'</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> <p>For improved performance, a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> which is loaded from a file can also cache the source code to its generated module on @@ -224,7 +224,7 @@ <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s1">'/docs/mytmpl.txt'</span><span class="p">,</span> <span class="n">module_directory</span><span class="o">=</span><span class="s1">'/tmp/mako_modules'</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> <p>When the above code is rendered, a file <code class="docutils literal notranslate"><span class="pre">/tmp/mako_modules/docs/mytmpl.txt.py</span></code> is created containing the @@ -258,7 +258,7 @@ have been a little bit contrived in order to illustrate the basic concepts. But a real application would get most or all of its templates directly from the <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a>, using the -aptly named <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_template()</span></code></a> method, which accepts the URI of the +aptly named <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TemplateLookup.get_template()</span></code></a> method, which accepts the URI of the desired template:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span> <span class="kn">from</span> <span class="nn">mako.lookup</span> <span class="kn">import</span> <span class="n">TemplateLookup</span> @@ -267,7 +267,7 @@ <span class="k">def</span> <span class="nf">serve_template</span><span class="p">(</span><span class="n">templatename</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">templatename</span><span class="p">)</span> - <span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">))</span></pre></div> + <span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">))</span></pre></div> </div> <p>In the example above, we create a <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> which will look for templates in the <code class="docutils literal notranslate"><span class="pre">/docs</span></code> directory, and will store @@ -279,7 +279,7 @@ exception, which is a custom Mako exception.</p> <p>When the lookup locates templates, it will also assign a <code class="docutils literal notranslate"><span class="pre">uri</span></code> property to the <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> which is the URI passed to the -<a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_template()</span></code></a> call. <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> uses this URI to calculate the +<a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TemplateLookup.get_template()</span></code></a> call. <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> uses this URI to calculate the name of its module file. So in the above example, a <code class="docutils literal notranslate"><span class="pre">templatename</span></code> argument of <code class="docutils literal notranslate"><span class="pre">/etc/beans/info.txt</span></code> will create a module file <code class="docutils literal notranslate"><span class="pre">/tmp/mako_modules/etc/beans/info.txt.py</span></code>.</p> @@ -303,7 +303,7 @@ <h3>Setting Filesystem Checks<a class="headerlink" href="#setting-filesystem-checks" title="Permalink to this headline">¶</a></h3> <p>Another important flag on <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> is <code class="docutils literal notranslate"><span class="pre">filesystem_checks</span></code>. This defaults to <code class="docutils literal notranslate"><span class="pre">True</span></code>, and says that each -time a template is returned by the <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_template()</span></code></a> method, the +time a template is returned by the <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TemplateLookup.get_template()</span></code></a> method, the revision time of the original template file is checked against the last time the template was loaded, and if the file is newer will reload its contents and recompile the template. On a @@ -323,19 +323,19 @@ <span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s1">'/docs'</span><span class="p">],</span> <span class="n">output_encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="n">encoding_errors</span><span class="o">=</span><span class="s1">'replace'</span><span class="p">)</span> <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s2">"foo.txt"</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> +<span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> -<p>When using Python 3, the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> method will return a <code class="docutils literal notranslate"><span class="pre">bytes</span></code> +<p>When using Python 3, the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render()</span></code></a> method will return a <code class="docutils literal notranslate"><span class="pre">bytes</span></code> object, <strong>if</strong> <code class="docutils literal notranslate"><span class="pre">output_encoding</span></code> is set. Otherwise it returns a <code class="docutils literal notranslate"><span class="pre">string</span></code>.</p> -<p>Additionally, the <a class="reference internal" href="#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render_unicode()</span></code></a> method exists which will +<p>Additionally, the <a class="reference internal" href="#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Template.render_unicode()</span></code></a> method exists which will return the template output as a Python <code class="docutils literal notranslate"><span class="pre">unicode</span></code> object, or in Python 3 a <code class="docutils literal notranslate"><span class="pre">string</span></code>:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">())</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">())</span></pre></div> </div> <p>The above method disregards the output encoding keyword argument; you can encode yourself by saying:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="s1">'replace'</span><span class="p">))</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="s1">'replace'</span><span class="p">))</span></pre></div> </div> <p>Note that Mako’s ability to return data in any encoding and/or <code class="docutils literal notranslate"><span class="pre">unicode</span></code> implies that the underlying output stream of the @@ -367,33 +367,33 @@ <span class="k">try</span><span class="p">:</span> <span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span> - <span class="k">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span> + <span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span> <span class="k">except</span><span class="p">:</span> - <span class="k">print</span><span class="p">(</span><span class="n">exceptions</span><span class="o">.</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> + <span class="nb">print</span><span class="p">(</span><span class="n">exceptions</span><span class="o">.</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> <p>Or for the HTML render function:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">mako</span> <span class="kn">import</span> <span class="n">exceptions</span> <span class="k">try</span><span class="p">:</span> <span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span> - <span class="k">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span> + <span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span> <span class="k">except</span><span class="p">:</span> - <span class="k">print</span><span class="p">(</span><span class="n">exceptions</span><span class="o">.</span><span class="n">html_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> + <span class="nb">print</span><span class="p">(</span><span class="n">exceptions</span><span class="o">.</span><span class="n">html_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> <p>The <a class="reference internal" href="#mako.exceptions.html_error_template" title="mako.exceptions.html_error_template"><code class="xref py py-func docutils literal notranslate"><span class="pre">html_error_template()</span></code></a> template accepts two options: specifying <code class="docutils literal notranslate"><span class="pre">full=False</span></code> causes only a section of an HTML document to be rendered. Specifying <code class="docutils literal notranslate"><span class="pre">css=False</span></code> will disable the default stylesheet from being rendered.</p> <p>E.g.:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="n">exceptions</span><span class="o">.</span><span class="n">html_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">full</span><span class="o">=</span><span class="bp">False</span><span class="p">))</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">exceptions</span><span class="o">.</span><span class="n">html_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">full</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span></pre></div> </div> <p>The HTML render function is also available built-in to <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> using the <code class="docutils literal notranslate"><span class="pre">format_exceptions</span></code> flag. In this case, any exceptions raised within the <strong>render</strong> stage of the template will result in the output being substituted with the output of <a class="reference internal" href="#mako.exceptions.html_error_template" title="mako.exceptions.html_error_template"><code class="xref py py-func docutils literal notranslate"><span class="pre">html_error_template()</span></code></a>:</p> -<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s2">"/foo/bar"</span><span class="p">,</span> <span class="n">format_exceptions</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> -<span class="k">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> +<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s2">"/foo/bar"</span><span class="p">,</span> <span class="n">format_exceptions</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> +<span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span></pre></div> </div> <p>Note that the compile stage of the above template occurs when you construct the <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> itself, and no output stream is @@ -413,13 +413,13 @@ <span class="k">try</span><span class="p">:</span> <span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span> - <span class="k">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span> + <span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">())</span> <span class="k">except</span><span class="p">:</span> <span class="n">traceback</span> <span class="o">=</span> <span class="n">RichTraceback</span><span class="p">()</span> <span class="k">for</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span> <span class="ow">in</span> <span class="n">traceback</span><span class="o">.</span><span class="n">traceback</span><span class="p">:</span> - <span class="k">print</span><span class="p">(</span><span class="s2">"File </span><span class="si">%s</span><span class="s2">, line </span><span class="si">%s</span><span class="s2">, in </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">))</span> - <span class="k">print</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span> - <span class="k">print</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">traceback</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">),</span> <span class="n">traceback</span><span class="o">.</span><span class="n">error</span><span class="p">))</span></pre></div> + <span class="nb">print</span><span class="p">(</span><span class="s2">"File </span><span class="si">%s</span><span class="s2">, line </span><span class="si">%s</span><span class="s2">, in </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">))</span> + <span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span> + <span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">traceback</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">),</span> <span class="n">traceback</span><span class="o">.</span><span class="n">error</span><span class="p">))</span></pre></div> </div> </div> <div class="section" id="common-framework-integrations"> @@ -441,7 +441,7 @@ </div> <div class="section" id="pygments"> <h3>Pygments<a class="headerlink" href="#pygments" title="Permalink to this headline">¶</a></h3> -<p>A <a class="reference external" href="http://pygments.pocoo.org">Pygments</a>-compatible syntax +<p>A <a class="reference external" href="https://pygments.org/">Pygments</a>-compatible syntax highlighting module is included under <code class="xref py py-mod docutils literal notranslate"><span class="pre">mako.ext.pygmentplugin</span></code>. This module is used in the generation of Mako documentation and also contains various <cite>setuptools</cite> entry points under the heading @@ -518,15 +518,55 @@ </div> <div class="section" id="api-reference"> <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2> -<dl class="class"> +<table class="longtable docutils"> +<colgroup> +<col style="width: 10%" /> +<col style="width: 90%" /> +</colgroup> +<thead> +<tr class="row-odd"><th class="head">Object Name</th> +<th class="head">Description</th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.template.DefTemplate"><code class="sig-name descname">DefTemplate</code></a></p></td> +<td><p>Bases: <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.template.Template</span></code></a></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.exceptions.html_error_template"><code class="sig-name descname">html_error_template</code></a>()</p></td> +<td><p>Provides a template that renders a stack trace in an HTML format, +providing an excerpt of code as well as substituting source template +filenames, line numbers and code for that of the originating source +template, as applicable.</p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="sig-name descname">RichTraceback</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.template.Template"><code class="sig-name descname">Template</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.lookup.TemplateCollection"><code class="sig-name descname">TemplateCollection</code></a></p></td> +<td><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p></td> +</tr> +<tr class="row-odd"><td class="nowrap"><p><a class="reference internal" href="#mako.lookup.TemplateLookup"><code class="sig-name descname">TemplateLookup</code></a></p></td> +<td><p>Bases: <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection</span></code></a></p></td> +</tr> +<tr class="row-even"><td class="nowrap"><p><a class="reference internal" href="#mako.exceptions.text_error_template"><code class="sig-name descname">text_error_template</code></a>([lookup])</p></td> +<td><p>Provides a template that renders a stack trace in a similar format to +the Python interpreter, substituting source template filenames, line +numbers and code for that of the originating source template, as +applicable.</p></td> +</tr> +</tbody> +</table> +<dl class="py class"> <dt id="mako.template.Template"> -<em class="property">class </em><code class="sig-prename descclassname">mako.template.</code><code class="sig-name descname">Template</code><span class="sig-paren">(</span><em class="sig-param">text=None</em>, <em class="sig-param">filename=None</em>, <em class="sig-param">uri=None</em>, <em class="sig-param">format_exceptions=False</em>, <em class="sig-param">error_handler=None</em>, <em class="sig-param">lookup=None</em>, <em class="sig-param">output_encoding=None</em>, <em class="sig-param">encoding_errors='strict'</em>, <em class="sig-param">module_directory=None</em>, <em class="sig-param">cache_args=None</em>, <em class="sig-param">cache_impl='beaker'</em>, <em class="sig-param">cache_enabled=True</em>, <em class="sig-param">cache_type=None</em>, <em class="sig-param">cache_dir=None</em>, <em class="sig-param">cache_url=None</em>, <em class="sig-param">module_filename=None</em>, <em class="sig-param">input_encoding=None</em>, <em class="sig-param">disable_unicode=False</em>, <em class="sig-param">module_writer=None</em>, <em class="sig-param">bytestring_passthrough=False</em>, <em class="sig-param">default_filters=None</em>, <em class="sig-param">buffer_filters=()</em>, <em class="sig-param">strict_undefined=False</em>, <em class="sig-param">imports=None</em>, <em class="sig-param">future_imports=None</em>, <em class="sig-param">enable_loop=True</em>, <em class="sig-param">preprocessor=None</em>, <em class="sig-param">lexer_cls=None</em>, <em class="sig-param">include_error_handler=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.template.</code><code class="sig-name descname">Template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">text</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">filename</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">uri</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">format_exceptions</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">error_handler</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">lookup</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">output_encoding</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">encoding_errors</span><span class="o">=</span><span class="default_value">'strict'</span></em>, <em class="sig-param"><span class="n">module_directory</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_args</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_impl</span><span class="o">=</span><span class="default_value">'beaker'</span></em>, <em class="sig-param"><span class="n">cache_enabled</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">cache_type</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_dir</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_url</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">module_filename</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">input_encoding</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">disable_unicode</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">module_writer</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">bytestring_passthrough</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">default_filters</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">buffer_filters</span><span class="o">=</span><span class="default_value">()</span></em>, <em class="sig-param"><span class="n">strict_undefined</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">imports</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">future_imports</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">enable_loop</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">preprocessor</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">lexer_cls</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">include_error_handler</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>Represents a compiled template.</p> <p><a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> includes a reference to the original -template source (via the <a class="reference internal" href="#mako.exceptions.RichTraceback.source" title="mako.exceptions.RichTraceback.source"><code class="xref py py-attr docutils literal notranslate"><span class="pre">source</span></code></a> attribute) +template source (via the <a class="reference internal" href="#mako.template.Template.source" title="mako.template.Template.source"><code class="xref py py-attr docutils literal notranslate"><span class="pre">source</span></code></a> attribute) as well as the source code of the -generated Python module (i.e. the <code class="xref py py-attr docutils literal notranslate"><span class="pre">code</span></code> attribute), +generated Python module (i.e. the <a class="reference internal" href="#mako.template.Template.code" title="mako.template.Template.code"><code class="xref py py-attr docutils literal notranslate"><span class="pre">code</span></code></a> attribute), as well as a reference to an actual Python module.</p> <p><a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> is constructed using either a literal string representing the template text, or a filename representing a filesystem @@ -707,30 +747,30 @@ </ul> </dd> </dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.template.Template.code"> -<em class="property">property </em><code class="sig-name descname">code</code><a class="headerlink" href="#mako.template.Template.code" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">code</code><a class="headerlink" href="#mako.template.Template.code" title="Permalink to this definition">¶</a></dt> <dd><p>Return the module source code for this <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.template.Template.get_def"> -<code class="sig-name descname">get_def</code><span class="sig-paren">(</span><em class="sig-param">name</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.get_def" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">get_def</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.get_def" title="Permalink to this definition">¶</a></dt> <dd><p>Return a def of this template as a <a class="reference internal" href="#mako.template.DefTemplate" title="mako.template.DefTemplate"><code class="xref py py-class docutils literal notranslate"><span class="pre">DefTemplate</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.template.Template.list_defs"> -<code class="sig-name descname">list_defs</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.list_defs" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">list_defs</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.list_defs" title="Permalink to this definition">¶</a></dt> <dd><p>return a list of defs in the template.</p> <div class="versionadded"> <p><span class="versionmodified added">New in version 1.0.4.</span></p> </div> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.template.Template.render"> -<code class="sig-name descname">render</code><span class="sig-paren">(</span><em class="sig-param">*args</em>, <em class="sig-param">**data</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.render" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">render</code><span class="sig-paren">(</span><em class="sig-param"><span class="o">*</span><span class="n">args</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">data</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.render" title="Permalink to this definition">¶</a></dt> <dd><p>Render the output of this template as a string.</p> <p>If the template specifies an output encoding, the string will be encoded accordingly, else the output is raw (raw @@ -741,43 +781,46 @@ pulled from the given <code class="docutils literal notranslate"><span class="pre">*args</span></code>, <code class="docutils literal notranslate"><span class="pre">**data</span></code> members.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.template.Template.render_context"> -<code class="sig-name descname">render_context</code><span class="sig-paren">(</span><em class="sig-param">context</em>, <em class="sig-param">*args</em>, <em class="sig-param">**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.render_context" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">render_context</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">context</span></em>, <em class="sig-param"><span class="o">*</span><span class="n">args</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">kwargs</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.render_context" title="Permalink to this definition">¶</a></dt> <dd><p>Render this <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> with the given context.</p> <p>The data is written to the context’s buffer.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.template.Template.render_unicode"> -<code class="sig-name descname">render_unicode</code><span class="sig-paren">(</span><em class="sig-param">*args</em>, <em class="sig-param">**data</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.render_unicode" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">render_unicode</code><span class="sig-paren">(</span><em class="sig-param"><span class="o">*</span><span class="n">args</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">data</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.Template.render_unicode" title="Permalink to this definition">¶</a></dt> <dd><p>Render the output of this template as a unicode object.</p> </dd></dl> -<dl class="method"> +<dl class="py attribute"> <dt id="mako.template.Template.source"> -<em class="property">property </em><code class="sig-name descname">source</code><a class="headerlink" href="#mako.template.Template.source" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.template.Template"><code class="docutils literal notranslate"><span class="pre">mako.template.Template.</span></code></a><code class="sig-name descname">source</code><a class="headerlink" href="#mako.template.Template.source" title="Permalink to this definition">¶</a></dt> <dd><p>Return the template source code for this <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>.</p> </dd></dl> </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.template.DefTemplate"> -<em class="property">class </em><code class="sig-prename descclassname">mako.template.</code><code class="sig-name descname">DefTemplate</code><span class="sig-paren">(</span><em class="sig-param">parent</em>, <em class="sig-param">callable_</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.DefTemplate" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.template.</code><code class="sig-name descname">DefTemplate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">parent</span></em>, <em class="sig-param"><span class="n">callable_</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.DefTemplate" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.template.Template</span></code></a></p> -<p>Bases: <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.template.Template</span></code></a></p> <p>A <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> which represents a callable def in a parent template.</p> -<dl class="method"> +<div class="class-bases docutils container"> +<p><strong>Class signature</strong></p> +<p>class <a class="reference internal" href="#mako.template.DefTemplate" title="mako.template.DefTemplate"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.template.DefTemplate</span></code></a> (<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.template.Template</span></code></a>)</p> +</div> +<dl class="py method"> <dt id="mako.template.DefTemplate.get_def"> -<code class="sig-name descname">get_def</code><span class="sig-paren">(</span><em class="sig-param">name</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.DefTemplate.get_def" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.template.DefTemplate"><code class="docutils literal notranslate"><span class="pre">mako.template.DefTemplate.</span></code></a><code class="sig-name descname">get_def</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.template.DefTemplate.get_def" title="Permalink to this definition">¶</a></dt> <dd><p>Return a def of this template as a <a class="reference internal" href="#mako.template.DefTemplate" title="mako.template.DefTemplate"><code class="xref py py-class docutils literal notranslate"><span class="pre">DefTemplate</span></code></a>.</p> </dd></dl> </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.lookup.TemplateCollection"> <em class="property">class </em><code class="sig-prename descclassname">mako.lookup.</code><code class="sig-name descname">TemplateCollection</code><a class="headerlink" href="#mako.lookup.TemplateCollection" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> @@ -791,9 +834,9 @@ object’s <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateCollection</span></code></a> for resolution.</p> <p><a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateCollection</span></code></a> is an abstract class, with the usual default implementation being <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a>.</p> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateCollection.adjust_uri"> -<code class="sig-name descname">adjust_uri</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">filename</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.adjust_uri" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateCollection"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection.</span></code></a><code class="sig-name descname">adjust_uri</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="n">filename</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.adjust_uri" title="Permalink to this definition">¶</a></dt> <dd><p>Adjust the given <code class="docutils literal notranslate"><span class="pre">uri</span></code> based on the calling <code class="docutils literal notranslate"><span class="pre">filename</span></code>.</p> <p>When this method is called from the runtime, the <code class="docutils literal notranslate"><span class="pre">filename</span></code> parameter is taken directly to the <code class="docutils literal notranslate"><span class="pre">filename</span></code> @@ -804,16 +847,16 @@ here.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateCollection.filename_to_uri"> -<code class="sig-name descname">filename_to_uri</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">filename</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.filename_to_uri" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateCollection"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection.</span></code></a><code class="sig-name descname">filename_to_uri</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="n">filename</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.filename_to_uri" title="Permalink to this definition">¶</a></dt> <dd><p>Convert the given <code class="docutils literal notranslate"><span class="pre">filename</span></code> to a URI relative to this <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateCollection</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateCollection.get_template"> -<code class="sig-name descname">get_template</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">relativeto=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.get_template" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateCollection"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection.</span></code></a><code class="sig-name descname">get_template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="n">relativeto</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.get_template" title="Permalink to this definition">¶</a></dt> <dd><p>Return a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object corresponding to the given <code class="docutils literal notranslate"><span class="pre">uri</span></code>.</p> <p>The default implementation raises @@ -831,9 +874,9 @@ </dl> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateCollection.has_template"> -<code class="sig-name descname">has_template</code><span class="sig-paren">(</span><em class="sig-param">uri</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.has_template" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateCollection"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection.</span></code></a><code class="sig-name descname">has_template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateCollection.has_template" title="Permalink to this definition">¶</a></dt> <dd><p>Return <code class="docutils literal notranslate"><span class="pre">True</span></code> if this <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> is capable of returning a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object for the given <code class="docutils literal notranslate"><span class="pre">uri</span></code>.</p> @@ -846,11 +889,10 @@ </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.lookup.TemplateLookup"> -<em class="property">class </em><code class="sig-prename descclassname">mako.lookup.</code><code class="sig-name descname">TemplateLookup</code><span class="sig-paren">(</span><em class="sig-param">directories=None</em>, <em class="sig-param">module_directory=None</em>, <em class="sig-param">filesystem_checks=True</em>, <em class="sig-param">collection_size=-1</em>, <em class="sig-param">format_exceptions=False</em>, <em class="sig-param">error_handler=None</em>, <em class="sig-param">disable_unicode=False</em>, <em class="sig-param">bytestring_passthrough=False</em>, <em class="sig-param">output_encoding=None</em>, <em class="sig-param">encoding_errors='strict'</em>, <em class="sig-param">cache_args=None</em>, <em class="sig-param">cache_impl='beaker'</em>, <em class="sig-param">cache_enabled=True</em>, <em class="sig-param">cache_type=None</em>, <em class="sig-param">cache_dir=None</em>, <em class="sig-param">cache_url=None</em>, <em class="sig-param">modulename_callable=None</em>, <em class="sig-param">module_writer=None</em>, <em class="sig-param">default_filters=None</em>, <em class="sig-param">buffer_filters=()</em>, <em class="sig-param">strict_undefined=False</em>, <em class="sig-param">imports=None</em>, <em class="sig-param">future_imports=None</em>, <em class="sig-param">enable_loop=True</em>, <em class="sig-param">input_encoding=None</em>, <em class="sig-param">preprocessor=None</em>, <em class="sig-param">lexer_cls=None</em>, <em class="sig-param">include_error_handler=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.lookup.</code><code class="sig-name descname">TemplateLookup</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">directories</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">module_directory</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">filesystem_checks</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">collection_size</span><span class="o">=</span><span class="default_value">- 1</span></em>, <em class="sig-param"><span class="n">format_exceptions</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">error_handler</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">disable_unicode</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">bytestring_passthrough</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">output_encoding</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">encoding_errors</span><span class="o">=</span><span class="default_value">'strict'</span></em>, <em class="sig-param"><span class="n">cache_args</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_impl</span><span class="o">=</span><span class="default_value">'beaker'</span></em>, <em class="sig-param"><span class="n">cache_enabled</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">cache_type</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_dir</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">cache_url</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">modulename_callable</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">module_writer</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">default_filters</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">buffer_filters</span><span class="o">=</span><span class="default_value">()</span></em>, <em class="sig-param"><span class="n">strict_undefined</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">imports</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">future_imports</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">enable_loop</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">input_encoding</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">preprocessor</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">lexer_cls</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">include_error_handler</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection</span></code></a></p> -<p>Bases: <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection</span></code></a></p> <p>Represent a collection of templates that locates template source files from the local filesystem.</p> <p>The primary argument is the <code class="docutils literal notranslate"><span class="pre">directories</span></code> argument, the list of @@ -906,22 +948,26 @@ <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> objects are created, the keywords established with this <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a> are passed on to each new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>.</p> -<dl class="method"> +<div class="class-bases docutils container"> +<p><strong>Class signature</strong></p> +<p>class <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.lookup.TemplateLookup</span></code></a> (<a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">mako.lookup.TemplateCollection</span></code></a>)</p> +</div> +<dl class="py method"> <dt id="mako.lookup.TemplateLookup.adjust_uri"> -<code class="sig-name descname">adjust_uri</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">relativeto</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.adjust_uri" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateLookup"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateLookup.</span></code></a><code class="sig-name descname">adjust_uri</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="n">relativeto</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.adjust_uri" title="Permalink to this definition">¶</a></dt> <dd><p>Adjust the given <code class="docutils literal notranslate"><span class="pre">uri</span></code> based on the given relative URI.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateLookup.filename_to_uri"> -<code class="sig-name descname">filename_to_uri</code><span class="sig-paren">(</span><em class="sig-param">filename</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.filename_to_uri" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateLookup"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateLookup.</span></code></a><code class="sig-name descname">filename_to_uri</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">filename</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.filename_to_uri" title="Permalink to this definition">¶</a></dt> <dd><p>Convert the given <code class="docutils literal notranslate"><span class="pre">filename</span></code> to a URI relative to this <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateCollection</span></code></a>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateLookup.get_template"> -<code class="sig-name descname">get_template</code><span class="sig-paren">(</span><em class="sig-param">uri</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.get_template" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateLookup"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateLookup.</span></code></a><code class="sig-name descname">get_template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.get_template" title="Permalink to this definition">¶</a></dt> <dd><p>Return a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object corresponding to the given <code class="docutils literal notranslate"><span class="pre">uri</span></code>.</p> <div class="admonition note"> @@ -931,17 +977,17 @@ </div> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateLookup.put_string"> -<code class="sig-name descname">put_string</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">text</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.put_string" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateLookup"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateLookup.</span></code></a><code class="sig-name descname">put_string</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="n">text</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.put_string" title="Permalink to this definition">¶</a></dt> <dd><p>Place a new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object into this <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a>, based on the given string of <code class="docutils literal notranslate"><span class="pre">text</span></code>.</p> </dd></dl> -<dl class="method"> +<dl class="py method"> <dt id="mako.lookup.TemplateLookup.put_template"> -<code class="sig-name descname">put_template</code><span class="sig-paren">(</span><em class="sig-param">uri</em>, <em class="sig-param">template</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.put_template" title="Permalink to this definition">¶</a></dt> +<em class="property">method </em><a class="reference internal" href="#mako.lookup.TemplateLookup"><code class="docutils literal notranslate"><span class="pre">mako.lookup.TemplateLookup.</span></code></a><code class="sig-name descname">put_template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">uri</span></em>, <em class="sig-param"><span class="n">template</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.lookup.TemplateLookup.put_template" title="Permalink to this definition">¶</a></dt> <dd><p>Place a new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object into this <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateLookup</span></code></a>, based on the given <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> object.</p> @@ -949,44 +995,44 @@ </dd></dl> -<dl class="class"> +<dl class="py class"> <dt id="mako.exceptions.RichTraceback"> -<em class="property">class </em><code class="sig-prename descclassname">mako.exceptions.</code><code class="sig-name descname">RichTraceback</code><span class="sig-paren">(</span><em class="sig-param">error=None</em>, <em class="sig-param">traceback=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.exceptions.RichTraceback" title="Permalink to this definition">¶</a></dt> +<em class="property">class </em><code class="sig-prename descclassname">mako.exceptions.</code><code class="sig-name descname">RichTraceback</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">error</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">traceback</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.exceptions.RichTraceback" title="Permalink to this definition">¶</a></dt> <dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> <p>Pull the current exception from the <code class="docutils literal notranslate"><span class="pre">sys</span></code> traceback and extracts Mako-specific template information.</p> <p>See the usage examples in <a class="reference internal" href="#handling-exceptions"><span class="std std-ref">Handling Exceptions</span></a>.</p> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.error"> -<code class="sig-name descname">error</code><a class="headerlink" href="#mako.exceptions.RichTraceback.error" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">error</code><a class="headerlink" href="#mako.exceptions.RichTraceback.error" title="Permalink to this definition">¶</a></dt> <dd><p>the exception instance.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.message"> -<code class="sig-name descname">message</code><a class="headerlink" href="#mako.exceptions.RichTraceback.message" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">message</code><a class="headerlink" href="#mako.exceptions.RichTraceback.message" title="Permalink to this definition">¶</a></dt> <dd><p>the exception error message as unicode.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.source"> -<code class="sig-name descname">source</code><a class="headerlink" href="#mako.exceptions.RichTraceback.source" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">source</code><a class="headerlink" href="#mako.exceptions.RichTraceback.source" title="Permalink to this definition">¶</a></dt> <dd><p>source code of the file where the error occurred. If the error occurred within a compiled template, this is the template source.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.lineno"> -<code class="sig-name descname">lineno</code><a class="headerlink" href="#mako.exceptions.RichTraceback.lineno" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">lineno</code><a class="headerlink" href="#mako.exceptions.RichTraceback.lineno" title="Permalink to this definition">¶</a></dt> <dd><p>line number where the error occurred. If the error occurred within a compiled template, the line number is adjusted to that of the template source.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.records"> -<code class="sig-name descname">records</code><a class="headerlink" href="#mako.exceptions.RichTraceback.records" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">records</code><a class="headerlink" href="#mako.exceptions.RichTraceback.records" title="Permalink to this definition">¶</a></dt> <dd><p>a list of 8-tuples containing the original python traceback elements, plus the filename, line number, source line, and full template source @@ -994,26 +1040,26 @@ template, if any for that traceline (else the fields are <code class="docutils literal notranslate"><span class="pre">None</span></code>).</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.reverse_records"> -<code class="sig-name descname">reverse_records</code><a class="headerlink" href="#mako.exceptions.RichTraceback.reverse_records" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">reverse_records</code><a class="headerlink" href="#mako.exceptions.RichTraceback.reverse_records" title="Permalink to this definition">¶</a></dt> <dd><p>the list of records in reverse traceback – a list of 4-tuples, in the same format as a regular python traceback, with template-corresponding traceback records replacing the originals.</p> </dd></dl> -<dl class="attribute"> +<dl class="py attribute"> <dt id="mako.exceptions.RichTraceback.reverse_traceback"> -<code class="sig-name descname">reverse_traceback</code><a class="headerlink" href="#mako.exceptions.RichTraceback.reverse_traceback" title="Permalink to this definition">¶</a></dt> +<em class="property">attribute </em><a class="reference internal" href="#mako.exceptions.RichTraceback"><code class="docutils literal notranslate"><span class="pre">mako.exceptions.RichTraceback.</span></code></a><code class="sig-name descname">reverse_traceback</code><a class="headerlink" href="#mako.exceptions.RichTraceback.reverse_traceback" title="Permalink to this definition">¶</a></dt> <dd><p>the traceback list in reverse.</p> </dd></dl> </dd></dl> -<dl class="function"> +<dl class="py function"> <dt id="mako.exceptions.html_error_template"> -<code class="sig-prename descclassname">mako.exceptions.</code><code class="sig-name descname">html_error_template</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.exceptions.html_error_template" title="Permalink to this definition">¶</a></dt> +<em class="property">function </em><code class="sig-prename descclassname">mako.exceptions.</code><code class="sig-name descname">html_error_template</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#mako.exceptions.html_error_template" title="Permalink to this definition">¶</a></dt> <dd><p>Provides a template that renders a stack trace in an HTML format, providing an excerpt of code as well as substituting source template filenames, line numbers and code for that of the originating source @@ -1025,9 +1071,9 @@ won’t be included.</p> </dd></dl> -<dl class="function"> +<dl class="py function"> <dt id="mako.exceptions.text_error_template"> -<code class="sig-prename descclassname">mako.exceptions.</code><code class="sig-name descname">text_error_template</code><span class="sig-paren">(</span><em class="sig-param">lookup=None</em><span class="sig-paren">)</span><a class="headerlink" href="#mako.exceptions.text_error_template" title="Permalink to this definition">¶</a></dt> +<em class="property">function </em><code class="sig-prename descclassname">mako.exceptions.</code><code class="sig-name descname">text_error_template</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lookup</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#mako.exceptions.text_error_template" title="Permalink to this definition">¶</a></dt> <dd><p>Provides a template that renders a stack trace in a similar format to the Python interpreter, substituting source template filenames, line numbers and code for that of the originating source template, as @@ -1049,7 +1095,7 @@ <div id="docs-copyright"> © Copyright the Mako authors and contributors. - Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2 + Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 3.4.3 with Mako templates. </div> </div> @@ -1064,7 +1110,7 @@ <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', - VERSION: '1.0.14', + VERSION: '1.1.4', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html' }; @@ -1076,7 +1122,6 @@ <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> - <script type="text/javascript" src="_static/language_data.js"></script> <!-- end iterate through sphinx environment script_files --> <script type="text/javascript" src="_static/detectmobile.js"></script>
diff --git a/third_party/mako/mako/__init__.py b/third_party/mako/mako/__init__.py index 61c9d026..bd1a1c9 100644 --- a/third_party/mako/mako/__init__.py +++ b/third_party/mako/mako/__init__.py
@@ -1,8 +1,8 @@ # mako/__init__.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -__version__ = '1.0.14' +__version__ = '1.1.4'
diff --git a/third_party/mako/mako/_ast_util.py b/third_party/mako/mako/_ast_util.py index 74c0851..bdcdbf6 100644 --- a/third_party/mako/mako/_ast_util.py +++ b/third_party/mako/mako/_ast_util.py
@@ -1,5 +1,5 @@ # mako/_ast_util.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/ast.py b/third_party/mako/mako/ast.py index 8f2cf2e..cfae280 100644 --- a/third_party/mako/mako/ast.py +++ b/third_party/mako/mako/ast.py
@@ -1,5 +1,5 @@ # mako/ast.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/cache.py b/third_party/mako/mako/cache.py index b68b74f..26aa93e 100644 --- a/third_party/mako/mako/cache.py +++ b/third_party/mako/mako/cache.py
@@ -1,5 +1,5 @@ # mako/cache.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/cmd.py b/third_party/mako/mako/cmd.py index 5d52dfb..c0f2c75 100644 --- a/third_party/mako/mako/cmd.py +++ b/third_party/mako/mako/cmd.py
@@ -1,9 +1,10 @@ # mako/cmd.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php from argparse import ArgumentParser +import io from os.path import dirname from os.path import isfile import sys @@ -46,11 +47,17 @@ parser.add_argument( "--output-encoding", default=None, help="force output encoding" ) + parser.add_argument( + "--output-file", + default=None, + help="Write to file upon successful render instead of stdout", + ) parser.add_argument("input", nargs="?", default="-") options = parser.parse_args(argv) output_encoding = options.output_encoding + output_file = options.output_file if options.input == "-": lookup_dirs = options.template_dir or ["."] @@ -80,9 +87,16 @@ kw = dict([varsplit(var) for var in options.var]) try: - sys.stdout.write(template.render(**kw)) + rendered = template.render(**kw) except: _exit() + else: + if output_file: + io.open(output_file, "wt", encoding=output_encoding).write( + rendered + ) + else: + sys.stdout.write(rendered) if __name__ == "__main__":
diff --git a/third_party/mako/mako/codegen.py b/third_party/mako/mako/codegen.py index 5ca7b041..a9ae55b 100644 --- a/third_party/mako/mako/codegen.py +++ b/third_party/mako/mako/codegen.py
@@ -1,5 +1,5 @@ # mako/codegen.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -7,6 +7,7 @@ """provides functionality for rendering a parsetree constructing into module source code.""" +import json import re import time @@ -176,7 +177,7 @@ self.printer.writelines( '"""', "__M_BEGIN_METADATA", - compat.json.dumps(struct), + json.dumps(struct), "__M_END_METADATA\n" '"""', )
diff --git a/third_party/mako/mako/compat.py b/third_party/mako/mako/compat.py index a3b1fd0a..06bb8d99 100644 --- a/third_party/mako/mako/compat.py +++ b/third_party/mako/mako/compat.py
@@ -1,41 +1,52 @@ # mako/compat.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -import json # noqa +import collections +import inspect import sys -import time py3k = sys.version_info >= (3, 0) -py33 = sys.version_info >= (3, 3) py2k = sys.version_info < (3,) py27 = sys.version_info >= (2, 7) jython = sys.platform.startswith("java") win32 = sys.platform.startswith("win") pypy = hasattr(sys, "pypy_version_info") -if py3k: - # create a "getargspec" from getfullargspec(), which is not deprecated - # in Py3K; getargspec() has started to emit warnings as of Py3.5. - # As of Py3.4, now they are trying to move from getfullargspec() - # to "signature()", but getfullargspec() is not deprecated, so stick - # with that for now. - - import collections - - ArgSpec = collections.namedtuple( - "ArgSpec", ["args", "varargs", "keywords", "defaults"] - ) - from inspect import getfullargspec as inspect_getfullargspec - - def inspect_getargspec(func): - return ArgSpec(*inspect_getfullargspec(func)[0:4]) +ArgSpec = collections.namedtuple( + "ArgSpec", ["args", "varargs", "keywords", "defaults"] +) -else: - from inspect import getargspec as inspect_getargspec # noqa +def inspect_getargspec(func): + """getargspec based on fully vendored getfullargspec from Python 3.3.""" + + if inspect.ismethod(func): + func = func.__func__ + if not inspect.isfunction(func): + raise TypeError("{!r} is not a Python function".format(func)) + + co = func.__code__ + if not inspect.iscode(co): + raise TypeError("{!r} is not a code object".format(co)) + + nargs = co.co_argcount + names = co.co_varnames + nkwargs = co.co_kwonlyargcount if py3k else 0 + args = list(names[:nargs]) + + nargs += nkwargs + varargs = None + if co.co_flags & inspect.CO_VARARGS: + varargs = co.co_varnames[nargs] + nargs = nargs + 1 + varkw = None + if co.co_flags & inspect.CO_VARKEYWORDS: + varkw = co.co_varnames[nargs] + + return ArgSpec(args, varargs, varkw, func.__defaults__) if py3k: @@ -87,12 +98,21 @@ return eval("0" + lit) -if py33: - from importlib import machinery +if py3k: + from importlib import machinery, util - def load_module(module_id, path): - return machinery.SourceFileLoader(module_id, path).load_module() - + if hasattr(util, 'module_from_spec'): + # Python 3.5+ + def load_module(module_id, path): + spec = util.spec_from_file_location(module_id, path) + module = util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + else: + def load_module(module_id, path): + module = machinery.SourceFileLoader(module_id, path).load_module() + del sys.modules[module_id] + return module else: import imp @@ -100,7 +120,9 @@ def load_module(module_id, path): fp = open(path, "rb") try: - return imp.load_source(module_id, path, fp) + module = imp.load_source(module_id, path, fp) + del sys.modules[module_id] + return module finally: fp.close() @@ -126,39 +148,6 @@ return sys.exc_info()[1] -try: - import threading - - if py3k: - import _thread as thread - else: - import thread -except ImportError: - import dummy_threading as threading # noqa - - if py3k: - import _dummy_thread as thread - else: - import dummy_thread as thread # noqa - -if win32 or jython: - time_func = time.clock -else: - time_func = time.time - -try: - from functools import partial -except: - - def partial(func, *args, **keywords): - def newfunc(*fargs, **fkeywords): - newkeywords = keywords.copy() - newkeywords.update(fkeywords) - return func(*(args + fargs), **newkeywords) - - return newfunc - - all = all # noqa @@ -166,50 +155,6 @@ return exc.__class__.__name__ -try: - from inspect import CO_VARKEYWORDS, CO_VARARGS - - def inspect_func_args(fn): - if py3k: - co = fn.__code__ - else: - co = fn.func_code - - nargs = co.co_argcount - names = co.co_varnames - args = list(names[:nargs]) - - varargs = None - if co.co_flags & CO_VARARGS: - varargs = co.co_varnames[nargs] - nargs = nargs + 1 - varkw = None - if co.co_flags & CO_VARKEYWORDS: - varkw = co.co_varnames[nargs] - - if py3k: - return args, varargs, varkw, fn.__defaults__ - else: - return args, varargs, varkw, fn.func_defaults - - -except ImportError: - import inspect - - def inspect_func_args(fn): - return inspect.getargspec(fn) - - -if py3k: - # TODO: this has been restored in py3k - def callable(fn): # noqa - return hasattr(fn, "__call__") - - -else: - callable = callable # noqa - - ################################################ # cross-compatible metaclass implementation # Copyright (c) 2010-2012 Benjamin Peterson
diff --git a/third_party/mako/mako/exceptions.py b/third_party/mako/mako/exceptions.py index b6388b1..ea7b20d 100644 --- a/third_party/mako/mako/exceptions.py +++ b/third_party/mako/mako/exceptions.py
@@ -1,5 +1,5 @@ # mako/exceptions.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -166,9 +166,7 @@ module_source = info.code template_source = info.source template_filename = ( - info.template_filename - or info.template_uri - or filename + info.template_filename or info.template_uri or filename ) except KeyError: # A normal .py file (not a Template)
diff --git a/third_party/mako/mako/ext/autohandler.py b/third_party/mako/mako/ext/autohandler.py index 55afb95..8b1324ef 100644 --- a/third_party/mako/mako/ext/autohandler.py +++ b/third_party/mako/mako/ext/autohandler.py
@@ -1,5 +1,5 @@ # ext/autohandler.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/ext/babelplugin.py b/third_party/mako/mako/ext/babelplugin.py index dbe2cd0..76bbc5b 100644 --- a/third_party/mako/mako/ext/babelplugin.py +++ b/third_party/mako/mako/ext/babelplugin.py
@@ -1,5 +1,5 @@ # ext/babelplugin.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/ext/beaker_cache.py b/third_party/mako/mako/ext/beaker_cache.py index b415c9c..f65ce43 100644 --- a/third_party/mako/mako/ext/beaker_cache.py +++ b/third_party/mako/mako/ext/beaker_cache.py
@@ -1,5 +1,5 @@ # ext/beaker_cache.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/ext/extract.py b/third_party/mako/mako/ext/extract.py index 8a1bd540..ad2348a 100644 --- a/third_party/mako/mako/ext/extract.py +++ b/third_party/mako/mako/ext/extract.py
@@ -1,5 +1,5 @@ # ext/extract.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/ext/linguaplugin.py b/third_party/mako/mako/ext/linguaplugin.py index 955a5cb..c40fa74 100644 --- a/third_party/mako/mako/ext/linguaplugin.py +++ b/third_party/mako/mako/ext/linguaplugin.py
@@ -1,5 +1,5 @@ # ext/linguaplugin.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -27,7 +27,15 @@ self.python_extractor = get_extractor("x.py") if fileobj is None: fileobj = open(filename, "rb") - return self.process_file(fileobj) + must_close = True + else: + must_close = False + try: + for message in self.process_file(fileobj): + yield message + finally: + if must_close: + fileobj.close() def process_python(self, code, code_lineno, translator_strings): source = code.getvalue().strip()
diff --git a/third_party/mako/mako/ext/preprocessors.py b/third_party/mako/mako/ext/preprocessors.py index 1eeb7c5f..9cc06214 100644 --- a/third_party/mako/mako/ext/preprocessors.py +++ b/third_party/mako/mako/ext/preprocessors.py
@@ -1,5 +1,5 @@ # ext/preprocessors.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/ext/pygmentplugin.py b/third_party/mako/mako/ext/pygmentplugin.py index 28246934..943a67a 100644 --- a/third_party/mako/mako/ext/pygmentplugin.py +++ b/third_party/mako/mako/ext/pygmentplugin.py
@@ -1,5 +1,5 @@ # ext/pygmentplugin.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -59,7 +59,7 @@ ), (r"<%(?=([\w\.\:]+))", Comment.Preproc, "ondeftags"), ( - r"(<%(?:!?))(.*?)(%>)(?s)", + r"(?s)(<%(?:!?))(.*?)(%>)", bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc), ), (
diff --git a/third_party/mako/mako/ext/turbogears.py b/third_party/mako/mako/ext/turbogears.py index fdb7741..722a6b4 100644 --- a/third_party/mako/mako/ext/turbogears.py +++ b/third_party/mako/mako/ext/turbogears.py
@@ -1,5 +1,5 @@ # ext/turbogears.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/filters.py b/third_party/mako/mako/filters.py index ba69fddc..0ae33ff48 100644 --- a/third_party/mako/mako/filters.py +++ b/third_party/mako/mako/filters.py
@@ -1,5 +1,5 @@ # mako/filters.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/lexer.py b/third_party/mako/mako/lexer.py index dadd663..6226e26 100644 --- a/third_party/mako/mako/lexer.py +++ b/third_party/mako/mako/lexer.py
@@ -1,5 +1,5 @@ # mako/lexer.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -201,7 +201,7 @@ """ if isinstance(text, compat.text_type): m = self._coding_re.match(text) - encoding = m and m.group(1) or known_encoding or "ascii" + encoding = m and m.group(1) or known_encoding or "utf-8" return encoding, text if text.startswith(codecs.BOM_UTF8): @@ -222,7 +222,7 @@ if m: parsed_encoding = m.group(1) else: - parsed_encoding = known_encoding or "ascii" + parsed_encoding = known_encoding or "utf-8" if decode_raw: try:
diff --git a/third_party/mako/mako/lookup.py b/third_party/mako/mako/lookup.py index 93558b24..476326d 100644 --- a/third_party/mako/mako/lookup.py +++ b/third_party/mako/mako/lookup.py
@@ -1,5 +1,5 @@ # mako/lookup.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/parsetree.py b/third_party/mako/mako/parsetree.py index 2881da1..801e48a 100644 --- a/third_party/mako/mako/parsetree.py +++ b/third_party/mako/mako/parsetree.py
@@ -1,5 +1,5 @@ # mako/parsetree.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/pygen.py b/third_party/mako/mako/pygen.py index 603676d..947721f 100644 --- a/third_party/mako/mako/pygen.py +++ b/third_party/mako/mako/pygen.py
@@ -1,5 +1,5 @@ # mako/pygen.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/pyparser.py b/third_party/mako/mako/pyparser.py index e41c304b..b16672d 100644 --- a/third_party/mako/mako/pyparser.py +++ b/third_party/mako/mako/pyparser.py
@@ -1,5 +1,5 @@ # mako/pyparser.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php
diff --git a/third_party/mako/mako/runtime.py b/third_party/mako/mako/runtime.py index 0956cd0d..465908e6 100644 --- a/third_party/mako/mako/runtime.py +++ b/third_party/mako/mako/runtime.py
@@ -1,5 +1,5 @@ # mako/runtime.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -7,6 +7,7 @@ """provides runtime services for templates, including Context, Namespace, and various helper functions.""" +import functools import sys from mako import compat @@ -37,7 +38,7 @@ # "capture" function which proxies to the # generic "capture" function - self._data["capture"] = compat.partial(capture, self) + self._data["capture"] = functools.partial(capture, self) # "caller" stack used by def calls with content self.caller_stack = self._data["caller"] = CallerStack() @@ -625,7 +626,7 @@ def get(key): callable_ = self.template._get_def_callable(key) - return compat.partial(callable_, self.context) + return functools.partial(callable_, self.context) for k in self.template.module._exports: yield (k, get(k)) @@ -635,7 +636,7 @@ val = self.callables[key] elif self.template.has_def(key): callable_ = self.template._get_def_callable(key) - val = compat.partial(callable_, self.context) + val = functools.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) @@ -686,15 +687,15 @@ for key in dir(self.module): if key[0] != "_": callable_ = getattr(self.module, key) - if compat.callable(callable_): - yield key, compat.partial(callable_, self.context) + if callable(callable_): + yield key, functools.partial(callable_, self.context) def __getattr__(self, key): if key in self.callables: val = self.callables[key] elif hasattr(self.module, key): callable_ = getattr(self.module, key) - val = compat.partial(callable_, self.context) + val = functools.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) else: @@ -731,7 +732,7 @@ """ - if not compat.callable(callable_): + if not callable(callable_): raise exceptions.RuntimeException( "capture() function expects a callable as " "its argument (i.e. capture(func, *args, **kwargs))" @@ -885,7 +886,7 @@ def _kwargs_for_callable(callable_, data): - argspec = compat.inspect_func_args(callable_) + argspec = compat.inspect_getargspec(callable_) # for normal pages, **pageargs is usually present if argspec[2]: return data @@ -900,7 +901,7 @@ def _kwargs_for_include(callable_, data, **kwargs): - argspec = compat.inspect_func_args(callable_) + argspec = compat.inspect_getargspec(callable_) namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None] for arg in namedargs: if arg != "context" and arg in data and arg not in kwargs:
diff --git a/third_party/mako/mako/template.py b/third_party/mako/mako/template.py index 8e87d50..5ed232046 100644 --- a/third_party/mako/mako/template.py +++ b/third_party/mako/mako/template.py
@@ -1,5 +1,5 @@ # mako/template.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php @@ -7,11 +7,11 @@ """Provides the Template class, a facade for parsing, generating and executing template strings, as well as template runtime operations.""" +import json import os import re import shutil import stat -import sys import tempfile import types import weakref @@ -413,14 +413,12 @@ self, data, filename, path, self.module_writer ) module = compat.load_module(self.module_id, path) - del sys.modules[self.module_id] if module._magic_number != codegen.MAGIC_NUMBER: data = util.read_file(filename) _compile_module_file( self, data, filename, path, self.module_writer ) module = compat.load_module(self.module_id, path) - del sys.modules[self.module_id] ModuleInfo(module, path, self, filename, None, None, None) else: # template filename and no module directory, compile code @@ -519,17 +517,17 @@ """A Template which is constructed given an existing Python module. - e.g.:: + e.g.:: - t = Template("this is a template") - f = file("mymodule.py", "w") - f.write(t.code) - f.close() + t = Template("this is a template") + f = file("mymodule.py", "w") + f.write(t.code) + f.close() - import mymodule + import mymodule - t = ModuleTemplate(mymodule) - print t.render() + t = ModuleTemplate(mymodule) + print(t.render()) """ @@ -659,7 +657,7 @@ source_map = re.search( r"__M_BEGIN_METADATA(.+?)__M_END_METADATA", module_source, re.S ).group(1) - source_map = compat.json.loads(source_map) + source_map = json.loads(source_map) source_map["line_map"] = dict( (int(k), int(v)) for k, v in source_map["line_map"].items() )
diff --git a/third_party/mako/mako/util.py b/third_party/mako/mako/util.py index 4f1426d..16e3c72 100644 --- a/third_party/mako/mako/util.py +++ b/third_party/mako/mako/util.py
@@ -1,14 +1,17 @@ # mako/util.py -# Copyright 2006-2019 the Mako authors and contributors <see AUTHORS file> +# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file> # # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php +from __future__ import absolute_import +from ast import parse import codecs import collections import operator import os import re +import timeit from mako import compat @@ -180,7 +183,7 @@ def __init__(self, key, value): self.key = key self.value = value - self.timestamp = compat.time_func() + self.timestamp = timeit.default_timer() def __repr__(self): return repr(self.value) @@ -191,7 +194,7 @@ def __getitem__(self, key): item = dict.__getitem__(self, key) - item.timestamp = compat.time_func() + item.timestamp = timeit.default_timer() return item.value def values(self): @@ -256,9 +259,7 @@ m = _PYTHON_MAGIC_COMMENT_re.match(line1.decode("ascii", "ignore")) if not m: try: - import parser - - parser.suite(line1.decode("ascii", "ignore")) + parse(line1.decode("ascii", "ignore")) except (ImportError, SyntaxError): # Either it's a real syntax error, in which case the source # is not valid python source, or line2 is a continuation of
diff --git a/third_party/mako/setup.cfg b/third_party/mako/setup.cfg index 8eb274a3..5ec681bb 100644 --- a/third_party/mako/setup.cfg +++ b/third_party/mako/setup.cfg
@@ -3,7 +3,7 @@ tag_date = 0 [tool:pytest] -addopts = --tb native -v -r fxX +addopts = --tb native -v -r fxX -W error python_files = test/*test_*.py [upload] @@ -11,6 +11,7 @@ identity = C4DAFEE1 [flake8] +show-source = true enable-extensions = G ignore = A003, @@ -23,3 +24,6 @@ import-order-style = google application-import-names = mako,test +[bdist_wheel] +universal = 1 +
diff --git a/third_party/mako/setup.py b/third_party/mako/setup.py index 17b6c70..cc5127d 100644 --- a/third_party/mako/setup.py +++ b/third_party/mako/setup.py
@@ -14,44 +14,24 @@ ) v.close() -readme = open(os.path.join(os.path.dirname(__file__), "README.rst")).read() +readme = os.path.join(os.path.dirname(__file__), "README.rst") -if sys.version_info < (2, 6): - raise Exception("Mako requires Python 2.6 or higher.") - -markupsafe_installs = ( - sys.version_info >= (2, 6) and sys.version_info < (3, 0) -) or sys.version_info >= (3, 3) - -install_requires = [] - -if markupsafe_installs: - install_requires.append("MarkupSafe>=0.9.2") - -try: - import argparse # noqa -except ImportError: - install_requires.append("argparse") +install_requires = ["MarkupSafe>=0.9.2"] -class PyTest(TestCommand): - user_options = [("pytest-args=", "a", "Arguments to pass to py.test")] - - def initialize_options(self): - TestCommand.initialize_options(self) - self.pytest_args = [] - - def finalize_options(self): - TestCommand.finalize_options(self) - self.test_args = [] - self.test_suite = True +class UseTox(TestCommand): + RED = 31 + RESET_SEQ = "\033[0m" + BOLD_SEQ = "\033[1m" + COLOR_SEQ = "\033[1;%dm" def run_tests(self): - # import here, cause outside the eggs aren't loaded - import pytest - - errno = pytest.main(self.pytest_args) - sys.exit(errno) + sys.stderr.write( + "%s%spython setup.py test is deprecated by PyPA. Please invoke " + "'tox' with no arguments for a basic test run.\n%s" + % (self.COLOR_SEQ % self.RED, self.BOLD_SEQ, self.RESET_SEQ) + ) + sys.exit(1) setup( @@ -59,7 +39,8 @@ version=VERSION, description="A super-fast templating language that borrows the \ best ideas from the existing templating languages.", - long_description=readme, + long_description=open(readme).read(), + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", classifiers=[ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", @@ -67,6 +48,9 @@ "Intended Audience :: Developers", "Programming Language :: Python", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", @@ -77,16 +61,13 @@ url="https://www.makotemplates.org/", project_urls={ "Documentation": "https://docs.makotemplates.org", - "Issue Tracker": "https://github.com/sqlalchemy/mako" + "Issue Tracker": "https://github.com/sqlalchemy/mako", }, license="MIT", packages=find_packages(".", exclude=["examples*", "test*"]), - tests_require=["pytest", "mock"], - cmdclass={"test": PyTest}, + cmdclass={"test": UseTox}, zip_safe=False, - python_requires=">=2.6", install_requires=install_requires, - extras_require={}, entry_points=""" [python.templating.engines] mako = mako.ext.turbogears:TGPlugin @@ -99,12 +80,20 @@ css+mako = mako.ext.pygmentplugin:MakoCssLexer [babel.extractors] - mako = mako.ext.babelplugin:extract + mako = mako.ext.babelplugin:extract [babel] [lingua.extractors] - mako = mako.ext.linguaplugin:LinguaMakoExtractor + mako = mako.ext.linguaplugin:LinguaMakoExtractor [lingua] [console_scripts] mako-render = mako.cmd:cmdline """, + extras_require={ + 'babel': [ + 'Babel', + ], + 'lingua': [ + 'lingua', + ], + }, )
diff --git a/third_party/mako/test/__init__.py b/third_party/mako/test/__init__.py index b91e709..1770962 100644 --- a/third_party/mako/test/__init__.py +++ b/third_party/mako/test/__init__.py
@@ -6,18 +6,10 @@ from mako import compat from mako.cache import CacheImpl from mako.cache import register_plugin -from mako.compat import py33 from mako.compat import py3k from mako.template import Template from mako.util import update_wrapper -try: - # unitttest has a SkipTest also but pytest doesn't - # honor it unless nose is imported too... - from nose import SkipTest -except ImportError: - from _pytest.runner import Skipped as SkipTest - template_base = os.path.join(os.path.dirname(__file__), "templates") module_base = os.path.join(template_base, "modules") @@ -106,7 +98,7 @@ shutil.rmtree(module_base, True) -if py33: +if py3k: from unittest import mock # noqa else: import mock # noqa @@ -149,7 +141,7 @@ def maybe(*args, **kw): if predicate(): msg = "'%s' skipped: %s" % (fn_name, reason) - raise SkipTest(msg) + raise unittest.SkipTest(msg) else: return fn(*args, **kw)
diff --git a/third_party/mako/test/ext/test_babelplugin.py b/third_party/mako/test/ext/test_babelplugin.py index 5f25a6a..ca12444 100644 --- a/third_party/mako/test/ext/test_babelplugin.py +++ b/third_party/mako/test/ext/test_babelplugin.py
@@ -63,6 +63,7 @@ @skip() def test_extract(self): mako_tmpl = open(os.path.join(template_base, "gettext.mako")) + self.addCleanup(mako_tmpl.close) messages = list( extract( mako_tmpl, @@ -103,6 +104,7 @@ mako_tmpl = open( os.path.join(template_base, "gettext_utf8.mako"), "rb" ) + self.addCleanup(mako_tmpl.close) message = next( extract(mako_tmpl, set(["_", None]), [], {"encoding": "utf-8"}) ) @@ -113,6 +115,7 @@ mako_tmpl = open( os.path.join(template_base, "gettext_cp1251.mako"), "rb" ) + self.addCleanup(mako_tmpl.close) message = next( extract(mako_tmpl, set(["_", None]), [], {"encoding": "cp1251"}) )
diff --git a/third_party/mako/test/templates/chs_unicode_py3k.html b/third_party/mako/test/templates/chs_unicode_py3k.html index e4b6a8f..1ee49cc 100644 --- a/third_party/mako/test/templates/chs_unicode_py3k.html +++ b/third_party/mako/test/templates/chs_unicode_py3k.html
@@ -1,4 +1,3 @@ -## -*- coding:utf-8 -*- <% msg = 'æ–°ä¸å›½çš„主å¸' %>
diff --git a/third_party/mako/test/templates/chs_utf8.html b/third_party/mako/test/templates/chs_utf8.html index 5f4733f..50886be3 100644 --- a/third_party/mako/test/templates/chs_utf8.html +++ b/third_party/mako/test/templates/chs_utf8.html
@@ -1,4 +1,3 @@ -## -*- coding:utf-8 -*- <% msg = 'æ–°ä¸å›½çš„主å¸' %>
diff --git a/third_party/mako/test/templates/unicode_arguments.html b/third_party/mako/test/templates/unicode_arguments.html index b363cb6..e6d7c2ca 100644 --- a/third_party/mako/test/templates/unicode_arguments.html +++ b/third_party/mako/test/templates/unicode_arguments.html
@@ -1,4 +1,3 @@ -# coding: utf-8 <%def name="my_def(x)"> x is: ${x}
diff --git a/third_party/mako/test/templates/unicode_arguments_py3k.html b/third_party/mako/test/templates/unicode_arguments_py3k.html index 47d918a..871517b 100644 --- a/third_party/mako/test/templates/unicode_arguments_py3k.html +++ b/third_party/mako/test/templates/unicode_arguments_py3k.html
@@ -1,4 +1,3 @@ -# coding: utf-8 <%def name="my_def(x)"> x is: ${x}
diff --git a/third_party/mako/test/templates/unicode_runtime_error.html b/third_party/mako/test/templates/unicode_runtime_error.html index 862dce5..dda7f62 100644 --- a/third_party/mako/test/templates/unicode_runtime_error.html +++ b/third_party/mako/test/templates/unicode_runtime_error.html
@@ -1,2 +1,2 @@ ## -*- coding: utf-8 -*- -<% print 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »' + int(5/0) %> \ No newline at end of file +<% x = 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »' + int(5/0) %> \ No newline at end of file
diff --git a/third_party/mako/test/templates/unicode_syntax_error.html b/third_party/mako/test/templates/unicode_syntax_error.html index 982af33c..aa53025b 100644 --- a/third_party/mako/test/templates/unicode_syntax_error.html +++ b/third_party/mako/test/templates/unicode_syntax_error.html
@@ -1,2 +1,2 @@ ## -*- coding: utf-8 -*- -<% print 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » %> \ No newline at end of file +<% x = 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » %> \ No newline at end of file
diff --git a/third_party/mako/test/test_cache.py b/third_party/mako/test/test_cache.py index 7fe9350..d662872 100644 --- a/third_party/mako/test/test_cache.py +++ b/third_party/mako/test/test_cache.py
@@ -1,4 +1,5 @@ import time +import unittest from mako import lookup from mako.cache import CacheImpl @@ -9,7 +10,6 @@ from mako.template import Template from test import eq_ from test import module_base -from test import SkipTest from test import TemplateTest from test.util import result_lines @@ -649,9 +649,9 @@ def setUp(self): if not beaker_cache.has_beaker: - raise SkipTest("Beaker is required for these tests.") + raise unittest.SkipTest("Beaker is required for these tests.") if not py27: - raise SkipTest("newer beakers not working w/ py26") + raise unittest.SkipTest("newer beakers not working w/ py26") def _install_mock_cache(self, template, implname=None): template.cache_args["manager"] = self._regions() @@ -676,7 +676,9 @@ try: import dogpile.cache # noqa except ImportError: - raise SkipTest("dogpile.cache is required to run these tests") + raise unittest.SkipTest( + "dogpile.cache is required to run these tests" + ) def _install_mock_cache(self, template, implname=None): template.cache_args["regions"] = self._regions()
diff --git a/third_party/mako/test/test_template.py b/third_party/mako/test/test_template.py index 89e5a61d..40fd10c 100644 --- a/third_party/mako/test/test_template.py +++ b/third_party/mako/test/test_template.py
@@ -541,9 +541,7 @@ # won't read the file even with open(...encoding='utf-8') unless # errors is specified. or if there's some quirk in 3.1.2 # since I'm pretty sure this test worked with py3k when I wrote it. - template.render( - path=self._file_path("internationalization.html") - ) + template.render(path=self._file_path("internationalization.html")) @requires_python_2 def test_bytestring_passthru(self): @@ -1682,7 +1680,7 @@ 8, 8, ], - "source_encoding": "ascii", + "source_encoding": "utf-8", "filename": None, "line_map": { 35: 29, @@ -1773,7 +1771,7 @@ 8, 8, ], - "source_encoding": "ascii", + "source_encoding": "utf-8", "filename": None, "line_map": { 34: 10,
diff --git a/third_party/mako/test/test_util.py b/third_party/mako/test/test_util.py index f3f3edb7..e40390f7 100644 --- a/third_party/mako/test/test_util.py +++ b/third_party/mako/test/test_util.py
@@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import os +import sys import unittest from mako import compat @@ -43,10 +44,13 @@ @skip_if(lambda: compat.pypy, "Pypy does this differently") def test_load_module(self): fn = os.path.join(os.path.dirname(__file__), "test_util.py") + sys.modules.pop("mako.template") module = compat.load_module("mako.template", fn) + self.assertNotIn("mako.template", sys.modules) + self.assertIn("UtilTest", dir(module)) import mako.template - self.assertEqual(module, mako.template) + self.assertNotEqual(module, mako.template) def test_load_plugin_failure(self): loader = util.PluginLoader("fakegroup")
diff --git a/third_party/mako/tox.ini b/third_party/mako/tox.ini index 8611507..d3ef981 100644 --- a/third_party/mako/tox.ini +++ b/third_party/mako/tox.ini
@@ -1,10 +1,10 @@ [tox] -envlist = py{27,35,36,37,38} +envlist = py [testenv] cov_args=--cov=mako --cov-report term --cov-report xml -deps=pytest +deps=pytest>=3.1.0 mock beaker markupsafe @@ -20,15 +20,15 @@ commands=py.test {env:COVERAGE:} {posargs} -# thanks to https://julien.danjou.info/the-best-flake8-extensions/ [testenv:pep8] -basepython = python3.7 +basepython = python3 deps= flake8 flake8-import-order flake8-builtins flake8-docstrings flake8-rst-docstrings + pydocstyle<4.0.0 # used by flake8-rst-docstrings pygments -commands = flake8 ./mako/ ./test/ setup.py --exclude test/templates,test/foo +commands = flake8 ./mako/ ./test/ setup.py --exclude test/templates,test/foo {posargs}
diff --git a/tools/binary_size/supersize.pydeps b/tools/binary_size/supersize.pydeps index 504718ff..b3f306e 100644 --- a/tools/binary_size/supersize.pydeps +++ b/tools/binary_size/supersize.pydeps
@@ -35,7 +35,7 @@ ../grit/grit/node/structure.py ../grit/grit/node/variant.py ../grit/grit/pseudo.py -../grit/grit/pseudo_rtl.py +../grit/grit/pseudolocales.py ../grit/grit/tclib.py ../grit/grit/util.py ../grit/grit/xtb_reader.py
diff --git a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp index 9e429e3..3232ba47 100644 --- a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp +++ b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
@@ -307,21 +307,35 @@ return it != file_lines_.end(); } - // Returns true if any of the filter file lines is a substring of - // |string_to_match|. + // Returns true if |string_to_match| matches based on the filter file lines. + // Filter file lines can contain both inclusions and exclusions in the filter. + // Only returns true if |string_to_match| both matches an inclusion filter and + // is *not* matched by an exclusion filter. bool ContainsSubstringOf(llvm::StringRef string_to_match) const { - if (!substring_regex_.hasValue()) { - std::vector<std::string> regex_escaped_file_lines; - regex_escaped_file_lines.reserve(file_lines_.size()); - for (const llvm::StringRef& file_line : file_lines_.keys()) - regex_escaped_file_lines.push_back(llvm::Regex::escape(file_line)); - std::string substring_regex_pattern = - llvm::join(regex_escaped_file_lines.begin(), - regex_escaped_file_lines.end(), "|"); - substring_regex_.emplace(substring_regex_pattern); + if (!inclusion_substring_regex_.hasValue()) { + std::vector<std::string> regex_escaped_inclusion_file_lines; + std::vector<std::string> regex_escaped_exclusion_file_lines; + regex_escaped_inclusion_file_lines.reserve(file_lines_.size()); + for (const llvm::StringRef& file_line : file_lines_.keys()) { + if (file_line.startswith("!")) { + regex_escaped_exclusion_file_lines.push_back( + llvm::Regex::escape(file_line.substr(1))); + } else { + regex_escaped_inclusion_file_lines.push_back( + llvm::Regex::escape(file_line)); + } + } + std::string inclusion_substring_regex_pattern = + llvm::join(regex_escaped_inclusion_file_lines.begin(), + regex_escaped_inclusion_file_lines.end(), "|"); + inclusion_substring_regex_.emplace(inclusion_substring_regex_pattern); + std::string exclusion_substring_regex_pattern = + llvm::join(regex_escaped_exclusion_file_lines.begin(), + regex_escaped_exclusion_file_lines.end(), "|"); + exclusion_substring_regex_.emplace(exclusion_substring_regex_pattern); } - - return substring_regex_->match(string_to_match); + return inclusion_substring_regex_->match(string_to_match) && + !exclusion_substring_regex_->match(string_to_match); } private: @@ -368,9 +382,16 @@ // Stores all file lines (after stripping comments and blank lines). llvm::StringSet<> file_lines_; + // |file_lines_| is partitioned based on whether the line starts with a ! + // (exclusion line) or not (inclusion line). Inclusion lines specify things to + // be matched by the filter. The exclusion lines specify what to force exclude + // from the filter. Lazily-constructed regex that matches strings that contain + // any of the inclusion lines in |file_lines_|. + mutable llvm::Optional<llvm::Regex> inclusion_substring_regex_; + // Lazily-constructed regex that matches strings that contain any of the - // |file_lines_|. - mutable llvm::Optional<llvm::Regex> substring_regex_; + // exclusion lines in |file_lines_|. + mutable llvm::Optional<llvm::Regex> exclusion_substring_regex_; }; AST_MATCHER_P(clang::FieldDecl,
diff --git a/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt b/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt index 9df211b..1ccbdfa 100644 --- a/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt +++ b/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt
@@ -4,6 +4,9 @@ # If a source file path contains any of the lines in the filter file below, # then such source file will not be rewritten. # +# Lines prefixed with "!" can be used to force include files that matched a file +# path to be ignored. +# # Note that the rewriter has a hardcoded logic for a handful of path-based # exclusions that cannot be expressed as substring matches: # - Excluding paths containing "third_party/", but still covering @@ -50,12 +53,17 @@ # elsewhere - for example "v8/" is excluded in another part of this # file. # +# The common/ directories must be included in the rewrite as they contain code +# that is also used from the browser process. +# # Also, note that isInThirdPartyLocation AST matcher in # RewriteRawPtrFields.cpp explicitly includes third_party/blink # (because it is in the same git repository as the rest of Chromium), # but we go ahead and exclude it below. /renderer/ # (e.g. //content/renderer/ or //components/visitedlink/renderer/). third_party/blink/ +!third_party/blink/public/common/ +!third_party/blink/common/ # Exclude paths in separate repositories - i.e. in directories that # 1. Contain a ".git" subdirectory
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/path-filter-file-always-include-expected.cc b/tools/clang/rewrite_raw_ptr_fields/tests/path-filter-file-always-include-expected.cc new file mode 100644 index 0000000..1b8e5ee --- /dev/null +++ b/tools/clang/rewrite_raw_ptr_fields/tests/path-filter-file-always-include-expected.cc
@@ -0,0 +1,13 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/memory/checked_ptr.h" + +class SomeClass; + +struct MyStruct { + // Rewrite expected - this file is force included in the rewrite using ! in + // tests/paths-to-ignore.txt file. + CheckedPtr<SomeClass> ptr_field_; +};
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/path-filter-file-always-include-original.cc b/tools/clang/rewrite_raw_ptr_fields/tests/path-filter-file-always-include-original.cc new file mode 100644 index 0000000..86a1f542 --- /dev/null +++ b/tools/clang/rewrite_raw_ptr_fields/tests/path-filter-file-always-include-original.cc
@@ -0,0 +1,11 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +class SomeClass; + +struct MyStruct { + // Rewrite expected - this file is force included in the rewrite using ! in + // tests/paths-to-ignore.txt file. + SomeClass* ptr_field_; +};
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/paths-to-ignore.txt b/tools/clang/rewrite_raw_ptr_fields/tests/paths-to-ignore.txt index e61b1a7c..a925371 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/paths-to-ignore.txt +++ b/tools/clang/rewrite_raw_ptr_fields/tests/paths-to-ignore.txt
@@ -11,6 +11,10 @@ # Next line contains a substring of the tests/path-filter-file-...cc file. th-filter-fi +# Next line says to include a file if it contains "always-include" substring +# (even if it also matches the "the-filter-fi" substring above) +!always-include + # The lines below don't match any test paths - these lines have been included to # exercise a bit further the regex # building code in # FilterFile::ContainsSubstringOf.
diff --git a/tools/grit/grit/clique.py b/tools/grit/grit/clique.py index e7be3ec..16e82b5a 100644 --- a/tools/grit/grit/clique.py +++ b/tools/grit/grit/clique.py
@@ -16,7 +16,7 @@ from grit import exception from grit import lazy_re from grit import pseudo -from grit import pseudo_rtl +from grit import pseudolocales from grit import tclib @@ -399,8 +399,11 @@ if lang == msglang: return self.clique[msglang] - if lang == constants.FAKE_BIDI: - return pseudo_rtl.PseudoRTLMessage(self.GetMessage()) + if pseudo_if_no_match: + if lang == constants.PSEUDOLOCALE_LONG_STRINGS: + return pseudolocales.PseudoLongStringMessage(self.GetMessage()) + elif lang == constants.PSEUDOLOCALE_RTL: + return pseudolocales.PseudoRTLMessage(self.GetMessage()) if fallback_to_english: self.uber_clique._AddMissingTranslation(lang, self, is_error=False)
diff --git a/tools/grit/grit/constants.py b/tools/grit/grit/constants.py index 8229c94..1a82faf 100644 --- a/tools/grit/grit/constants.py +++ b/tools/grit/grit/constants.py
@@ -15,7 +15,9 @@ # A special language, translations into which are always "TTTTTT". CONSTANT_LANGUAGE = 'x_constant' -FAKE_BIDI = 'fake-bidi' +PSEUDOLOCALE_LONG_STRINGS = 'en-XA' +PSEUDOLOCALE_RTL = 'ar-XB' +PSEUDOLOCALES = [PSEUDOLOCALE_LONG_STRINGS, PSEUDOLOCALE_RTL] # Magic number added to the header of resources brotli compressed by grit. Used # to easily identify resources as being brotli compressed. See
diff --git a/tools/grit/grit/format/chrome_messages_json.py b/tools/grit/grit/format/chrome_messages_json.py index 88ec1d91..8be7272 100644 --- a/tools/grit/grit/format/chrome_messages_json.py +++ b/tools/grit/grit/format/chrome_messages_json.py
@@ -27,11 +27,11 @@ id = id[4:] translation_missing = child.GetCliques()[0].clique.get(lang) is None; - if (child.ShouldFallbackToEnglish() and translation_missing and - lang != constants.FAKE_BIDI): - # Skip the string if it's not translated. Chrome will fallback - # to English automatically. - continue + if (child.ShouldFallbackToEnglish() and translation_missing + and lang not in constants.PSEUDOLOCALES): + # Skip the string if it's not translated. Chrome will fallback + # to English automatically. + continue loc_message = encoder.encode(child.ws_at_start + child.Translate(lang) + child.ws_at_end)
diff --git a/tools/grit/grit/format/rc.py b/tools/grit/grit/format/rc.py index ed32bb8..be8efcd 100644 --- a/tools/grit/grit/format/rc.py +++ b/tools/grit/grit/format/rc.py
@@ -163,7 +163,10 @@ 'gl' : '045604e4', # No codepage for Zulu, use unicode(1200). 'zu' : '043504b0', - 'fake-bidi' : '040d04e7', + + # Pseudolocales + 'ar-XB' : '040d04e7', + 'en-XA' : '040904b0', } # Language ID resource: http://msdn.microsoft.com/en-us/library/ms776294.aspx @@ -250,7 +253,10 @@ 'si' : 'LANG_SINHALESE, SUBLANG_SINHALESE_SRI_LANKA', 'ne' : 'LANG_NEPALI, SUBLANG_NEPALI_NEPAL', 'ti' : 'LANG_TIGRIGNA, SUBLANG_TIGRIGNA_ERITREA', - 'fake-bidi' : 'LANG_HEBREW, SUBLANG_DEFAULT', + + # Pseudolocales + 'ar-XB' : 'LANG_HEBREW, SUBLANG_DEFAULT', + 'en-XA' : 'LANG_ENGLISH, SUBLANG_ENGLISH_US', } # A note on 'no-specific-language' in the following few functions:
diff --git a/tools/grit/grit/pseudo_rtl.py b/tools/grit/grit/pseudo_rtl.py deleted file mode 100644 index 2240b57..0000000 --- a/tools/grit/grit/pseudo_rtl.py +++ /dev/null
@@ -1,104 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -'''Pseudo RTL, (aka Fake Bidi) support. It simply wraps each word with -Unicode RTL overrides. -More info at https://sites.google.com/a/chromium.org/dev/Home/fake-bidi -''' - -from __future__ import print_function - -import re - -from grit import lazy_re -from grit import tclib - -ACCENTED_STRINGS = { - 'a': u"\u00e5", 'e': u"\u00e9", 'i': u"\u00ee", 'o': u"\u00f6", - 'u': u"\u00fb", 'A': u"\u00c5", 'E': u"\u00c9", 'I': u"\u00ce", - 'O': u"\u00d6", 'U': u"\u00db", 'c': u"\u00e7", 'd': u"\u00f0", - 'n': u"\u00f1", 'p': u"\u00fe", 'y': u"\u00fd", 'C': u"\u00c7", - 'D': u"\u00d0", 'N': u"\u00d1", 'P': u"\u00de", 'Y': u"\u00dd", - 'f': u"\u0192", 's': u"\u0161", 'S': u"\u0160", 'z': u"\u017e", - 'Z': u"\u017d", 'g': u"\u011d", 'G': u"\u011c", 'h': u"\u0125", - 'H': u"\u0124", 'j': u"\u0135", 'J': u"\u0134", 'k': u"\u0137", - 'K': u"\u0136", 'l': u"\u013c", 'L': u"\u013b", 't': u"\u0163", - 'T': u"\u0162", 'w': u"\u0175", 'W': u"\u0174", - '$': u"\u20ac", '?': u"\u00bf", 'R': u"\u00ae", r'!': u"\u00a1", -} - -# a character set containing the keys in ACCENTED_STRINGS -# We should not accent characters in an escape sequence such as "\n". -# To be safe, we assume every character following a backslash is an escaped -# character. We also need to consider the case like "\\n", which means -# a blackslash and a character "n", we will accent the character "n". -TO_ACCENT = lazy_re.compile( - r'[%s]|\\[a-z\\]' % ''.join(ACCENTED_STRINGS.keys())) - -# Lex text so that we don't interfere with html tokens and entities. -# This lexing scheme will handle all well formed tags and entities, html or -# xhtml. It will not handle comments, CDATA sections, or the unescaping tags: -# script, style, xmp or listing. If any of those appear in messages, -# something is wrong. -TOKENS = [ lazy_re.compile( - '^%s' % pattern, # match at the beginning of input - re.I | re.S # html tokens are case-insensitive - ) - for pattern in - ( - # a run of non html special characters - r'[^<&]+', - # a tag - (r'</?[a-z]\w*' # beginning of tag - r'(?:\s+\w+(?:\s*=\s*' # attribute start - r'(?:[^\s"\'>]+|"[^\"]*"|\'[^\']*\'))?' # attribute value - r')*\s*/?>'), - # an entity - r'&(?:[a-z]\w+|#\d+|#x[\da-f]+);', - # an html special character not part of a special sequence - r'.' - ) ] - -ALPHABETIC_RUN = lazy_re.compile(r'([^\W0-9_]+)') - -RLO = u'\u202e' -PDF = u'\u202c' - -def PseudoRTLString(text): - '''Returns a fake bidirectional version of the source string. This code is - based on accentString above, in turn copied from Frank Tang. - ''' - parts = [] - while text: - m = None - for token in TOKENS: - m = token.search(text) - if m: - part = m.group(0) - text = text[len(part):] - if part[0] not in ('<', '&'): - # not a tag or entity, so accent - part = ALPHABETIC_RUN.sub(lambda run: RLO + run.group() + PDF, part) - parts.append(part) - break - return ''.join(parts) - - -def PseudoRTLMessage(message): - '''Returns a pseudo-RTL (aka Fake-Bidi) translation of the provided message. - - Args: - message: tclib.Message() - - Return: - tclib.Translation() - ''' - transl = tclib.Translation() - for part in message.GetContent(): - if isinstance(part, tclib.Placeholder): - transl.AppendPlaceholder(part) - else: - transl.AppendText(PseudoRTLString(part)) - - return transl
diff --git a/tools/grit/grit/pseudolocales.py b/tools/grit/grit/pseudolocales.py new file mode 100644 index 0000000..296f3e55 --- /dev/null +++ b/tools/grit/grit/pseudolocales.py
@@ -0,0 +1,325 @@ +# Copyright (c) 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Pseudolocale translations for chrome.""" + +from __future__ import print_function + +import re +import string + +from collections import namedtuple +from grit import lazy_re +from grit import tclib + +ACCENTED_STRINGS = { + '!': u'\u00a1', + '$': u'\u20ac', + '?': u'\u00bf', + 'A': u'\u00c5', + 'C': u'\u00c7', + 'D': u'\u00d0', + 'E': u'\u00c9', + 'G': u'\u011c', + 'H': u'\u0124', + 'I': u'\u00ce', + 'J': u'\u0134', + 'K': u'\u0136', + 'L': u'\u013b', + 'N': u'\u00d1', + 'O': u'\u00d6', + 'P': u'\u00de', + 'R': u'\u00ae', + 'S': u'\u0160', + 'T': u'\u0162', + 'U': u'\u00db', + 'W': u'\u0174', + 'Y': u'\u00dd', + 'Z': u'\u017d', + 'a': u'\u00e5', + 'c': u'\u00e7', + 'd': u'\u00f0', + 'e': u'\u00e9', + 'f': u'\u0192', + 'g': u'\u011d', + 'h': u'\u0125', + 'i': u'\u00ee', + 'j': u'\u0135', + 'k': u'\u0137', + 'l': u'\u013c', + 'n': u'\u00f1', + 'o': u'\u00f6', + 'p': u'\u00fe', + 's': u'\u0161', + 't': u'\u0163', + 'u': u'\u00fb', + 'w': u'\u0175', + 'y': u'\u00fd', + 'z': u'\u017e', +} + +NUMBERS = [ + 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', + 'ten' +] +PLACEHOLDER_STRING = '{PLACEHOLDER_VARIABLE}' +ALPHABETIC_RUN = lazy_re.compile(r'([^\W0-9_]+)') +WORD = lazy_re.compile(r'\b\S+\b') + +# RTL modifiers for letters +RLO = u'\u202e' +PDF = u'\u202c' + + +class Node(object): + """A node in the syntax tree representing a message to be translated.""" + + translatable = False + after = '' + + def __init__(self, text, children=None): + self.text = text + self.children = [] if children is None else children + + def GetNumWords(self): + """Returns an approximate worst-case (maximum) number of words within the + tree.""" + return sum(child.GetNumWords() for child in self.children) + + def Transform(self, fn): + """Modifies the tree by applying fn to any translatable text within the tree + + Args: + fn: Callable[[unicode], unicode] + """ + for child in self.children: + child.Transform(fn) + + def ToString(self): + """Returns a string representation of the tree suitable for creating a + translation from. + """ + children = ''.join(c.ToString() for c in self.children) + return u'%s%s%s' % (self.text, children, self.after) + + def __repr__(self): + # For debugging + if self.children: + child_lines = '\n'.join(' ' + line for node in self.children + for line in repr(node).split('\n')) + return '%s[before=%s, after=%s\n%s\n]' % (self.__class__.__name__, + repr(self.text), repr( + self.after), child_lines) + else: + return '%s %s' % (self.__class__.__name__, repr(self.text)) + + @classmethod + def _MatchPattern(cls, text): + match = cls.pattern.match(text) + if match is not None: + return cls(match.group(0)), text[len(match.group(0)):] + return None, text + + @classmethod + def Parse(cls, text): + """Matches the node against the text, consuming any part of the text that + matches. + + Args: + text: str + + Return: (Optional[Node], str) + If the text starts with something matching the node, returns + (node, leftover). + Otherwise, returns (None, text) + """ + return cls._MatchPattern(text) + + +class HtmlTag(Node): + """HTMLTag represents a HTML tag (eg. <a href='...'> or </span>). + Note that since we don't care about the HTML structure, this does not + form a tree, has no children, and no linking between open and close tags. + + Lex text so that we don't interfere with html tokens. + This lexing scheme will handle all well formed tags, html or xhtml. + It will not handle comments, CDATA sections, or the unescaping tags: + script, style, xmp or listing. If any of those appear in messages, + something is wrong. + """ + pattern = lazy_re.compile( + r'^</?[a-z]\w*' # beginning of tag + r'(?:\s+\w+(?:\s*=\s*' # attribute start + r'(?:[^\s"\'>]+|"[^\"]*"|\'[^\']*\'))?' # attribute value + r')*\s*/?>', + re.S | re.I) + + +class RawText(Node): + """RawText represents regular text able to be translated.""" + # Raw text can have a < in it, but only at the very start. + # This guarantees that it's already tried and failed to match an HTML tag. + pattern = lazy_re.compile(r'^[^{}][^{}<]*', re.S) + + def GetNumWords(self): + return len(WORD.findall(self.text)) + + def Transform(self, fn): + self.text = fn(self.text) + + +class BasicVariable(Node): + """Represents a variable. Usually used inside a plural option, but has been + overloaded to store placeholders as well. + """ + pattern = lazy_re.compile(r'^{[A-Z0-9_]+}') + + def GetNumWords(self): + return 1 + + +class PluralOption(Node): + """Represents a single option for a plural selection. + eg. =1 {singular option here} + """ + pattern = lazy_re.compile(r'^(=[0-9]+|other)\s*{') + after = '}\n' + + @classmethod + def Parse(cls, text): + node, text = cls._MatchPattern(text) + assert node is not None, text + child, text = NodeSequence.Parse(text) + assert child is not None, text + node.children = child.children if isinstance(child, + NodeSequence) else [child] + + assert text.startswith('}') + return node, text[1:] + + +class Plural(Node): + """Represents a set of options for plurals. + eg. {VARIABLE, plural, =1 {singular} other {plural}} + """ + pattern = lazy_re.compile(r'^{[A-Z0-9_]+,\s+plural,\s+(offset:\d+\s+)?', re.S) + after = '}' + + @classmethod + def Parse(cls, text): + node, text = cls._MatchPattern(text) + if node is None: + return None, text + while not text.startswith('}'): + child, text = PluralOption.Parse(text) + assert child is not None, text + node.children.append(child) + text = text.lstrip() + + assert text.startswith('}'), text + return node, text[1:] + + def GetNumWords(self): + return max(child.GetNumWords() for child in self.children) + + +class NodeSequence(Node): + """Represents a series of nodes. + eg. hello {VAR} -> NodeSequence([RawText('Hello'), BasicVariable('{VAR}'])""" + child_types = [HtmlTag, BasicVariable, Plural, RawText] + + def __init__(self, children): + super(NodeSequence, self).__init__('', children) + + @classmethod + def Parse(cls, text): + children = [] + orig_text = None + while text != orig_text: + orig_text = text + for node in cls.child_types: + child, text = node.Parse(text) + if child is not None: + children.append(child) + break + assert children, text + if len(children) == 1: + return children[0], text + return cls(children), text + + +def BuildTree(text): + """Builds a tree from some text""" + root, leftovers = NodeSequence.Parse(text) + assert not leftovers, leftovers + return root + + +def BuildTreeFromMessage(message): + """Builds a tree from message, substituting any placeholders with + PLACEHOLDER_STRING. Returns (tree, substituted placeholders) + """ + text = '' + placeholders = [] + for part in message.GetContent(): + if isinstance(part, tclib.Placeholder): + text += PLACEHOLDER_STRING + placeholders.append(part) + else: + text += part + return BuildTree(text), placeholders + + +def ToTranslation(tree, placeholders): + """Converts the tree back to a translation, substituting the placeholders + back in as required. + """ + text = tree.ToString() + assert text.count(PLACEHOLDER_STRING) == len(placeholders) + transl = tclib.Translation() + for placeholder in placeholders: + index = text.find(PLACEHOLDER_STRING) + if index > 0: + transl.AppendText(text[:index]) + text = text[index + len(PLACEHOLDER_STRING):] + transl.AppendPlaceholder(placeholder) + if text: + transl.AppendText(text) + return transl + + +def PseudoLongStringMessage(message): + """Returns a pseudo-long string (en-XA) translation of the provided message. + + Args: + message: tclib.Message() + + Return: + tclib.Translation() + """ + + tree, placeholders = BuildTreeFromMessage(message) + # This will change after the transformation, so do it early. + n_words = tree.GetNumWords() + tree.Transform(lambda x: ''.join( + ACCENTED_STRINGS.get(letter, letter) for letter in x)) + transl = ToTranslation(tree, placeholders) + transl.AppendText(' ' + ' '.join(NUMBERS[i % len(NUMBERS)] + for i in range(n_words))) + + return transl + + +def PseudoRTLMessage(message): + """Returns a pseudo-RTL (ar-XB) translation of the provided message. + + Args: + message: tclib.Message() + + Return: + tclib.Translation() + """ + tree, placeholders = BuildTreeFromMessage(message) + tree.Transform(lambda text: ALPHABETIC_RUN.sub( + lambda run: RLO + run.group() + PDF, text)) + return ToTranslation(tree, placeholders)
diff --git a/tools/grit/grit/pseudolocales_unittest.py b/tools/grit/grit/pseudolocales_unittest.py new file mode 100755 index 0000000..3c5487e --- /dev/null +++ b/tools/grit/grit/pseudolocales_unittest.py
@@ -0,0 +1,281 @@ +#!/usr/bin/env python +# Copyright (c) 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +'''Unit tests for grit.pseudolocales''' + +from __future__ import print_function + +import sys +import os.path +if __name__ == '__main__': + sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +import unittest + +import six + +import grit.pseudolocales as pl + +from grit import tclib +import grit.extern.tclib + +PLACEHOLDER_NODE = pl.BasicVariable(pl.PLACEHOLDER_STRING) +VAR_NODE = pl.BasicVariable('{VAR}') + + +class TclibUnittest(unittest.TestCase): + def assertBuildTree(self, text, tree): + self.assertTreesEqual(pl.BuildTree(text), tree) + + def assertTreesEqual(self, lhs, rhs): + try: + self.assertSubtreesEqual(lhs, rhs) + except AssertionError as e: + print('Actual:', lhs, 'Expected:', rhs, sep='\n') + raise e + + def assertSubtreesEqual(self, lhs, rhs): + try: + self.assertIsInstance(lhs, rhs.__class__) + self.assertIsInstance(rhs, lhs.__class__) + self.assertEqual(lhs.text, rhs.text) + self.assertEqual(lhs.after, rhs.after) + self.assertEqual(len(lhs.children), len(rhs.children)) + except AssertionError as e: + print('Failing subtree actual:', + lhs, + 'Failing subtree expected:', + rhs, + sep='\n') + raise e + for lhs_child, rhs_child in zip(lhs.children, rhs.children): + self.assertSubtreesEqual(lhs_child, rhs_child) + + def testSplitTextBasic(self): + self.assertBuildTree('foo bar baz', pl.RawText('foo bar baz')) + + def testSplitTextTags(self): + self.assertBuildTree( + 'foo<a href="url">bar</a>baz', + pl.NodeSequence([ + pl.RawText('foo'), + pl.HtmlTag('<a href="url">'), + pl.RawText('bar'), + pl.HtmlTag('</a>'), + pl.RawText('baz'), + ])) + + def testSplitTextVariables(self): + self.assertBuildTree( + 'Downloaded by <a href="{PLACEHOLDER}">{PLACEHOLDER}</a>', + pl.NodeSequence([ + pl.RawText('Downloaded by '), + pl.HtmlTag('<a href="{PLACEHOLDER}">'), + pl.BasicVariable('{PLACEHOLDER}'), + pl.HtmlTag('</a>'), + ])) + + def testSplitTextWithCurlies(self): + self.assertBuildTree( + '''{COUNT, plural, + =0 {Open all in &incognito window} + =1 {Open in &incognito window} + other {Open all ({COUNT}) in &incognito window}}''', + pl.Plural('{COUNT, plural,\n ', [ + pl.PluralOption('=0 {', + [pl.RawText('Open all in &incognito window')]), + pl.PluralOption('=1 {', [pl.RawText('Open in &incognito window')]), + pl.PluralOption('other {', [ + pl.RawText('Open all ('), + pl.BasicVariable('{COUNT}'), + pl.RawText(') in &incognito window'), + ]), + ])) + + self.assertBuildTree( + '''{ATTEMPTS_LEFT, plural, + =1 {{0} attempt left} + other {{0}<a>attempts</a> left}}''', + pl.Plural('{ATTEMPTS_LEFT, plural,\n ', [ + pl.PluralOption( + '=1 {', [pl.BasicVariable('{0}'), + pl.RawText(' attempt left')]), + pl.PluralOption('other {', [ + pl.BasicVariable('{0}'), + pl.HtmlTag('<a>'), + pl.RawText('attempts'), + pl.HtmlTag('</a>'), + pl.RawText(' left') + ]) + ])) + + def testRawTextNumWords(self): + self.assertEqual(pl.RawText('hello').GetNumWords(), 1) + self.assertEqual(pl.RawText('hello world').GetNumWords(), 2) + self.assertEqual(pl.RawText(' ').GetNumWords(), 0) + self.assertEqual(pl.RawText('hello \n world').GetNumWords(), 2) + self.assertEqual(pl.RawText('that\'s nice, right').GetNumWords(), 3) + self.assertEqual(pl.RawText('1 2 3 4 5').GetNumWords(), 5) + + def testTreeNumWords(self): + self.assertEqual(pl.HtmlTag('<a href="blah">').GetNumWords(), 0) + self.assertEqual(pl.BasicVariable('{COUNT}').GetNumWords(), 1) + + self.assertEqual( + pl.NodeSequence([pl.RawText('hi'), + pl.RawText('World')]).GetNumWords(), 2) + self.assertEqual( + pl.PluralOption( + 'other {', + [pl.RawText('hello'), pl.RawText('World')]).GetNumWords(), 2) + self.assertEqual( + pl.Plural('{COUNT, plural, {', [ + pl.PluralOption('=0 {', [pl.RawText('1 2')]), + pl.PluralOption('=0 {', [pl.RawText('1 2 3')]), + pl.PluralOption('=0 {', [pl.RawText('1 2 3 4 5 6 7 8 9 10')]), + ]).GetNumWords(), 10) + + def assertTransformsInto(self, initial, expected): + initial.Transform(lambda x: x.title()) + self.assertTreesEqual(initial, expected) + + def testTransform(self): + self.assertTransformsInto(pl.RawText('HI WORLD'), pl.RawText('Hi World')) + self.assertTransformsInto(pl.BasicVariable('{HELLO}'), + pl.BasicVariable('{HELLO}')) + self.assertTransformsInto(pl.HtmlTag('<a>'), pl.HtmlTag('<a>')) + self.assertTransformsInto( + pl.NodeSequence( + [pl.RawText('HELLO'), + pl.HtmlTag('<a>'), + pl.RawText('WORLD')]), + pl.NodeSequence( + [pl.RawText('Hello'), + pl.HtmlTag('<a>'), + pl.RawText('World')])) + self.assertTransformsInto( + pl.Plural('{ATTEMPTS_LEFT, plural,\n ', [ + pl.PluralOption('=1 {', [pl.RawText('hello')]), + pl.PluralOption('other {', [pl.RawText('world')]) + ]), + pl.Plural('{ATTEMPTS_LEFT, plural,\n ', [ + pl.PluralOption('=1 {', [pl.RawText('Hello')]), + pl.PluralOption('other {', [pl.RawText('World')]) + ])) + + def testToString(self): + self.assertEqual(pl.RawText('Hello world').ToString(), 'Hello world') + self.assertEqual(pl.BasicVariable('{0}').ToString(), '{0}') + self.assertEqual(pl.HtmlTag('<a>').ToString(), '<a>') + self.assertEqual( + pl.NodeSequence([pl.RawText('Hello'), + pl.RawText('World')]).ToString(), 'HelloWorld') + self.assertEqual( + pl.Plural('{ATTEMPTS_LEFT, plural,\n ', [ + pl.PluralOption('=1 {', [pl.RawText('hello')]), + pl.PluralOption('other {', [pl.RawText('world')]) + ]).ToString(), + '{ATTEMPTS_LEFT, plural,\n =1 {hello}\nother {world}\n}') + + def testBuildAndUnbuildTree(self): + p1 = tclib.Placeholder(u'USERNAME', '%s', 'foo') + p2 = tclib.Placeholder(u'EMAIL', '%s', 'bar') + + msg = tclib.Message() + msg.AppendText('hello') + msg.AppendPlaceholder(p1) + msg.AppendPlaceholder(p2) + msg.AppendText('world') + + tree, placeholders = pl.BuildTreeFromMessage(msg) + self.assertTreesEqual( + tree, + pl.NodeSequence([ + pl.RawText('hello'), PLACEHOLDER_NODE, PLACEHOLDER_NODE, + pl.RawText('world') + ])) + self.assertEqual(placeholders, [p1, p2]) + + transl = pl.ToTranslation(tree, placeholders) + self.assertEqual(transl.GetContent(), ['hello', p1, p2, 'world']) + + def testPseudolocales(self): + p1 = tclib.Placeholder(u'USERNAME', '%s', 'foo') + p2 = tclib.Placeholder(u'EMAIL', '%s', 'bar') + msg = tclib.Message() + msg.AppendText('h_') + msg.AppendPlaceholder(p1) + msg.AppendPlaceholder(p2) + msg.AppendText('w') + + self.assertEqual( + pl.PseudoLongStringMessage(msg).GetContent(), + [u'\u0125_', p1, p2, u'\u0175', ' one two three four']) + + msg.AppendText('hello world') + self.assertEqual( + pl.PseudoRTLMessage(msg).GetContent(), + [u'\u202eh\u202c_', p1, p2, u'\u202ewhello\u202c \u202eworld\u202c']) + + # If it fails to translate with prod messages, add the failure to here to + # make sure it doesn't happen again. + def testProdFailures(self): + p1 = tclib.Placeholder(u'USERNAME', '%s', 'foo') + + msg = tclib.Message() + msg.AppendText(u'{LINE_COUNT, plural,\n =1 {<1 line not shown>}\n' + ' other {<') + msg.AppendPlaceholder(p1) + msg.AppendText(u' lines not shown>}\n}') + tree, _ = pl.BuildTreeFromMessage(msg) + self.assertTreesEqual( + tree, + pl.Plural('{LINE_COUNT, plural,\n ', [ + pl.PluralOption('=1 {', [pl.RawText('<1 line not shown>')]), + pl.PluralOption('other {', [ + pl.RawText('<'), PLACEHOLDER_NODE, + pl.RawText(' lines not shown>') + ]) + ])) + + msg = tclib.Message() + msg.AppendText(u'{1, plural,\n \n =1 {Rated ') + msg.AppendPlaceholder(p1) + msg.AppendText(u' by one user.}\n other{Rated ') + msg.AppendPlaceholder(p1) + msg.AppendText(u' by # users.}}') + tree, _ = pl.BuildTreeFromMessage(msg) + self.assertTreesEqual( + tree, + pl.Plural('{1, plural,\n \n ', [ + pl.PluralOption('=1 {', [ + pl.RawText('Rated '), PLACEHOLDER_NODE, + pl.RawText(' by one user.') + ]), + pl.PluralOption('other{', [ + pl.RawText('Rated '), PLACEHOLDER_NODE, + pl.RawText(' by # users.') + ]), + ])) + + self.assertTreesEqual( + pl.BuildTree('{0, plural, offset:2\n' + ' =1 {{VAR}}\n' + ' =2 {{VAR}, {VAR}}\n' + ' other {{VAR}, {VAR}, and # more}\n' + ' }'), + pl.Plural('{0, plural, offset:2\n ', [ + pl.PluralOption('=1 {', [VAR_NODE]), + pl.PluralOption('=2 {', + [VAR_NODE, pl.RawText(', '), VAR_NODE]), + pl.PluralOption('other {', [ + VAR_NODE, + pl.RawText(', '), VAR_NODE, + pl.RawText(', and # more') + ]), + ])) + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/grit/grit/testdata/chrome/app/generated_resources.grd b/tools/grit/grit/testdata/chrome/app/generated_resources.grd index c2efb77..65c96e28 100644 --- a/tools/grit/grit/testdata/chrome/app/generated_resources.grd +++ b/tools/grit/grit/testdata/chrome/app/generated_resources.grd
@@ -46,7 +46,6 @@ <output filename="generated_resources_eu.pak" type="data_package" lang="eu" /> </if> <output filename="generated_resources_fa.pak" type="data_package" lang="fa" /> - <output filename="generated_resources_fake-bidi.pak" type="data_package" lang="fake-bidi" /> <output filename="generated_resources_fi.pak" type="data_package" lang="fi" /> <output filename="generated_resources_fil.pak" type="data_package" lang="fil" /> <output filename="generated_resources_fr.pak" type="data_package" lang="fr" /> @@ -106,6 +105,10 @@ <output filename="generated_resources_vi.pak" type="data_package" lang="vi" /> <output filename="generated_resources_zh-CN.pak" type="data_package" lang="zh-CN" /> <output filename="generated_resources_zh-TW.pak" type="data_package" lang="zh-TW" /> + + <!-- Pseudolocales --> + <output filename="generated_resources_ar-XB.pak" type="data_package" lang="ar-XB" /> + <output filename="generated_resources_en-XA.pak" type="data_package" lang="en-XA" /> </outputs> <translations> <file path="resources/generated_resources_am.xtb" lang="am" />
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index f614568..ad9404c42c 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1018,6 +1018,14 @@ </int> </enum> +<enum name="AccountManagerAccountAdditionResultStatus"> + <int value="0" label="Success"/> + <int value="1" label="Already in progress"/> + <int value="2" label="Cancelled by user"/> + <int value="3" label="Network error"/> + <int value="4" label="Unexpected response"/> +</enum> + <enum name="AccountManagerAccountAdditionSource"> <int value="0" label="Add account button in Settings"/> <int value="1" label="Re-auth account button in Settings"/> @@ -14153,7 +14161,11 @@ <int value="0" label="CRAS_HFP_BATTERY_INDICATOR_NONE"/> <int value="1" label="CRAS_HFP_BATTERY_INDICATOR_HFP"/> <int value="2" label="CRAS_HFP_BATTERY_INDICATOR_APPLE"/> - <int value="3" label="CRAS_HFP_BATTERY_INDICATOR_BOTH"/> + <int value="3" label="CRAS_HFP_BATTERY_INDICATOR_HFP_APPLE"/> + <int value="4" label="CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS"/> + <int value="5" label="CRAS_HFP_BATTERY_INDICATOR_HFP_PLANTRONICS"/> + <int value="6" label="CRAS_HFP_BATTERY_INDICATOR_APPLE_PLANTRONICS"/> + <int value="7" label="CRAS_HFP_BATTERY_INDICATOR_ALL"/> </enum> <enum name="CrasHfpCodec">
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index e12d809b..c60f9c9 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -33,6 +33,18 @@ <variant name=".Unknown" summary="unknown but not the default search engine"/> </variants> +<histogram name="AccountManager.AccountAdditionResultStatus" + enum="AccountManagerAccountAdditionResultStatus" expires_after="2022-02-01"> + <owner>sinhak@chromium.org</owner> + <owner>anastasiian@chromium.org</owner> + <summary> + Records the result of in-session account addition (or re-authentication) + triggers on Chrome OS. This is recorded whenever an in-session account + addition (or re-authentication) is triggered and user finishes or cancels + the flow. + </summary> +</histogram> + <histogram name="AccountManager.AccountAdditionSource" enum="AccountManagerAccountAdditionSource" expires_after="2021-08-01"> <owner>sinhak@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index b971d287..548cc875 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,12 +1,12 @@ { "trace_processor_shell": { "win": { - "hash": "7995b43f2e8f135027d99cb7fe8100e9f7e7171d", - "remote_path": "perfetto_binaries/trace_processor_shell/win/52852a8ec96d2db2a97fffd2ea9a62e58d65845d/trace_processor_shell.exe" + "hash": "f364592dea9f49f219a0b9340b49ff07b8aabe4a", + "remote_path": "perfetto_binaries/trace_processor_shell/win/7cb370fb0a2f055e7781a0924e3a275d7adedf6b/trace_processor_shell.exe" }, "mac": { - "hash": "7961eef6b83b7d5b2c867cc4b2494c6c1d94f6c4", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/52852a8ec96d2db2a97fffd2ea9a62e58d65845d/trace_processor_shell" + "hash": "c0dca9becba53487e5f45f6f5696929787999da7", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/7cb370fb0a2f055e7781a0924e3a275d7adedf6b/trace_processor_shell" }, "linux": { "hash": "9a68a5070bda85da38a566f8dbc59ca3da01aac4",
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc index 1a44931..c119a82 100644 --- a/ui/accessibility/ax_node_position_unittest.cc +++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -3631,8 +3631,10 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPositionAndEmptyTextSandwich) { // This test updates the tree structure to test a specific edge case - // `AsLeafTextPosition` when there is an empty leaf text node between - // two non-empty text nodes. Empty leaf nodes should be skipped when finding - // the leaf equivalent position. + // two non-empty text nodes. Empty leaf nodes should not be skipped when + // finding the leaf equivalent position, otherwise important controls (e.g. + // buttons) that are unlabelled could accidentally be skipped while + // navigating. AXNodeData root_data; root_data.id = 1; root_data.role = ax::mojom::Role::kRootWebArea; @@ -3659,7 +3661,7 @@ // Create a text position on the root pointing to just after the // first static text leaf node. Even though the button has empty inner text, - // still it should not be skipped when finding the leaf text position. + // still, it should not be skipped when finding the leaf text position. TestPositionType text_position = AXNodePosition::CreateTextPosition( GetTreeID(), root_data.id, 9 /* text_offset */, ax::mojom::TextAffinity::kDownstream); @@ -3687,6 +3689,156 @@ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity()); } +TEST_F(AXPositionTest, AsLeafTextPositionWithTextPositionAndEmbeddedObject) { + g_ax_embedded_object_behavior = AXEmbeddedObjectBehavior::kExposeCharacter; + + // ++1 kRootWebArea "<embedded_object><embedded_object>" + // ++++2 kImage alt="Test image" + // ++++3 kParagraph "<embedded_object>" + // ++++++4 kLink "Hello" + // ++++++++5 kStaticText "Hello" + // ++++++++++6 kInlineTextBox "Hello" + AXNodeData root; + AXNodeData image; + AXNodeData paragraph; + AXNodeData link; + AXNodeData static_text; + AXNodeData inline_box; + + root.id = 1; + image.id = 2; + paragraph.id = 3; + link.id = 4; + static_text.id = 5; + inline_box.id = 6; + + root.role = ax::mojom::Role::kRootWebArea; + root.child_ids = {image.id, paragraph.id}; + + image.role = ax::mojom::Role::kImage; + image.SetName("Test image"); + // Alt text should not appear in the tree's text representation, so we need to + // set the right NameFrom. + image.SetNameFrom(ax::mojom::NameFrom::kAttribute); + + paragraph.role = ax::mojom::Role::kParagraph; + paragraph.child_ids = {link.id}; + + link.role = ax::mojom::Role::kLink; + link.AddState(ax::mojom::State::kLinked); + link.child_ids = {static_text.id}; + + static_text.role = ax::mojom::Role::kStaticText; + static_text.SetName("Hello"); + static_text.child_ids = {inline_box.id}; + + inline_box.role = ax::mojom::Role::kInlineTextBox; + inline_box.SetName("Hello"); + + SetTree( + CreateAXTree({root, image, paragraph, link, static_text, inline_box})); + + TestPositionType before_root = AXNodePosition::CreateTextPosition( + GetTreeID(), root.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, before_root); + TestPositionType middle_root = AXNodePosition::CreateTextPosition( + GetTreeID(), root.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, middle_root); + TestPositionType middle_root_upstream = AXNodePosition::CreateTextPosition( + GetTreeID(), root.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + ASSERT_NE(nullptr, middle_root_upstream); + TestPositionType after_root = AXNodePosition::CreateTextPosition( + GetTreeID(), root.id, 2 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, after_root); + // A position with an upstream affinity after the root should make no + // difference compared with a downstream affinity, but we'll test it for + // completeness. + TestPositionType after_root_upstream = AXNodePosition::CreateTextPosition( + GetTreeID(), root.id, 2 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + ASSERT_NE(nullptr, after_root_upstream); + + TestPositionType before_image = AXNodePosition::CreateTextPosition( + GetTreeID(), image.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, before_image); + // Alt text should not appear in the tree's text representation, but since the + // image is both a character and a word boundary it should be replaced by the + // "embedded object replacement character" in the text representation. + TestPositionType after_image = AXNodePosition::CreateTextPosition( + GetTreeID(), image.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, after_image); + + TestPositionType before_paragraph = AXNodePosition::CreateTextPosition( + GetTreeID(), paragraph.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, before_paragraph); + // The paragraph has a link inside it, so it will only expose a single + // "embedded object replacement character". + TestPositionType after_paragraph = AXNodePosition::CreateTextPosition( + GetTreeID(), paragraph.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, after_paragraph); + // A position with an upstream affinity after the paragraph should make no + // difference compared with a downstream affinity, but we'll test it for + // completeness. + TestPositionType after_paragraph_upstream = + AXNodePosition::CreateTextPosition(GetTreeID(), paragraph.id, + 1 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + ASSERT_NE(nullptr, after_paragraph_upstream); + + TestPositionType before_link = AXNodePosition::CreateTextPosition( + GetTreeID(), link.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, before_link); + // The llink has the text "Hello" inside it. + TestPositionType after_link = AXNodePosition::CreateTextPosition( + GetTreeID(), link.id, 5 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, after_link); + // A position with an upstream affinity after the link should make no + // difference compared with a downstream affinity, but we'll test it for + // completeness. + TestPositionType after_link_upstream = AXNodePosition::CreateTextPosition( + GetTreeID(), link.id, 5 /* text_offset */, + ax::mojom::TextAffinity::kUpstream); + ASSERT_NE(nullptr, after_link_upstream); + + TestPositionType before_inline_box = AXNodePosition::CreateTextPosition( + GetTreeID(), inline_box.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, before_inline_box); + // The inline box has the text "Hello" inside it. + TestPositionType after_inline_box = AXNodePosition::CreateTextPosition( + GetTreeID(), inline_box.id, 5 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, after_inline_box); + + EXPECT_EQ(*before_root->AsLeafTextPosition(), *before_image); + EXPECT_EQ(*middle_root->AsLeafTextPosition(), *before_inline_box); + // As mentioned above, alt text should not appear in the tree's text + // representation, but since the image is both a character and a word boundary + // it should be replaced by the "embedded object replacement character" in the + // text representation. + EXPECT_EQ(*middle_root_upstream->AsLeafTextPosition(), *after_image); + EXPECT_EQ(*after_root->AsLeafTextPosition(), *after_inline_box); + EXPECT_EQ(*after_root_upstream->AsLeafTextPosition(), *after_inline_box); + + EXPECT_EQ(*before_paragraph->AsLeafTextPosition(), *before_inline_box); + EXPECT_EQ(*after_paragraph->AsLeafTextPosition(), *after_inline_box); + EXPECT_EQ(*after_paragraph_upstream->AsLeafTextPosition(), *after_inline_box); + + EXPECT_EQ(*before_link->AsLeafTextPosition(), *before_inline_box); + EXPECT_EQ(*after_link->AsLeafTextPosition(), *after_inline_box); + EXPECT_EQ(*after_link_upstream->AsLeafTextPosition(), *after_inline_box); +} + TEST_F(AXPositionTest, AsUnignoredPosition) { // ++root_data // ++++static_text_data_1 "1"
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index 9ba5212..b5e5abf 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -1409,7 +1409,7 @@ // No need to check for "before text" positions here because they are only // present on leaf anchor nodes. AXPositionInstance text_position = AsTextPosition(); - int adjusted_offset = text_position->text_offset_; + int offset_in_parent = text_position->text_offset_; do { AXPositionInstance child = text_position->CreateChildPositionAt(0); DCHECK(!child->IsNullPosition()); @@ -1422,11 +1422,13 @@ // unignored position will turn into an ignored one after calling this // method. for (int i = 1; - i < text_position->AnchorChildCount() && adjusted_offset >= 0; ++i) { - const int child_length = child->MaxTextOffsetInParent(); - const bool contributes_no_text_in_parent = !child_length; + i < text_position->AnchorChildCount() && offset_in_parent >= 0; + ++i) { + const int child_length_in_parent = child->MaxTextOffsetInParent(); + const bool contributes_no_text_in_parent = + (child_length_in_parent == 0); const bool is_anchor_unignored = !child->GetAnchor()->IsIgnored(); - if (adjusted_offset == 0 && contributes_no_text_in_parent && + if (offset_in_parent == 0 && contributes_no_text_in_parent && is_anchor_unignored) { // If the text offset corresponds to multiple child positions because // some of the children have no inner text or hypertext, the above @@ -1435,11 +1437,11 @@ break; } - if (adjusted_offset < child_length) + if (offset_in_parent < child_length_in_parent) break; if (affinity_ == ax::mojom::TextAffinity::kUpstream && - adjusted_offset == child_length) { + offset_in_parent == child_length_in_parent) { // Maintain upstream affinity so that we'll be able to choose the // correct leaf anchor if the text offset is right on the boundary // between two leaves. @@ -1448,14 +1450,30 @@ } child = text_position->CreateChildPositionAt(i); - adjusted_offset -= child_length; + offset_in_parent -= child_length_in_parent; + } + + // The text offset provided by our parent position might need to be + // adjusted, if this is an "after text" position and our anchor node is an + // embedded object (as determined by `IsEmbeddedObjectInParent()`). + // ++kRootWebArea "<embedded_object>" + // ++++kParagraph "Hello" + // TextPosition anchor=kRootWebArea text_offset=1 + // should be translated into the following text position + // TextPosition anchor=kParagraph text_offset=5 annotated_text=Hello<> + // and not into the following one + // TextPosition anchor=kParagraph text_offset=1 annotated_text=<H>ello + if (child->IsEmbeddedObjectInParent() && + offset_in_parent == child->MaxTextOffsetInParent()) { + offset_in_parent -= child->MaxTextOffsetInParent(); + offset_in_parent += child->MaxTextOffset(); } text_position = std::move(child); } while (!text_position->IsLeaf()); DCHECK(text_position->IsLeafTextPosition()); - text_position->text_offset_ = adjusted_offset; + text_position->text_offset_ = offset_in_parent; // A leaf Text position is always downstream since there is no ambiguity as // to whether it refers to the end of the current or the start of the next // line.
diff --git a/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js b/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js index 0fbf77b..7e76d6b 100644 --- a/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js +++ b/ui/file_manager/file_manager/background/js/runtime_loaded_test_util.js
@@ -1228,3 +1228,12 @@ test.util.sync.progressCenterNeverNotifyCompleted = () => { window.background.progressCenter.neverNotifyCompleted(); }; + +/** + * Waits for the background page to initialize. + * @param {function()} callback Callback function called when background page + * has finished initializing. + */ +test.util.async.waitForBackgroundReady = callback => { + window.background.ready(callback); +};
diff --git a/ui/file_manager/file_manager/foreground/elements/BUILD.gn b/ui/file_manager/file_manager/foreground/elements/BUILD.gn index fb41fe3..52fb9f5 100644 --- a/ui/file_manager/file_manager/foreground/elements/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
@@ -445,6 +445,7 @@ js_file = "icons.m.js" html_file = "icons.html" html_type = "iron-iconset" + preserve_url_scheme = true } js_library("xf_button") {
diff --git a/ui/file_manager/integration_tests/file_manager/background.js b/ui/file_manager/integration_tests/file_manager/background.js index 4dadf4b..a45a57e 100644 --- a/ui/file_manager/integration_tests/file_manager/background.js +++ b/ui/file_manager/integration_tests/file_manager/background.js
@@ -661,3 +661,22 @@ const flag = dialog.attributes['single-partition-format'] || ''; return !!flag; } + +/** + * Waits until the MediaApp/Backlight shows up. + */ +async function waitForMediaApp() { + // The MediaApp window should open for the image. + const caller = getCaller(); + const mediaAppAppId = 'jhdjimmaggjajfjphpljagpgkidjilnj'; + await repeatUntil(async () => { + const result = await sendTestMessage({ + name: 'hasSwaStarted', + swaAppId: mediaAppAppId, + }); + + if (result !== 'true') { + return pending(caller, 'Waiting for MediaApp to open'); + } + }); +}
diff --git a/ui/file_manager/integration_tests/file_manager/drive_specific.js b/ui/file_manager/integration_tests/file_manager/drive_specific.js index d737981..3295969 100644 --- a/ui/file_manager/integration_tests/file_manager/drive_specific.js +++ b/ui/file_manager/integration_tests/file_manager/drive_specific.js
@@ -24,6 +24,16 @@ ]; /** + * Expected text shown in the Enable Docs Offline dialog. + * + * @type {string} + * @const + */ +const ENABLE_DOCS_OFFLINE_MESSAGE = + 'Enable Google Docs Offline to make Docs, Sheets and Slides ' + + 'available offline.'; + +/** * Returns the steps to start a search for 'hello' and wait for the * autocomplete results to appear. */ @@ -57,6 +67,22 @@ } /** + * Opens the Enable Docs Offline dialog and waits for it to appear in the given + * |appId| window. + * + * @param {string} appId + */ +async function openAndWaitForEnableDocsOfflineDialog(appId) { + // Simulate Drive signalling Files App to open a dialog. + await sendTestMessage({name: 'displayEnableDocsOfflineDialog'}); + + // Check: the Enable Docs Offline dialog should appear. + const dialogText = await remoteCall.waitForElement( + appId, '.cr-dialog-container.shown .cr-dialog-text'); + chrome.test.assertEq(ENABLE_DOCS_OFFLINE_MESSAGE, dialogText.text); +} + +/** * Tests opening the "Offline" on the sidebar navigation by clicking the icon, * and checks contents of the file list. Only the entries "available offline" * should be shown. "Available offline" entries are hosted documents and the @@ -729,12 +755,8 @@ chrome.test.assertTrue( await remoteCall.callRemoteTestUtil('openFile', appId, ['deep.jpg'])); - // The Gallery window should open with the image in it. - const galleryAppId = await galleryApp.waitForWindow('gallery.html'); - await galleryApp.waitForSlideImage(galleryAppId, 100, 100, 'deep'); - chrome.test.assertTrue( - await galleryApp.closeWindowAndWait(galleryAppId), - 'Failed to close Gallery window'); + // The MediaApp window should open for the image. + await waitForMediaApp(); }; /** @@ -763,12 +785,8 @@ chrome.test.assertTrue( await remoteCall.callRemoteTestUtil('openFile', appId, ['deep.jpg'])); - // The Gallery window should open with the image in it. - const galleryAppId = await galleryApp.waitForWindow('gallery.html'); - await galleryApp.waitForSlideImage(galleryAppId, 100, 100, 'deep'); - chrome.test.assertTrue( - await galleryApp.closeWindowAndWait(galleryAppId), - 'Failed to close Gallery window'); + // The MediaApp window should open for the image. + await waitForMediaApp(); }; /** @@ -825,3 +843,96 @@ await remoteCall.waitForElementLost( appId, '#offline-info-banner:not([hidden])'); }; + +/** + * Tests that the Enable Docs Offline dialog appears in the Files App. + */ +testcase.driveEnableDocsOfflineDialog = async () => { + // Open Files app on Drive. + const appId = await setupAndWaitUntilReady(RootPath.DRIVE, []); + + // Open the Enable Docs Offline dialog. + await openAndWaitForEnableDocsOfflineDialog(appId); + + // Click on the ok button. + await remoteCall.waitAndClickElement( + appId, '.cr-dialog-container.shown .cr-dialog-ok'); + + // Check: the last dialog result should be 1 (accept). + let lastResult = await sendTestMessage({name: 'getLastDriveDialogResult'}); + chrome.test.assertEq('1', lastResult); + + // Open the Enable Docs Offline dialog. + await openAndWaitForEnableDocsOfflineDialog(appId); + + // Click on the cancel button. + await remoteCall.waitAndClickElement( + appId, '.cr-dialog-container.shown .cr-dialog-cancel'); + + // Check: the last dialog result should be 2 (reject). + lastResult = await sendTestMessage({name: 'getLastDriveDialogResult'}); + chrome.test.assertEq('2', lastResult); + + // Open the Enable Docs Offline dialog. + await openAndWaitForEnableDocsOfflineDialog(appId); + + // Close Files App. + await remoteCall.closeWindowAndWait(appId); + + // Check: the last dialog result should be 3 (dismiss). + lastResult = await sendTestMessage({name: 'getLastDriveDialogResult'}); + chrome.test.assertEq('3', lastResult); +}; + +/** + * Tests that the Enable Docs Offline dialog launches a Files App window if + * there are none open. + */ +testcase.driveEnableDocsOfflineDialogWithoutWindow = async () => { + // Wait for the background page to listen to events from the browser. + await remoteCall.callRemoteTestUtil('waitForBackgroundReady', null, []); + + // Simulate Drive signalling Files App to open a dialog. + await sendTestMessage({name: 'displayEnableDocsOfflineDialog'}); + + // Check: A Files App window should appear. + const appId = await remoteCall.waitForWindow('files#'); + + // Check: the Enable Docs Offline dialog should appear. + const dialogText = await remoteCall.waitForElement( + appId, '.cr-dialog-container.shown .cr-dialog-text'); + chrome.test.assertEq(ENABLE_DOCS_OFFLINE_MESSAGE, dialogText.text); + + // Click on the ok button. + await remoteCall.waitAndClickElement( + appId, '.cr-dialog-container.shown .cr-dialog-ok'); + + // Check: the last dialog result should be 1 (accept). + const lastResult = await sendTestMessage({name: 'getLastDriveDialogResult'}); + chrome.test.assertEq('1', lastResult); +}; + +/** + * Tests that the Enable Docs Offline dialog appears in the focused window if + * there are more than one Files App windows open. + */ +testcase.driveEnableDocsOfflineDialogMultipleWindows = async () => { + // Open two Files app windows on Drive, and the second one should be focused. + const appId1 = await setupAndWaitUntilReady(RootPath.DRIVE, []); + const appId2 = await setupAndWaitUntilReady(RootPath.DRIVE, []); + + // Open the Enable Docs Offline dialog and check that it appears in the second + // window. + await openAndWaitForEnableDocsOfflineDialog(appId2); + + // Check: there should be no dialog shown in the first window. + await remoteCall.waitForElementLost(appId1, '.cr-dialog-container.shown'); + + // Click on the ok button in the second window. + await remoteCall.waitAndClickElement( + appId2, '.cr-dialog-container.shown .cr-dialog-ok'); + + // Check: the last dialog result should be 1 (accept). + const lastResult = await sendTestMessage({name: 'getLastDriveDialogResult'}); + chrome.test.assertEq('1', lastResult); +};
diff --git a/ui/file_manager/integration_tests/file_manager/launcher_search.js b/ui/file_manager/integration_tests/file_manager/launcher_search.js index 3dbf9d3a..ea9e5f8 100644 --- a/ui/file_manager/integration_tests/file_manager/launcher_search.js +++ b/ui/file_manager/integration_tests/file_manager/launcher_search.js
@@ -33,18 +33,8 @@ await remoteCall.callRemoteTestUtil( 'launcherSearchOpenResult', null, [fileURLs[0]]); - // Files app opens Gallery for images, so check Gallery app has been - // launched. - const galleryAppId = await galleryApp.waitForWindow('gallery.html'); - - // Check the image is displayed. - const imageNameNoExtension = imageName.split('.')[0]; - - // Check: the slide image element should appear. - chrome.test.assertTrue( - !!await galleryApp.waitForSlideImage( - galleryAppId, 0, 0, imageNameNoExtension), - 'Failed to find the slide image element'); + // Files app opens the MediaApp for images, so wait for it. + await waitForMediaApp(); }; const hostedDocument = Object.assign(
diff --git a/ui/file_manager/integration_tests/file_manager/open_image_backlight.js b/ui/file_manager/integration_tests/file_manager/open_image_backlight.js deleted file mode 100644 index 6d8fd93..0000000 --- a/ui/file_manager/integration_tests/file_manager/open_image_backlight.js +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -'use strict'; - -(() => { - const BACKLIGHT_APP_ID = 'jhdjimmaggjajfjphpljagpgkidjilnj'; - - /** Tests opening an image opens Backlight. */ - testcase.imageOpenBacklight = async () => { - await sendTestMessage({ - name: 'expectFileTask', - fileNames: [ENTRIES.image3.targetPath], - openType: 'launch' - }); - - // Open Files.App on Downloads, add image3 to Downloads. - const filesAppId = - await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.image3], []); - - // Open the image file in Files app. - chrome.test.assertTrue(await remoteCall.callRemoteTestUtil( - 'openFile', filesAppId, [ENTRIES.image3.targetPath])); - - // Wait for Backlight to open. - const caller = getCaller(); - await repeatUntil(async () => { - const result = await sendTestMessage({ - name: 'hasSwaStarted', - swaAppId: BACKLIGHT_APP_ID, - }); - - if (result !== 'true') { - return pending(caller, 'Waiting for Backlight to open'); - } - }); - }; -})();
diff --git a/ui/file_manager/integration_tests/file_manager/open_image_media_app.js b/ui/file_manager/integration_tests/file_manager/open_image_media_app.js new file mode 100644 index 0000000..610dcc42 --- /dev/null +++ b/ui/file_manager/integration_tests/file_manager/open_image_media_app.js
@@ -0,0 +1,62 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +(() => { + /** + * Tests opening an image opens MediaApp/Backlight. + * @param {string} path Directory path (Downloads or Drive). + */ + async function imageOpen(path) { + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.image3.targetPath], + openType: 'launch' + }); + + // Open Files.App on Downloads, add image3 to Downloads. + const filesAppId = + await setupAndWaitUntilReady(path, [ENTRIES.image3], [ENTRIES.image3]); + + // Open the image file in Files app. + chrome.test.assertTrue(await remoteCall.callRemoteTestUtil( + 'openFile', filesAppId, [ENTRIES.image3.targetPath])); + + // Wait for the expected 1 a11y announce. + const caller = getCaller(); + await repeatUntil(async () => { + const a11yMessages = await remoteCall.callRemoteTestUtil( + 'getA11yAnnounces', filesAppId, []); + + if (a11yMessages.length === 1) { + return true; + } + + return pending( + caller, + 'Waiting for 1 a11y message, got: ' + JSON.stringify(a11yMessages)); + }); + + // Fetch A11y messages. + const a11yMessages = + await remoteCall.callRemoteTestUtil('getA11yAnnounces', filesAppId, []); + + // Check that opening the file was announced to screen reader. + chrome.test.assertEq(1, a11yMessages.length); + chrome.test.assertEq('Opening file image3.jpg.', a11yMessages[0]); + + // Wait for MediaApp to open. + await waitForMediaApp(); + } + + + testcase.imageOpenMediaAppDownloads = () => { + return imageOpen(RootPath.DOWNLOADS); + }; + + testcase.imageOpenMediaAppDrive = () => { + return imageOpen(RootPath.DRIVE); + }; +})();
diff --git a/ui/file_manager/integration_tests/file_manager/zip_files.js b/ui/file_manager/integration_tests/file_manager/zip_files.js index d9725d9..c7bee573 100644 --- a/ui/file_manager/integration_tests/file_manager/zip_files.js +++ b/ui/file_manager/integration_tests/file_manager/zip_files.js
@@ -117,6 +117,29 @@ }; /** + * Tests that Files app's zip implementation notify FileTasks when mounted. + */ +testcase.zipNotifyFileTasks = async () => { + await sendTestMessage({ + name: 'expectFileTask', + fileNames: [ENTRIES.zipArchive.targetPath], + openType: 'launch' + }); + + // Open Files app on Downloads containing a zip file. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, [ENTRIES.zipArchive], []); + + // Open the zip file. + chrome.test.assertTrue( + !!await remoteCall.callRemoteTestUtil('openFile', appId, ['archive.zip']), + 'openFile failed'); + + // Wait for the zip archive to mount. + await remoteCall.waitForElement(appId, `[scan-completed="archive.zip"]`); +}; + +/** * Tests zip file, with absolute paths, open (aka unzip) from Downloads. */ testcase.zipFileOpenDownloadsWithAbsolutePaths = async () => {
diff --git a/ui/file_manager/integration_tests/file_manager_test_manifest.json b/ui/file_manager/integration_tests/file_manager_test_manifest.json index f506869..a5d4986 100644 --- a/ui/file_manager/integration_tests/file_manager_test_manifest.json +++ b/ui/file_manager/integration_tests/file_manager_test_manifest.json
@@ -38,7 +38,7 @@ "file_manager/metrics.js", "file_manager/my_files.js", "file_manager/open_audio_files.js", - "file_manager/open_image_backlight.js", + "file_manager/open_image_media_app.js", "file_manager/open_image_files.js", "file_manager/open_sniffed_files.js", "file_manager/open_video_files.js",
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc index 67f8897..cfb2318 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
@@ -706,7 +706,7 @@ ViewAXPlatformNodeDelegate* submenu = submenu_accessibility(); EXPECT_FALSE(submenu->GetData().HasState(ax::mojom::State::kFocusable)); - EXPECT_EQ(submenu->GetChildCount(), 7); + EXPECT_EQ(submenu->GetChildCount(), 8); EXPECT_EQ(submenu->GetData().role, ax::mojom::Role::kMenu); EXPECT_EQ(submenu->GetData().GetHasPopup(), ax::mojom::HasPopup::kMenu); @@ -811,8 +811,8 @@ EXPECT_FALSE(separator_item->GetData().IsSelectable()); EXPECT_FALSE(separator_item->GetData().GetBoolAttribute( ax::mojom::BoolAttribute::kSelected)); - EXPECT_TRUE(separator_item->IsInvisibleOrIgnored()); - EXPECT_TRUE(separator_item->GetData().IsInvisibleOrIgnored()); + EXPECT_FALSE(separator_item->IsInvisibleOrIgnored()); + EXPECT_FALSE(separator_item->GetData().IsInvisibleOrIgnored()); EXPECT_EQ(separator_item->GetData().role, ax::mojom::Role::kSplitter); EXPECT_EQ(separator_item->GetData().GetHasPopup(), ax::mojom::HasPopup::kFalse); @@ -821,7 +821,7 @@ EXPECT_FALSE(separator_item->GetData().HasIntAttribute( ax::mojom::IntAttribute::kSetSize)); EXPECT_EQ(separator_item->GetChildCount(), 0); - EXPECT_EQ(separator_item->GetIndexInParent(), -1); + EXPECT_EQ(separator_item->GetIndexInParent(), 5); // MenuItemView::Type::kHighlighted ViewAXPlatformNodeDelegate* highlighted_item = view_accessibility(items[6]); @@ -838,7 +838,7 @@ EXPECT_EQ(highlighted_item->GetPosInSet(), 6); EXPECT_EQ(highlighted_item->GetSetSize(), 7); EXPECT_EQ(highlighted_item->GetChildCount(), 0); - EXPECT_EQ(highlighted_item->GetIndexInParent(), 5); + EXPECT_EQ(highlighted_item->GetIndexInParent(), 6); // MenuItemView::Type::kTitle ViewAXPlatformNodeDelegate* title_item = view_accessibility(items[7]); @@ -853,7 +853,7 @@ EXPECT_EQ(title_item->GetPosInSet(), 7); EXPECT_EQ(title_item->GetSetSize(), 7); EXPECT_EQ(title_item->GetChildCount(), 0); - EXPECT_EQ(title_item->GetIndexInParent(), 6); + EXPECT_EQ(title_item->GetIndexInParent(), 7); } #if defined(USE_AURA)
diff --git a/ui/views/controls/menu/menu_separator.cc b/ui/views/controls/menu/menu_separator.cc index 6366dea..98343f8 100644 --- a/ui/views/controls/menu/menu_separator.cc +++ b/ui/views/controls/menu/menu_separator.cc
@@ -105,7 +105,6 @@ void MenuSeparator::GetAccessibleNodeData(ui::AXNodeData* node_data) { node_data->role = ax::mojom::Role::kSplitter; - node_data->AddState(ax::mojom::State::kIgnored); } BEGIN_METADATA(MenuSeparator, View)