// Copyright (c) 2010 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 "webkit/appcache/view_appcache_internals_job.h" #include "base/logging.h" #include "base/format_macros.h" #include "base/utf_string_conversions.h" #include "base/i18n/time_formatting.h" #include "base/string_util.h" #include "webkit/appcache/appcache_service.h" namespace { const char kErrorMessage[] = "Error in retrieving Application caches."; const char kEmptyAppCachesMessage[] = "No available Application caches."; void StartHTML(std::string* out) { DCHECK(out); out->append( "" "AppCache Internals" ""); } void EndHTML(std::string* out) { DCHECK(out); out->append(""); } void AddLiTag(const std::string& element_title, const std::string& element_data, std::string* out) { DCHECK(out); out->append("
  • "); out->append(element_title); out->append(element_data); out->append("
  • "); } void WrapInHREF(const std::string& in, std::string* out) { out->append(""); out->append(in); out->append("
    "); } void AddHTMLFromAppCacheToOutput( const appcache::AppCacheInfoVector& appcaches, std::string* out) { for (std::vector::const_iterator info = appcaches.begin(); info != appcaches.end(); ++info) { out->append("

    "); std::string anchored_manifest; WrapInHREF(info->manifest_url.spec(), &anchored_manifest); out->append("Manifest: "); out->append(anchored_manifest); out->append("


    "); } } struct ManifestURLComparator { public: bool operator() ( const appcache::AppCacheInfo& lhs, const appcache::AppCacheInfo& rhs) const { return (lhs.manifest_url.spec() < rhs.manifest_url.spec()); } } manifest_url_comparator; } // namespace namespace appcache { ViewAppCacheInternalsJob::ViewAppCacheInternalsJob( URLRequest* request, AppCacheService* service) : URLRequestSimpleJob(request), appcache_service_(service) { } ViewAppCacheInternalsJob::~ViewAppCacheInternalsJob() { // Cancel callback if job is destroyed before callback is called. if (appcache_info_callback_) appcache_info_callback_.release()->Cancel(); } void ViewAppCacheInternalsJob::Start() { if (!request_) return; info_collection_ = new AppCacheInfoCollection; appcache_info_callback_ = new net::CancelableCompletionCallback( this, &ViewAppCacheInternalsJob::OnGotAppCacheInfo); appcache_service_->GetAllAppCacheInfo( info_collection_, appcache_info_callback_); } void ViewAppCacheInternalsJob::GenerateHTMLAppCacheInfo( std::string* out) const { typedef std::map InfoByOrigin; AppCacheInfoVector appcaches; for (InfoByOrigin::const_iterator origin = info_collection_->infos_by_origin.begin(); origin != info_collection_->infos_by_origin.end(); ++origin) { for (AppCacheInfoVector::const_iterator info = origin->second.begin(); info != origin->second.end(); ++info) appcaches.push_back(*info); } std::sort(appcaches.begin(), appcaches.end(), manifest_url_comparator); AddHTMLFromAppCacheToOutput(appcaches, out); } void ViewAppCacheInternalsJob::OnGotAppCacheInfo(int rv) { appcache_info_callback_ = NULL; if (rv != net::OK) info_collection_ = NULL; StartAsync(); } bool ViewAppCacheInternalsJob::GetData(std::string* mime_type, std::string* charset, std::string* data) const { mime_type->assign("text/html"); charset->assign("UTF-8"); data->clear(); StartHTML(data); if (!info_collection_.get()) data->append(kErrorMessage); else if (info_collection_->infos_by_origin.empty()) data->append(kEmptyAppCachesMessage); else GenerateHTMLAppCacheInfo(data); EndHTML(data); return true; } } // namespace appcache