blob: d98302cf5791b4933c26a7e374ccbbe7fcd24d87 [file] [log] [blame]
// Copyright 2018 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/modules/manifest/image_resource_type_converters.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h"
#include "third_party/blink/public/platform/web_icon_sizes_parser.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace mojo {
namespace {
using Purpose = blink::mojom::blink::ManifestImageResource::Purpose;
using blink::WebSize;
using blink::WebString;
using blink::WebVector;
// https://w3c.github.io/manifest/#sizes-member.
WTF::Vector<gfx::Size> ParseSizes(const WTF::String& sizes) {
WebVector<gfx::Size> parsed_sizes = blink::WebIconSizesParser::ParseIconSizes(
WebString::FromASCII(sizes.Ascii()));
WTF::HashSet<std::pair<int, int>, WTF::PairHash<int, int>,
WTF::PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<int>,
WTF::UnsignedWithZeroKeyHashTraits<int>>>
unique_sizes;
WTF::Vector<gfx::Size> results;
for (const auto& size : parsed_sizes) {
auto add_result =
unique_sizes.insert(std::make_pair(size.width(), size.height()));
if (add_result.is_new_entry) {
results.push_back(size);
}
}
return results;
}
// https://w3c.github.io/manifest/#purpose-member.
WTF::Vector<Purpose> ParsePurpose(const WTF::String& purpose) {
WTF::HashSet<WTF::String> valid_purpose_set;
WTF::Vector<Purpose> results;
// Only two purpose values are defined.
valid_purpose_set.ReserveCapacityForSize(2u);
results.ReserveInitialCapacity(2u);
WTF::Vector<WTF::String> split_purposes;
purpose.LowerASCII().Split(' ', false /* allow_empty_entries */,
split_purposes);
for (const WTF::String& lowercase_purpose : split_purposes) {
Purpose purpose_enum;
if (lowercase_purpose == "any") {
purpose_enum = Purpose::ANY;
} else if (lowercase_purpose == "badge") {
purpose_enum = Purpose::BADGE;
} else if (lowercase_purpose == "maskable") {
purpose_enum = Purpose::MASKABLE;
} else {
// TODO(rayankans): Issue developer warning.
continue;
}
auto add_result = valid_purpose_set.insert(lowercase_purpose);
if (add_result.is_new_entry) {
results.push_back(purpose_enum);
} else {
// TODO(rayankans): Issue developer warning.
}
}
return results;
}
WTF::String ParseType(const WTF::String& type) {
if (type.IsNull() || type.IsEmpty())
return "";
if (!blink::IsSupportedMimeType(type.Ascii())) {
// TODO(rayankans): Issue developer warning.
return "";
}
return type;
}
} // namespace
blink::mojom::blink::ManifestImageResourcePtr TypeConverter<
blink::mojom::blink::ManifestImageResourcePtr,
blink::ManifestImageResource*>::Convert(const blink::ManifestImageResource*
image_resource) {
auto image_resource_ptr = blink::mojom::blink::ManifestImageResource::New();
image_resource_ptr->src = blink::KURL(image_resource->src());
if (image_resource->hasSizes())
image_resource_ptr->sizes = ParseSizes(image_resource->sizes());
if (image_resource->hasPurpose())
image_resource_ptr->purpose = ParsePurpose(image_resource->purpose());
image_resource_ptr->type = ParseType(image_resource->type());
return image_resource_ptr;
}
} // namespace mojo
namespace blink {
Manifest::ImageResource ConvertManifestImageResource(
const ManifestImageResource* icon) {
Manifest::ImageResource manifest_icon;
manifest_icon.src = blink::KURL(icon->src());
manifest_icon.type = WebString(mojo::ParseType(icon->type())).Utf16();
// Parse 'purpose'
const auto purposes = mojo::ParsePurpose(icon->purpose());
// ParsePurpose() would've weeded out any purposes that're not ANY or BADGE.
for (auto purpose : purposes) {
switch (purpose) {
case mojo::Purpose::ANY:
manifest_icon.purpose.emplace_back(
Manifest::ImageResource::Purpose::ANY);
break;
case mojo::Purpose::BADGE:
manifest_icon.purpose.emplace_back(
Manifest::ImageResource::Purpose::BADGE);
break;
case mojo::Purpose::MASKABLE:
manifest_icon.purpose.emplace_back(
Manifest::ImageResource::Purpose::MASKABLE);
break;
}
}
// Parse 'sizes'.
WTF::Vector<gfx::Size> sizes = mojo::ParseSizes(icon->sizes());
for (const auto& size : sizes) {
manifest_icon.sizes.emplace_back(size);
}
return manifest_icon;
}
} // namespace blink