diff options
author | benjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-11 21:03:26 +0000 |
---|---|---|
committer | benjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-11 21:03:26 +0000 |
commit | 9d27318a0a0dbbb7312b8026be240d8def439406 (patch) | |
tree | cc6cf11ea0fbb4f6ea2eb62c3bc41d49864d2e7a | |
parent | df66ed60b88d0331b3bd815622a77047cdc1e0d8 (diff) | |
download | chromium_src-9d27318a0a0dbbb7312b8026be240d8def439406.zip chromium_src-9d27318a0a0dbbb7312b8026be240d8def439406.tar.gz chromium_src-9d27318a0a0dbbb7312b8026be240d8def439406.tar.bz2 |
Switch the downloads API over to IDL/json_schema_compiler
Modify ppapi/generators/idl_parser.py to
0: not require a file-level comment (but generate the same parse tree structure),
1: actually support ext_attrs (modifiers) for dictionaries, and
2: support [ext_attr=(symbols|values)].
Modify json_schema_compiler to
0: use "base::Value" and any_helper.ANY_CLASS instead of Value and Any in order to support ArrayBuffers named |value| or |any|,
1: actually test that namespaces and dictionaries are sorted correctly,
2: fix HGenerator._FieldDependencyOrder(),
3: support [inline_doc] on dictionaries and enums,
4: support descriptions on enums,
5: support documentation_permissions_required,
6: support [legalValues=(values...)].
Review URL: https://chromiumcodereview.appspot.com/10639020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146201 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 969 insertions, 1991 deletions
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc index 49e8f77..16b076cc 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api.cc @@ -38,9 +38,11 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/webui/web_ui_util.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/extensions/api/downloads.h" #include "content/public/browser/download_interrupt_reasons.h" #include "content/public/browser/download_item.h" #include "content/public/browser/download_save_info.h" +#include "content/public/browser/download_url_parameters.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -324,10 +326,7 @@ void GetManagers( } } -DownloadItem* GetActiveItemInternal( - Profile* profile, - bool include_incognito, - int id) { +DownloadItem* GetActiveItem(Profile* profile, bool include_incognito, int id) { DownloadManager* manager = NULL; DownloadManager* incognito_manager = NULL; GetManagers(profile, include_incognito, &manager, &incognito_manager); @@ -337,207 +336,220 @@ DownloadItem* GetActiveItemInternal( return download_item; } -} // namespace - -bool DownloadsFunctionInterface::RunImplImpl( - DownloadsFunctionInterface* pimpl) { - CHECK(pimpl); - if (!pimpl->ParseArgs()) return false; - UMA_HISTOGRAM_ENUMERATION( - "Download.ApiFunctions", pimpl->function(), DOWNLOADS_FUNCTION_LAST); - return pimpl->RunInternal(); -} - -SyncDownloadsFunction::SyncDownloadsFunction( - DownloadsFunctionInterface::DownloadsFunctionName function) - : function_(function) { -} - -SyncDownloadsFunction::~SyncDownloadsFunction() {} +enum DownloadsFunctionName { + DOWNLOADS_FUNCTION_DOWNLOAD = 0, + DOWNLOADS_FUNCTION_SEARCH = 1, + DOWNLOADS_FUNCTION_PAUSE = 2, + DOWNLOADS_FUNCTION_RESUME = 3, + DOWNLOADS_FUNCTION_CANCEL = 4, + DOWNLOADS_FUNCTION_ERASE = 5, + DOWNLOADS_FUNCTION_SET_DESTINATION = 6, + DOWNLOADS_FUNCTION_ACCEPT_DANGER = 7, + DOWNLOADS_FUNCTION_SHOW = 8, + DOWNLOADS_FUNCTION_DRAG = 9, + DOWNLOADS_FUNCTION_GET_FILE_ICON = 10, + DOWNLOADS_FUNCTION_OPEN = 11, + // Insert new values here, not at the beginning. + DOWNLOADS_FUNCTION_LAST +}; -bool SyncDownloadsFunction::RunImpl() { - return DownloadsFunctionInterface::RunImplImpl(this); +void RecordApiFunctions(DownloadsFunctionName function) { + UMA_HISTOGRAM_ENUMERATION("Download.ApiFunctions", + function, + DOWNLOADS_FUNCTION_LAST); } -DownloadsFunctionInterface::DownloadsFunctionName -SyncDownloadsFunction::function() const { - return function_; -} +void CompileDownloadQueryOrderBy( + const std::string& order_by_str, std::string* error, DownloadQuery* query) { + // TODO(benjhayden): Consider switching from LazyInstance to explicit string + // comparisons. + static base::LazyInstance<SortTypeMap> sorter_types = + LAZY_INSTANCE_INITIALIZER; + if (sorter_types.Get().size() == 0) + InitSortTypeMap(sorter_types.Get()); -DownloadItem* SyncDownloadsFunction::GetActiveItem(int download_id) { - return GetActiveItemInternal(profile(), include_incognito(), download_id); + std::vector<std::string> order_by_strs; + base::SplitString(order_by_str, ' ', &order_by_strs); + for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); + iter != order_by_strs.end(); ++iter) { + std::string term_str = *iter; + if (term_str.empty()) + continue; + DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING; + if (term_str[0] == '-') { + direction = DownloadQuery::DESCENDING; + term_str = term_str.substr(1); + } + SortTypeMap::const_iterator sorter_type = + sorter_types.Get().find(term_str); + if (sorter_type == sorter_types.Get().end()) { + *error = download_extension_errors::kInvalidOrderByError; + return; + } + query->AddSorter(sorter_type->second, direction); + } } -AsyncDownloadsFunction::AsyncDownloadsFunction( - DownloadsFunctionInterface::DownloadsFunctionName function) - : function_(function) { -} +void RunDownloadQuery( + const extensions::api::downloads::DownloadQuery& query_in, + Profile* profile, + bool include_incognito, + std::string* error, + DownloadQuery::DownloadVector* results) { + // TODO(benjhayden): Consider switching from LazyInstance to explicit string + // comparisons. + static base::LazyInstance<FilterTypeMap> filter_types = + LAZY_INSTANCE_INITIALIZER; + if (filter_types.Get().size() == 0) + InitFilterTypeMap(filter_types.Get()); -AsyncDownloadsFunction::~AsyncDownloadsFunction() {} + DownloadQuery query_out; -bool AsyncDownloadsFunction::RunImpl() { - return DownloadsFunctionInterface::RunImplImpl(this); -} + if (query_in.limit.get()) { + if (*query_in.limit.get() < 0) { + *error = download_extension_errors::kInvalidQueryLimit; + return; + } + query_out.Limit(*query_in.limit.get()); + } + if (query_in.state.get()) { + DownloadItem::DownloadState state = StateEnumFromString( + *query_in.state.get()); + if (state == DownloadItem::MAX_DOWNLOAD_STATE) { + *error = download_extension_errors::kInvalidStateError; + return; + } + query_out.AddFilter(state); + } + if (query_in.danger.get()) { + content::DownloadDangerType danger_type = + DangerEnumFromString(*query_in.danger.get()); + if (danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) { + *error = download_extension_errors::kInvalidDangerTypeError; + return; + } + query_out.AddFilter(danger_type); + } + if (query_in.order_by.get()) { + CompileDownloadQueryOrderBy(*query_in.order_by.get(), error, &query_out); + if (!error->empty()) + return; + } -DownloadsFunctionInterface::DownloadsFunctionName -AsyncDownloadsFunction::function() const { - return function_; -} + scoped_ptr<base::DictionaryValue> query_in_value(query_in.ToValue().Pass()); + for (base::DictionaryValue::Iterator query_json_field(*query_in_value.get()); + query_json_field.HasNext(); query_json_field.Advance()) { + FilterTypeMap::const_iterator filter_type = + filter_types.Get().find(query_json_field.key()); + if (filter_type != filter_types.Get().end()) { + if (!query_out.AddFilter(filter_type->second, query_json_field.value())) { + *error = download_extension_errors::kInvalidFilterError; + return; + } + } + } -DownloadItem* AsyncDownloadsFunction::GetActiveItem(int download_id) { - return GetActiveItemInternal(profile(), include_incognito(), download_id); + DownloadManager* manager = NULL; + DownloadManager* incognito_manager = NULL; + GetManagers(profile, include_incognito, &manager, &incognito_manager); + DownloadQuery::DownloadVector all_items; + if (query_in.id.get()) { + DownloadItem* item = manager->GetDownloadItem(*query_in.id.get()); + if (!item && incognito_manager) + item = incognito_manager->GetDownloadItem(*query_in.id.get()); + if (item) + all_items.push_back(item); + } else { + manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items); + if (incognito_manager) + incognito_manager->GetAllDownloads( + FilePath(FILE_PATH_LITERAL("")), &all_items); + } + query_out.Search(all_items.begin(), all_items.end(), results); } -DownloadsDownloadFunction::DownloadsDownloadFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_DOWNLOAD) { -} +} // namespace +DownloadsDownloadFunction::DownloadsDownloadFunction() {} DownloadsDownloadFunction::~DownloadsDownloadFunction() {} -DownloadsDownloadFunction::IOData::IOData() - : save_as(false), - extra_headers(NULL), - method("GET"), - rdh(NULL), - resource_context(NULL), - render_process_host_id(0), - render_view_host_routing_id(0) { -} - -DownloadsDownloadFunction::IOData::~IOData() {} - -bool DownloadsDownloadFunction::ParseArgs() { - base::DictionaryValue* options = NULL; - std::string url; - iodata_.reset(new IOData()); - EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); - EXTENSION_FUNCTION_VALIDATE(options->GetString(kUrlKey, &url)); - iodata_->url = GURL(url); - if (!iodata_->url.is_valid()) { - error_ = download_extension_errors::kInvalidURLError; - return false; - } - - if (!iodata_->url.SchemeIs("data") && - iodata_->url.GetOrigin() != GetExtension()->url().GetOrigin() && - !GetExtension()->HasHostPermission(iodata_->url)) { +bool DownloadsDownloadFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Download::Params> params( + extensions::api::downloads::Download::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + const extensions::api::downloads::DownloadOptions& options = params->options; + GURL download_url(options.url); + if (!download_url.is_valid() || + (!download_url.SchemeIs("data") && + download_url.GetOrigin() != GetExtension()->url().GetOrigin() && + !GetExtension()->HasHostPermission(download_url))) { error_ = download_extension_errors::kInvalidURLError; return false; } - if (options->HasKey(kFilenameKey)) { - EXTENSION_FUNCTION_VALIDATE(options->GetString( - kFilenameKey, &iodata_->filename)); - if (!ValidateFilename(iodata_->filename)) { + content::DownloadSaveInfo save_info; + if (options.filename.get()) { + // TODO(benjhayden): Make json_schema_compiler generate string16s instead of + // std::strings. Can't get filename16 from options.ToValue() because that + // converts it from std::string. + base::DictionaryValue* options_value = NULL; + EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options_value)); + string16 filename16; + EXTENSION_FUNCTION_VALIDATE(options_value->GetString( + kFilenameKey, &filename16)); + if (!ValidateFilename(filename16)) { error_ = download_extension_errors::kGenericError; return false; } - } - - if (options->HasKey(kSaveAsKey)) { - EXTENSION_FUNCTION_VALIDATE(options->GetBoolean( - kSaveAsKey, &iodata_->save_as)); - } - - if (options->HasKey(kMethodKey)) { - EXTENSION_FUNCTION_VALIDATE(options->GetString( - kMethodKey, &iodata_->method)); - } - - // It's ok to use a pointer to extra_headers without DeepCopy()ing because - // |args_| (which owns *extra_headers) is guaranteed to live as long as - // |this|. - if (options->HasKey(kHeadersKey)) { - EXTENSION_FUNCTION_VALIDATE(options->GetList( - kHeadersKey, &iodata_->extra_headers)); - } - - if (options->HasKey(kBodyKey)) { - EXTENSION_FUNCTION_VALIDATE(options->GetString( - kBodyKey, &iodata_->post_body)); - } - - if (iodata_->extra_headers != NULL) { - for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) { - base::DictionaryValue* header = NULL; - std::string name; - EXTENSION_FUNCTION_VALIDATE(iodata_->extra_headers->GetDictionary( - index, &header)); - EXTENSION_FUNCTION_VALIDATE(header->GetString( - kHeaderNameKey, &name)); - if (!net::HttpUtil::IsSafeHeader(name)) { + // TODO(benjhayden) Ensure that this filename is interpreted as a path + // relative to the default downloads directory without allowing '..'. + save_info.suggested_name = filename16; + } + + if (options.save_as.get()) + save_info.prompt_for_save_location = *options.save_as.get(); + + Profile* current_profile = profile(); + if (include_incognito() && profile()->HasOffTheRecordProfile()) + current_profile = profile()->GetOffTheRecordProfile(); + + scoped_ptr<content::DownloadUrlParameters> download_params( + new content::DownloadUrlParameters( + download_url, + render_view_host()->GetProcess()->GetID(), + render_view_host()->GetRoutingID(), + current_profile->GetResourceContext(), + save_info)); + + if (options.headers.get()) { + typedef extensions::api::downloads::HeaderNameValuePair HeaderNameValuePair; + for (std::vector<linked_ptr<HeaderNameValuePair> >::const_iterator iter = + options.headers->begin(); + iter != options.headers->end(); + ++iter) { + const HeaderNameValuePair& name_value = **iter; + if (!net::HttpUtil::IsSafeHeader(name_value.name)) { error_ = download_extension_errors::kGenericError; return false; } + download_params->add_request_header(name_value.name, name_value.value); } } - iodata_->rdh = content::ResourceDispatcherHost::Get(); - iodata_->resource_context = profile()->GetResourceContext(); - iodata_->render_process_host_id = render_view_host()->GetProcess()->GetID(); - iodata_->render_view_host_routing_id = render_view_host()->GetRoutingID(); - return true; -} - -bool DownloadsDownloadFunction::RunInternal() { - VLOG(1) << __FUNCTION__ << " " << iodata_->url.spec(); - if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( - &DownloadsDownloadFunction::BeginDownloadOnIOThread, this))) { - error_ = download_extension_errors::kGenericError; - return false; - } - return true; -} - -void DownloadsDownloadFunction::BeginDownloadOnIOThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DVLOG(1) << __FUNCTION__ << " " << iodata_->url.spec(); - content::DownloadSaveInfo save_info; - // TODO(benjhayden) Ensure that this filename is interpreted as a path - // relative to the default downloads directory without allowing '..'. - save_info.suggested_name = iodata_->filename; - save_info.prompt_for_save_location = iodata_->save_as; - - scoped_ptr<net::URLRequest> request(new net::URLRequest( - iodata_->url, - NULL, - iodata_->resource_context->GetRequestContext())); - request->set_method(iodata_->method); - if (iodata_->extra_headers != NULL) { - for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) { - base::DictionaryValue* header = NULL; - std::string name, value; - CHECK(iodata_->extra_headers->GetDictionary(index, &header)); - CHECK(header->GetString(kHeaderNameKey, &name)); - CHECK(header->GetString(kHeaderValueKey, &value)); - request->SetExtraRequestHeaderByName(name, value, false/*overwrite*/); - } - } - if (!iodata_->post_body.empty()) { - request->AppendBytesToUpload(iodata_->post_body.data(), - iodata_->post_body.size()); - } + if (options.method.get()) + download_params->set_method(*options.method.get()); + if (options.body.get()) + download_params->set_post_body(*options.body.get()); + download_params->set_callback(base::Bind( + &DownloadsDownloadFunction::OnStarted, this)); // Prevent login prompts for 401/407 responses. - request->set_load_flags(request->load_flags() | - net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); - - net::Error error = iodata_->rdh->BeginDownload( - request.Pass(), - false, // is_content_initiated - iodata_->resource_context, - iodata_->render_process_host_id, - iodata_->render_view_host_routing_id, - false, // prefer_cache - save_info, - base::Bind(&DownloadsDownloadFunction::OnStarted, this)); - iodata_.reset(); - - if (error != net::OK) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&DownloadsDownloadFunction::OnStarted, this, - DownloadId::Invalid(), error)); - } + download_params->set_load_flags(net::LOAD_DO_NOT_PROMPT_FOR_LOGIN); + + DownloadManager* manager = BrowserContext::GetDownloadManager( + current_profile); + manager->DownloadUrl(download_params.Pass()); + RecordApiFunctions(DOWNLOADS_FUNCTION_DOWNLOAD); + return true; } void DownloadsDownloadFunction::OnStarted(DownloadId dl_id, net::Error error) { @@ -551,150 +563,38 @@ void DownloadsDownloadFunction::OnStarted(DownloadId dl_id, net::Error error) { SendResponse(error_.empty()); } -DownloadsSearchFunction::DownloadsSearchFunction() - : SyncDownloadsFunction(DOWNLOADS_FUNCTION_SEARCH), - query_(new DownloadQuery()), - get_id_(0), - has_get_id_(false) { -} - +DownloadsSearchFunction::DownloadsSearchFunction() {} DownloadsSearchFunction::~DownloadsSearchFunction() {} -bool DownloadsSearchFunction::ParseArgs() { - static base::LazyInstance<FilterTypeMap> filter_types = - LAZY_INSTANCE_INITIALIZER; - if (filter_types.Get().size() == 0) - InitFilterTypeMap(filter_types.Get()); - - base::DictionaryValue* query_json = NULL; - EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); - for (base::DictionaryValue::Iterator query_json_field(*query_json); - query_json_field.HasNext(); query_json_field.Advance()) { - FilterTypeMap::const_iterator filter_type = - filter_types.Get().find(query_json_field.key()); - - if (filter_type != filter_types.Get().end()) { - if (!query_->AddFilter(filter_type->second, query_json_field.value())) { - error_ = download_extension_errors::kInvalidFilterError; - return false; - } - } else if (query_json_field.key() == kIdKey) { - EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsInteger( - &get_id_)); - has_get_id_ = true; - } else if (query_json_field.key() == kOrderByKey) { - if (!ParseOrderBy(query_json_field.value())) - return false; - } else if (query_json_field.key() == kDangerKey) { - std::string danger_str; - EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsString( - &danger_str)); - content::DownloadDangerType danger_type = - DangerEnumFromString(danger_str); - if (danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) { - error_ = download_extension_errors::kInvalidDangerTypeError; - return false; - } - query_->AddFilter(danger_type); - } else if (query_json_field.key() == kStateKey) { - std::string state_str; - EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsString( - &state_str)); - DownloadItem::DownloadState state = StateEnumFromString(state_str); - if (state == DownloadItem::MAX_DOWNLOAD_STATE) { - error_ = download_extension_errors::kInvalidStateError; - return false; - } - query_->AddFilter(state); - } else if (query_json_field.key() == kLimitKey) { - int limit = 0; - EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsInteger( - &limit)); - if (limit < 0) { - error_ = download_extension_errors::kInvalidQueryLimit; - return false; - } - query_->Limit(limit); - } else { - EXTENSION_FUNCTION_VALIDATE(false); - } - } - return true; -} - -bool DownloadsSearchFunction::ParseOrderBy(const base::Value& order_by_value) { - static base::LazyInstance<SortTypeMap> sorter_types = - LAZY_INSTANCE_INITIALIZER; - if (sorter_types.Get().size() == 0) - InitSortTypeMap(sorter_types.Get()); - - std::string order_by_str; - EXTENSION_FUNCTION_VALIDATE(order_by_value.GetAsString(&order_by_str)); - std::vector<std::string> order_by_strs; - base::SplitString(order_by_str, ' ', &order_by_strs); - for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); - iter != order_by_strs.end(); ++iter) { - std::string term_str = *iter; - if (term_str.empty()) - continue; - DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING; - if (term_str[0] == '-') { - direction = DownloadQuery::DESCENDING; - term_str = term_str.substr(1); - } - SortTypeMap::const_iterator sorter_type = - sorter_types.Get().find(term_str); - if (sorter_type == sorter_types.Get().end()) { - error_ = download_extension_errors::kInvalidOrderByError; - return false; - } - query_->AddSorter(sorter_type->second, direction); - } - return true; -} - -bool DownloadsSearchFunction::RunInternal() { - DownloadManager* manager = NULL; - DownloadManager* incognito_manager = NULL; - GetManagers(profile(), include_incognito(), &manager, &incognito_manager); - DownloadQuery::DownloadVector all_items, cpp_results; - if (has_get_id_) { - DownloadItem* item = manager->GetDownloadItem(get_id_); - if (!item && incognito_manager) - item = incognito_manager->GetDownloadItem(get_id_); - if (item) - all_items.push_back(item); - } else { - manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items); - if (incognito_manager) - incognito_manager->GetAllDownloads( - FilePath(FILE_PATH_LITERAL("")), &all_items); - } - query_->Search(all_items.begin(), all_items.end(), &cpp_results); +bool DownloadsSearchFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Search::Params> params( + extensions::api::downloads::Search::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + DownloadQuery::DownloadVector results; + RunDownloadQuery(params->query, profile(), include_incognito(), + &error_, &results); + if (!error_.empty()) + return false; base::ListValue* json_results = new base::ListValue(); - for (DownloadManager::DownloadVector::const_iterator it = cpp_results.begin(); - it != cpp_results.end(); ++it) { + for (DownloadManager::DownloadVector::const_iterator it = results.begin(); + it != results.end(); ++it) { scoped_ptr<base::DictionaryValue> item(DownloadItemToJSON(*it)); json_results->Append(item.release()); } result_.reset(json_results); + RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH); return true; } -DownloadsPauseFunction::DownloadsPauseFunction() - : SyncDownloadsFunction(DOWNLOADS_FUNCTION_PAUSE), - download_id_(DownloadId::Invalid().local()) { -} - +DownloadsPauseFunction::DownloadsPauseFunction() {} DownloadsPauseFunction::~DownloadsPauseFunction() {} -bool DownloadsPauseFunction::ParseArgs() { - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); - return true; -} - -bool DownloadsPauseFunction::RunInternal() { - DownloadItem* download_item = GetActiveItem(download_id_); +bool DownloadsPauseFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Pause::Params> params( + extensions::api::downloads::Pause::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + DownloadItem* download_item = GetActiveItem( + profile(), include_incognito(), params->download_id); if ((download_item == NULL) || !download_item->IsInProgress()) { // This could be due to an invalid download ID, or it could be due to the // download not being currently active. @@ -703,23 +603,20 @@ bool DownloadsPauseFunction::RunInternal() { // If download_item->IsPaused() already then we treat it as a success. download_item->TogglePause(); } + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_PAUSE); return error_.empty(); } -DownloadsResumeFunction::DownloadsResumeFunction() - : SyncDownloadsFunction(DOWNLOADS_FUNCTION_RESUME), - download_id_(DownloadId::Invalid().local()) { -} - +DownloadsResumeFunction::DownloadsResumeFunction() {} DownloadsResumeFunction::~DownloadsResumeFunction() {} -bool DownloadsResumeFunction::ParseArgs() { - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); - return true; -} - -bool DownloadsResumeFunction::RunInternal() { - DownloadItem* download_item = GetActiveItem(download_id_); +bool DownloadsResumeFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Resume::Params> params( + extensions::api::downloads::Resume::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + DownloadItem* download_item = GetActiveItem( + profile(), include_incognito(), params->download_id); if (download_item == NULL) { // This could be due to an invalid download ID, or it could be due to the // download not being currently active. @@ -728,130 +625,110 @@ bool DownloadsResumeFunction::RunInternal() { // If !download_item->IsPaused() already, then we treat it as a success. download_item->TogglePause(); } + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_RESUME); return error_.empty(); } -DownloadsCancelFunction::DownloadsCancelFunction() - : SyncDownloadsFunction(DOWNLOADS_FUNCTION_CANCEL), - download_id_(DownloadId::Invalid().local()) { -} - +DownloadsCancelFunction::DownloadsCancelFunction() {} DownloadsCancelFunction::~DownloadsCancelFunction() {} -bool DownloadsCancelFunction::ParseArgs() { - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); - return true; -} - -bool DownloadsCancelFunction::RunInternal() { - DownloadItem* download_item = GetActiveItem(download_id_); +bool DownloadsCancelFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Resume::Params> params( + extensions::api::downloads::Resume::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + DownloadItem* download_item = GetActiveItem( + profile(), include_incognito(), params->download_id); if (download_item != NULL) download_item->Cancel(true); // |download_item| can be NULL if the download ID was invalid or if the // download is not currently active. Either way, we don't consider it a // failure. + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_CANCEL); return error_.empty(); } -DownloadsEraseFunction::DownloadsEraseFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_ERASE) { -} - +DownloadsEraseFunction::DownloadsEraseFunction() {} DownloadsEraseFunction::~DownloadsEraseFunction() {} -bool DownloadsEraseFunction::ParseArgs() { - base::DictionaryValue* query_json = NULL; - EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); +bool DownloadsEraseFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Erase::Params> params( + extensions::api::downloads::Erase::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); error_ = download_extension_errors::kNotImplementedError; - return false; -} - -bool DownloadsEraseFunction::RunInternal() { - NOTIMPLEMENTED(); - return false; -} - -DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_SET_DESTINATION) { + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_ERASE); + return error_.empty(); } +DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() {} DownloadsSetDestinationFunction::~DownloadsSetDestinationFunction() {} -bool DownloadsSetDestinationFunction::ParseArgs() { - int dl_id = 0; - std::string path; - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); - EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &path)); - VLOG(1) << __FUNCTION__ << " " << dl_id << " " << &path; +bool DownloadsSetDestinationFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::SetDestination::Params> params( + extensions::api::downloads::SetDestination::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); error_ = download_extension_errors::kNotImplementedError; - return false; -} - -bool DownloadsSetDestinationFunction::RunInternal() { - NOTIMPLEMENTED(); - return false; -} - -DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_ACCEPT_DANGER) { + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_SET_DESTINATION); + return error_.empty(); } +DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() {} DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {} -bool DownloadsAcceptDangerFunction::ParseArgs() { - int dl_id = 0; - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); - VLOG(1) << __FUNCTION__ << " " << dl_id; +bool DownloadsAcceptDangerFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::AcceptDanger::Params> params( + extensions::api::downloads::AcceptDanger::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); error_ = download_extension_errors::kNotImplementedError; - return false; -} - -bool DownloadsAcceptDangerFunction::RunInternal() { - NOTIMPLEMENTED(); - return false; -} - -DownloadsShowFunction::DownloadsShowFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_SHOW) { + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_ACCEPT_DANGER); + return error_.empty(); } +DownloadsShowFunction::DownloadsShowFunction() {} DownloadsShowFunction::~DownloadsShowFunction() {} -bool DownloadsShowFunction::ParseArgs() { - int dl_id = 0; - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); - VLOG(1) << __FUNCTION__ << " " << dl_id; +bool DownloadsShowFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Show::Params> params( + extensions::api::downloads::Show::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); error_ = download_extension_errors::kNotImplementedError; - return false; + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_SHOW); + return error_.empty(); } -bool DownloadsShowFunction::RunInternal() { - NOTIMPLEMENTED(); - return false; -} +DownloadsOpenFunction::DownloadsOpenFunction() {} +DownloadsOpenFunction::~DownloadsOpenFunction() {} -DownloadsDragFunction::DownloadsDragFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_DRAG) { +bool DownloadsOpenFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Open::Params> params( + extensions::api::downloads::Open::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + error_ = download_extension_errors::kNotImplementedError; + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_OPEN); + return error_.empty(); } +DownloadsDragFunction::DownloadsDragFunction() {} DownloadsDragFunction::~DownloadsDragFunction() {} -bool DownloadsDragFunction::ParseArgs() { - int dl_id = 0; - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); - VLOG(1) << __FUNCTION__ << " " << dl_id; +bool DownloadsDragFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::Drag::Params> params( + extensions::api::downloads::Drag::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); error_ = download_extension_errors::kNotImplementedError; - return false; -} - -bool DownloadsDragFunction::RunInternal() { - NOTIMPLEMENTED(); - return false; + if (error_.empty()) + RecordApiFunctions(DOWNLOADS_FUNCTION_DRAG); + return error_.empty(); } DownloadsGetFileIconFunction::DownloadsGetFileIconFunction() - : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_GET_FILE_ICON), - icon_size_(kDefaultIconSize), + : icon_size_(kDefaultIconSize), icon_extractor_(new DownloadFileIconExtractorImpl()) { } @@ -863,25 +740,21 @@ void DownloadsGetFileIconFunction::SetIconExtractorForTesting( icon_extractor_.reset(extractor); } -bool DownloadsGetFileIconFunction::ParseArgs() { - int dl_id = 0; - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); - - base::DictionaryValue* options = NULL; - EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options)); - if (options->HasKey(kSizeKey)) { - EXTENSION_FUNCTION_VALIDATE(options->GetInteger(kSizeKey, &icon_size_)); - // We only support 16px and 32px icons. This is enforced in - // downloads.json. - DCHECK(icon_size_ == 16 || icon_size_ == 32); - } - +bool DownloadsGetFileIconFunction::RunImpl() { + scoped_ptr<extensions::api::downloads::GetFileIcon::Params> params( + extensions::api::downloads::GetFileIcon::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + const extensions::api::downloads::GetFileIconOptions* options = + params->options.get(); + int icon_size = kDefaultIconSize; + if (options && options->size.get()) + icon_size = *options->size.get(); DownloadManager* manager = NULL; DownloadManager* incognito_manager = NULL; GetManagers(profile(), include_incognito(), &manager, &incognito_manager); - DownloadItem* download_item = manager->GetDownloadItem(dl_id); + DownloadItem* download_item = manager->GetDownloadItem(params->download_id); if (!download_item && incognito_manager) - download_item = incognito_manager->GetDownloadItem(dl_id); + download_item = incognito_manager->GetDownloadItem(params->download_id); if (!download_item) { // The DownloadItem is is added to history when the path is determined. If // the download is not in history, then we don't have a path / final @@ -892,26 +765,24 @@ bool DownloadsGetFileIconFunction::ParseArgs() { // In-progress downloads return the intermediate filename for GetFullPath() // which doesn't have the final extension. Therefore we won't be able to // derive a good file icon for it. So we use GetTargetFilePath() instead. - path_ = download_item->GetTargetFilePath(); - DCHECK(!path_.empty()); - return true; -} - -bool DownloadsGetFileIconFunction::RunInternal() { - DCHECK(!path_.empty()); + FilePath path = download_item->GetTargetFilePath(); + DCHECK(!path.empty()); DCHECK(icon_extractor_.get()); + DCHECK(icon_size == 16 || icon_size == 32); EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath( - path_, IconLoaderSizeFromPixelSize(icon_size_), + path, IconLoaderSizeFromPixelSize(icon_size), base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this))); return true; } void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (url.empty()) + if (url.empty()) { error_ = download_extension_errors::kIconNotFoundError; - else + } else { + RecordApiFunctions(DOWNLOADS_FUNCTION_GET_FILE_ICON); result_.reset(base::Value::CreateStringValue(url)); + } SendResponse(error_.empty()); } diff --git a/chrome/browser/extensions/api/downloads/downloads_api.h b/chrome/browser/extensions/api/downloads/downloads_api.h index 65aaf52..c4c35d0 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api.h +++ b/chrome/browser/extensions/api/downloads/downloads_api.h @@ -46,296 +46,162 @@ extern const char kNotImplementedError[]; } // namespace download_extension_errors -class DownloadsFunctionInterface { - public: - enum DownloadsFunctionName { - DOWNLOADS_FUNCTION_DOWNLOAD = 0, - DOWNLOADS_FUNCTION_SEARCH = 1, - DOWNLOADS_FUNCTION_PAUSE = 2, - DOWNLOADS_FUNCTION_RESUME = 3, - DOWNLOADS_FUNCTION_CANCEL = 4, - DOWNLOADS_FUNCTION_ERASE = 5, - DOWNLOADS_FUNCTION_SET_DESTINATION = 6, - DOWNLOADS_FUNCTION_ACCEPT_DANGER = 7, - DOWNLOADS_FUNCTION_SHOW = 8, - DOWNLOADS_FUNCTION_DRAG = 9, - DOWNLOADS_FUNCTION_GET_FILE_ICON = 10, - // Insert new values here, not at the beginning. - DOWNLOADS_FUNCTION_LAST - }; - - protected: - virtual ~DownloadsFunctionInterface() {} - - // Return true if args_ is well-formed, otherwise set error_ and return false. - virtual bool ParseArgs() = 0; - - // Implementation-specific logic. "Do the thing that you do." Should return - // true if the call succeeded and false otherwise. - virtual bool RunInternal() = 0; - - // Which subclass is this. - virtual DownloadsFunctionName function() const = 0; - - // Wrap ParseArgs(), RunInternal(). - static bool RunImplImpl(DownloadsFunctionInterface* pimpl); -}; - -class SyncDownloadsFunction : public SyncExtensionFunction, - public DownloadsFunctionInterface { - protected: - explicit SyncDownloadsFunction(DownloadsFunctionName function); - virtual ~SyncDownloadsFunction(); - - // ExtensionFunction: - virtual bool RunImpl() OVERRIDE; - - // DownloadsFunctionInterface: - virtual DownloadsFunctionName function() const OVERRIDE; - - content::DownloadItem* GetActiveItem(int download_id); - - private: - DownloadsFunctionName function_; - - DISALLOW_COPY_AND_ASSIGN(SyncDownloadsFunction); -}; -class AsyncDownloadsFunction : public AsyncExtensionFunction, - public DownloadsFunctionInterface { - protected: - explicit AsyncDownloadsFunction(DownloadsFunctionName function); - virtual ~AsyncDownloadsFunction(); - - // ExtensionFunction: - virtual bool RunImpl() OVERRIDE; - - // DownloadsFunctionInterface: - virtual DownloadsFunctionName function() const OVERRIDE; - - content::DownloadItem* GetActiveItem(int download_id); - - private: - DownloadsFunctionName function_; - - DISALLOW_COPY_AND_ASSIGN(AsyncDownloadsFunction); -}; - -class DownloadsDownloadFunction : public AsyncDownloadsFunction { +class DownloadsDownloadFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.download"); - DownloadsDownloadFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsDownloadFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: - struct IOData { - public: - IOData(); - ~IOData(); - - GURL url; - string16 filename; - bool save_as; - base::ListValue* extra_headers; - std::string method; - std::string post_body; - content::ResourceDispatcherHost* rdh; - content::ResourceContext* resource_context; - int render_process_host_id; - int render_view_host_routing_id; - }; - - void BeginDownloadOnIOThread(); void OnStarted(content::DownloadId dl_id, net::Error error); - scoped_ptr<IOData> iodata_; - DISALLOW_COPY_AND_ASSIGN(DownloadsDownloadFunction); }; -class DownloadsSearchFunction : public SyncDownloadsFunction { +class DownloadsSearchFunction : public SyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.search"); - DownloadsSearchFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsSearchFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: - bool ParseOrderBy(const base::Value& order_by_value); - - scoped_ptr<DownloadQuery> query_; - int get_id_; - bool has_get_id_; - DISALLOW_COPY_AND_ASSIGN(DownloadsSearchFunction); }; -class DownloadsPauseFunction : public SyncDownloadsFunction { +class DownloadsPauseFunction : public SyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.pause"); - DownloadsPauseFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsPauseFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: - int download_id_; DISALLOW_COPY_AND_ASSIGN(DownloadsPauseFunction); }; -class DownloadsResumeFunction : public SyncDownloadsFunction { +class DownloadsResumeFunction : public SyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.resume"); - DownloadsResumeFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsResumeFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: - int download_id_; DISALLOW_COPY_AND_ASSIGN(DownloadsResumeFunction); }; -class DownloadsCancelFunction : public SyncDownloadsFunction { +class DownloadsCancelFunction : public SyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.cancel"); - DownloadsCancelFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsCancelFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: - int download_id_; DISALLOW_COPY_AND_ASSIGN(DownloadsCancelFunction); }; -class DownloadsEraseFunction : public AsyncDownloadsFunction { +class DownloadsEraseFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.erase"); - DownloadsEraseFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsEraseFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(DownloadsEraseFunction); }; -class DownloadsSetDestinationFunction : public AsyncDownloadsFunction { +class DownloadsSetDestinationFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.setDestination"); - DownloadsSetDestinationFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsSetDestinationFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(DownloadsSetDestinationFunction); }; -class DownloadsAcceptDangerFunction : public AsyncDownloadsFunction { +class DownloadsAcceptDangerFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.acceptDanger"); - DownloadsAcceptDangerFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsAcceptDangerFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(DownloadsAcceptDangerFunction); }; -class DownloadsShowFunction : public AsyncDownloadsFunction { +class DownloadsShowFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.show"); - DownloadsShowFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsShowFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(DownloadsShowFunction); }; -class DownloadsDragFunction : public AsyncDownloadsFunction { +class DownloadsOpenFunction : public AsyncExtensionFunction { public: - DECLARE_EXTENSION_FUNCTION_NAME("downloads.drag"); + DECLARE_EXTENSION_FUNCTION_NAME("downloads.open"); + DownloadsOpenFunction(); + virtual bool RunImpl() OVERRIDE; + + protected: + virtual ~DownloadsOpenFunction(); + + private: + DISALLOW_COPY_AND_ASSIGN(DownloadsOpenFunction); +}; +class DownloadsDragFunction : public AsyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION_NAME("downloads.drag"); DownloadsDragFunction(); + virtual bool RunImpl() OVERRIDE; protected: virtual ~DownloadsDragFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction); }; -class DownloadsGetFileIconFunction : public AsyncDownloadsFunction { +class DownloadsGetFileIconFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("downloads.getFileIcon"); - DownloadsGetFileIconFunction(); + virtual bool RunImpl() OVERRIDE; void SetIconExtractorForTesting(DownloadFileIconExtractor* extractor); protected: virtual ~DownloadsGetFileIconFunction(); - // DownloadsFunctionInterface: - virtual bool ParseArgs() OVERRIDE; - virtual bool RunInternal() OVERRIDE; - private: void OnIconURLExtracted(const std::string& url); FilePath path_; diff --git a/chrome/browser/extensions/extension_function_registry.cc b/chrome/browser/extensions/extension_function_registry.cc index 146941b..b2aede7 100644 --- a/chrome/browser/extensions/extension_function_registry.cc +++ b/chrome/browser/extensions/extension_function_registry.cc @@ -13,7 +13,6 @@ #include "chrome/browser/extensions/api/context_menu/context_menu_api.h" #include "chrome/browser/extensions/api/cookies/cookies_api.h" #include "chrome/browser/extensions/api/declarative/declarative_api.h" -#include "chrome/browser/extensions/api/downloads/downloads_api.h" #include "chrome/browser/extensions/api/extension_action/extension_browser_actions_api.h" #include "chrome/browser/extensions/api/extension_action/extension_page_actions_api.h" #include "chrome/browser/extensions/api/extension_action/extension_script_badge_api.h" @@ -451,19 +450,6 @@ void ExtensionFunctionRegistry::ResetFunctions() { RegisterFunction<RemovePermissionsFunction>(); RegisterFunction<RequestPermissionsFunction>(); - // Downloads - RegisterFunction<DownloadsDownloadFunction>(); - RegisterFunction<DownloadsSearchFunction>(); - RegisterFunction<DownloadsPauseFunction>(); - RegisterFunction<DownloadsResumeFunction>(); - RegisterFunction<DownloadsCancelFunction>(); - RegisterFunction<DownloadsEraseFunction>(); - RegisterFunction<DownloadsSetDestinationFunction>(); - RegisterFunction<DownloadsAcceptDangerFunction>(); - RegisterFunction<DownloadsShowFunction>(); - RegisterFunction<DownloadsDragFunction>(); - RegisterFunction<DownloadsGetFileIconFunction>(); - // PageCapture RegisterFunction<PageCaptureSaveAsMHTMLFunction>(); diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp index 82d526d..2101be4 100644 --- a/chrome/common/extensions/api/api.gyp +++ b/chrome/common/extensions/api/api.gyp @@ -32,6 +32,7 @@ 'idl_schema_files': [ 'alarms.idl', 'app_window.idl', + 'downloads.idl', 'experimental_bluetooth.idl', 'experimental_discovery.idl', 'experimental_dns.idl', diff --git a/chrome/common/extensions/api/downloads.idl b/chrome/common/extensions/api/downloads.idl new file mode 100644 index 0000000..0d750e4 --- /dev/null +++ b/chrome/common/extensions/api/downloads.idl @@ -0,0 +1,399 @@ +// 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. + +[permissions=downloads] +namespace downloads { + [inline_doc] dictionary HeaderNameValuePair { + // Name of the HTTP header. + DOMString name; + + // Value of the HTTP header. + DOMString value; + }; + + [inline_doc] enum HttpMethod {GET, POST}; + + [inline_doc] dictionary DownloadOptions { + // The URL to download. + DOMString url; + + // A file path relative to the Downloads directory to contain the downloaded + // file. + DOMString? filename; + + // Use a file-chooser to allow the user to select a filename. + boolean? saveAs; + + // The HTTP method to use if the URL uses the HTTP[S] protocol. + HttpMethod? method; + + // Extra HTTP headers to send with the request if the URL uses the HTTP[s] + // protocol. Each header is represented as a dictionary containing the keys + // <code>name</code> and either <code>value</code> or + // <code>binaryValue</code>, restricted to those allowed by XMLHttpRequest. + HeaderNameValuePair[]? headers; + + // Post body. + DOMString? body; + }; + + // <dl><dt>file</dt> + // <dd>The download's filename is suspicious.</dd> + // <dt>url</dt> + // <dd>The download's URL is known to be malicious.</dd> + // <dt>content</dt> + // <dd>The downloaded file is known to be malicious.</dd> + // <dt>uncommon</dt> + // <dd>The download's URL is not commonly downloaded and could be + // dangerous.</dd> + // <dt>safe</dt> + // <dd>The download presents no known danger to the user's computer.</dd> + // </dl> + // These string constants will never change, however the set of DangerTypes + // may change. + enum DangerType {file, url, content, uncommon, safe}; + + // <dl><dt>in_progress</dt> + // <dd>The download is currently receiving data from the server.</dd> + // <dt>interrupted</dt> + // <dd>An error broke the connection with the file host.</dd> + // <dt>complete</dt> + // <dd>The download completed successfully.</dd> + // </dl> + // These string constants will never change, however the set of States may + // change. + enum State {in_progress, interrupted, complete}; + + // The state of the process of downloading a file. + dictionary DownloadItem { + // An identifier that is persistent across browser sessions. + long id; + + // Absolute URL. + DOMString url; + + // Absolute local path. + DOMString filename; + + // False if this download is recorded in the history, true if it is not + // recorded. + boolean incognito; + + // Indication of whether this download is thought to be safe or known to be + // suspicious. + DangerType danger; + + // True if the user has accepted the download's danger. + boolean? dangerAccepted; + + // The file's MIME type. + DOMString mime; + + // Number of milliseconds between the unix epoch and when this download + // began. + long startTime; + + // Number of milliseconds between the unix epoch and when this download + // ended. + long? endTime; + + // Indicates whether the download is progressing, interrupted, or complete. + State state; + + // True if the download has stopped reading data from the host, but kept the + // connection open. + boolean paused; + + // Number indicating why a download was interrupted. + long? error; + + // Number of bytes received so far from the host, without considering file + // compression. + long bytesReceived; + + // Number of bytes in the whole file, without considering file compression, + // or -1 if unknown. + long totalBytes; + + // Number of bytes in the whole file post-decompression, or -1 if unknown. + long fileSize; + }; + + [inline_doc] dictionary DownloadQuery { + // This space-separated string of search terms that may be grouped using + // quotation marks limits results to <a + // href='#type-DownloadItem'>DownloadItems</a> whose <code>filename</code> + // or <code>url</code> contain all of the search terms that do not begin with a dash '-' + // and none of the search terms that do begin with a dash. + DOMString? query; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that + // started before the given ms since the epoch. + long? startedBefore; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that + // started after the given ms since the epoch. + long? startedAfter; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that ended before the given ms since the + // epoch. + long? endedBefore; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> that ended after the given ms since the + // epoch. + long? endedAfter; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose + // <code>totalBytes</code> is greater than the given integer. + long? totalBytesGreater; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose + // <code>totalBytes</code> is less than the given integer. + long? totalBytesLess; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose + // <code>filename</code> matches the given regular expression. + DOMString? filenameRegex; + + // Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose + // <code>url</code> matches the given regular expression. + DOMString? urlRegex; + + // Setting this integer limits the number of results. Otherwise, all + // matching <a href='#type-DownloadItem'>DownloadItems</a> will be returned. + long? limit; + + // Setting this string to a <a href='#type-DownloadItem'>DownloadItem</a> + // property sorts the <a href='#type-DownloadItem'>DownloadItems</a> prior + // to applying the above filters. For example, setting + // <code>orderBy='startTime'</code> sorts the <a + // href='#type-DownloadItem'>DownloadItems</a> by their start time in + // ascending order. To specify descending order, prefix <code>orderBy</code> + // with a hyphen: '-startTime'. + DOMString? orderBy; + + // The <code>id</code> of the <a href="#type-DownloadItem">DownloadItem</a> + // that changed. + long? id; + + // Absolute URL. + DOMString? url; + + // Absolute local path. + DOMString? filename; + + // Indication of whether this download is thought to be safe or known to be + // suspicious. + DangerType? danger; + + // True if the user has accepted the download's danger. + boolean? dangerAccepted; + + // The file's MIME type. + DOMString? mime; + + // Number of milliseconds between the unix epoch and when this download + // began. + long? startTime; + + // Number of milliseconds between the unix epoch and when this download + // ended. + long? endTime; + + // Indicates whether the download is progressing, interrupted, or complete. + State? state; + + // True if the download has stopped reading data from the host, but kept the + // connection open. + boolean? paused; + + // Number indicating why a download was interrupted. + long? error; + + // Number of bytes received so far from the host, without considering file + // compression. + long? bytesReceived; + + // Number of bytes in the whole file, without considering file compression, + // or -1 if unknown. + long? totalBytes; + + // Number of bytes in the whole file post-decompression, or -1 if unknown. + long? fileSize; + }; + + [inline_doc] dictionary DownloadStringDiff { + DOMString? previous; + DOMString? current; + }; + + [inline_doc] dictionary DownloadLongDiff { + long? previous; + long? current; + }; + + [inline_doc] dictionary DownloadBooleanDiff { + boolean? previous; + boolean? current; + }; + + // Encapsulates a change in a DownloadItem. + [inline_doc] dictionary DownloadDelta { + // An identifier that is persistent across browser sessions. + long id; + + // The change in <code>url</code>, if any. + DownloadStringDiff? url; + + // The change in <code>filename</code>, if any. + DownloadStringDiff? filename; + + // The change in <code>danger</code>, if any. + DownloadStringDiff? danger; + + // The change in <code>dangerAccepted</code>, if any. + DownloadBooleanDiff? dangerAccepted; + + // The change in <code>mime</code>, if any. + DownloadStringDiff? mime; + + // The change in <code>startTime</code>, if any. + DownloadLongDiff? startTime; + + // The change in <code>endTime</code>, if any. + DownloadLongDiff? endTime; + + // The change in <code>state</code>, if any. + DownloadStringDiff? state; + + // The change in <code>paused</code>, if any. + DownloadBooleanDiff? paused; + + // The change in <code>error</code>, if any. + DownloadLongDiff? error; + + // The change in <code>totalBytes</code>, if any. + DownloadLongDiff? totalBytes; + + // The change in <code>fileSize</code>, if any. + DownloadLongDiff? fileSize; + }; + + [inline_doc] dictionary GetFileIconOptions { + // The size of the icon. The returned icon will be square with dimensions + // size * size pixels. The default size for the icon is 32x32 pixels. + [legalValues=(16,32)] long? size; + }; + + callback DownloadCallback = void(long downloadId); + callback SearchCallback = void(DownloadItem[] results); + callback EraseCallback = void(long[] erasedIds); + callback NullCallback = void(); + callback GetFileIconCallback = void(optional DOMString iconURL); + + interface Functions { + // Download a URL. If the URL uses the HTTP[S] protocol, then the request + // will include all cookies currently set for its hostname. If both + // <code>filename</code> and <code>saveAs</code> are specified, then the + // Save As dialog will be displayed, pre-populated with the specified + // <code>filename</code>. If the download started successfully, + // <code>callback</code> will be called with the new <a href='#type-DownloadItem'>DownloadItem</a>'s + // <code>downloadId</code>. If there was an error starting the download, + // then <code>callback</code> will be called with + // <code>downloadId=undefined</code> and <a + // href='extension.html#property-lastError'>chrome.extension.lastError</a> + // will contain a descriptive string. The error strings are not guaranteed + // to remain backwards compatible between releases. You must not parse it. + // |options|: What to download and how. + // |callback|: Called with the id of the new <a href='#type-DownloadItem'>DownloadItem</a>. + static void download(DownloadOptions options, + optional DownloadCallback callback); + + // Find <a href='#type-DownloadItem'>DownloadItems</a>. Set + // <code>query</code> to the empty object to get all <a + // href='#type-DownloadItem'>DownloadItems</a>. To get a specific <a + // href='#type-DownloadItem'>DownloadItem</a>, set only the <code>id</code> + // field. + static void search(DownloadQuery query, SearchCallback callback); + + // Pause the download. If the request was successful the download is in a + // paused state. Otherwise <a + // href='extension.html#property-lastError'>chrome.extension.lastError</a> + // contains an error message. The request will fail if the download is not + // active. + // |downloadId|: The id of the download to pause. + // |callback|: Called when the pause request is completed. + static void pause(long downloadId, optional NullCallback callback); + + // Resume a paused download. If the request was successful the download is + // in progress and unpaused. Otherwise <a + // href='extension.html#property-lastError'>chrome.extension.lastError</a> + // contains an error message. The request will fail if the download is not + // active. + // |downloadId|: The id of the download to resume. + // |callback|: Called when the resume request is completed. + static void resume(long downloadId, optional NullCallback callback); + + // Cancel a download. When <code>callback</code> is run, the download is + // cancelled, completed, interrupted or doesn't exist anymore. + // |downloadId|: The id of the download to cancel. + // |callback|: Called when the cancel request is completed. + static void cancel(long downloadId, optional NullCallback callback); + + // Retrieve an icon for the specified download. For new downloads, file + // icons are available after the <a href='#event-onCreated'>onCreated</a> + // event has been received. The image returned by this function while a + // download is in progress may be different from the image returned after + // the download is complete. Icon retrieval is done by querying the + // underlying operating system or toolkit depending on the platform. The + // icon that is returned will therefore depend on a number of factors + // including state of the download, platform, registered file types and + // visual theme. If a file icon cannot be determined, <a + // href='extension.html#property-lastError'>chrome.extension.lastError</a> + // will contain an error message. + // |downloadId|: The identifier for the download. + // |callback|: A URL to an image that represents the download. + static void getFileIcon(long downloadId, + optional GetFileIconOptions options, + GetFileIconCallback callback); + + // Erase matching <a href='#type-DownloadItem'>DownloadItems</a> from + // history + [nodoc] static void erase(DownloadQuery query, + optional EraseCallback callback); + + // TODO(benjhayden) Comment. + [nodoc] static void setDestination(long downloadId, DOMString relativePath); + + // Prompt the user to either accept or cancel a dangerous download. + // <code>acceptDanger()</code> does not automatically accept dangerous + // downloads. + [nodoc] static void acceptDanger(long downloadId); + + // Show the downloaded file in its folder in a file manager. + [nodoc] static void show(long downloadId); + + // Open the downloaded file. + [nodoc] static void open(long downloadId); + + // Initiate dragging the file to another application. + [nodoc] static void drag(long downloadId); + }; + + interface Events { + // This event fires with the <a href='#type-DownloadItem'>DownloadItem</a> + // object when a download begins. + static void onCreated(DownloadItem downloadItem); + + // Fires with the <code>downloadId</code> when a download is erased from + // history. + // |downloadId|: The <code>id</code> of the <a href='#type-DownloadItem'>DownloadItem</a> that was erased. + static void onErased(long downloadId); + + // When any of a <a href='#type-DownloadItem'>DownloadItem</a>'s properties + // except <code>bytesReceived</code> changes, this event fires with the + // <code>downloadId</code> and an object containing the properties that changed. + static void onChanged(DownloadDelta downloadDelta); + }; +}; diff --git a/chrome/common/extensions/api/downloads.json b/chrome/common/extensions/api/downloads.json deleted file mode 100644 index 5cd7ff4..0000000 --- a/chrome/common/extensions/api/downloads.json +++ /dev/null @@ -1,1208 +0,0 @@ -[ - { - "documentation_permissions_required": [ - "downloads" - ], - "events": [ - { - "description": "This event fires with the <a href='#type-DownloadItem'>DownloadItem</a> object when a download begins.", - "name": "onCreated", - "parameters": [ - { - "$ref": "DownloadItem", - "name": "downloadItem" - } - ], - "type": "function" - }, - { - "description": "Fires with the <code>downloadId</code> when a download is erased from history.", - "name": "onErased", - "parameters": [ - { - "name": "downloadId", - "description": "The <code>id</code> of the <a href='#type-DownloadItem'>DownloadItem</a> that was erased.", - "type": "integer" - } - ], - "type": "function" - }, - { - "description": "When any of a <a href='#type-DownloadItem'>DownloadItem</a>'s properties except <code>bytesReceived</code> changes, this event fires with the <code>downloadId</code> and an object containing the properties that changed.", - "name": "onChanged", - "parameters": [ - { - "name": "downloadDelta", - "properties": { - "danger": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>danger</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "dangerAccepted": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>dangerAccepted</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "boolean" - }, - "previous": { - "optional": true, - "type": "boolean" - } - }, - "type": "object" - }, - "endTime": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>endTime</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "error": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>error</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "fileSize": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>fileSize</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "filename": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>filename</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "id": { - "description": "The <code>id</code> of the <a href='#type-DownloadItem'>DownloadItem</a> that changed.", - "type": "integer" - }, - "mime": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>mime</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "paused": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>paused</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "boolean" - }, - "previous": { - "optional": true, - "type": "boolean" - } - }, - "type": "object" - }, - "startTime": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>startTime</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "state": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>state</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "totalBytes": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>totalBytes</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "url": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>url</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - } - ], - "type": "function" - } - ], - "functions": [ - { - "description": "Download a URL. If the URL uses the HTTP[S] protocol, then the request will include all cookies currently set for its hostname. If both <code>filename</code> and <code>saveAs</code> are specified, then the Save As dialog will be displayed, pre-populated with the specified <code>filename</code>. If the download started successfully, <code>callback</code> will be called with the new <a href='#type-DownloadItem'>DownloadItem</a>'s <code>downloadId</code>. If there was an error starting the download, then <code>callback</code> will be called with <code>downloadId=undefined</code> and <a href='extension.html#property-lastError'>chrome.extension.lastError</a> will contain a descriptive string. The error strings are not guaranteed to remain backwards compatible between releases. You must not parse it.", - "name": "download", - "parameters": [ - { - "description": "What to download and how.", - "name": "options", - "properties": { - "body": { - "description": "Post body.", - "optional": true, - "type": "string" - }, - "filename": { - "description": "A file path relative to the Downloads directory to contain the downloaded file.", - "optional": true, - "type": "string" - }, - "headers": { - "description": "Extra HTTP headers to send with the request if the URL uses the HTTP[s] protocol. Each header is represented as a dictionary containing the keys <code>name</code> and either <code>value</code> or <code>binaryValue</code>, restricted to those allowed by XMLHttpRequest.", - "items": { - "properties": { - "name": { - "description": "Name of the HTTP header.", - "type": "string" - }, - "value": { - "description": "Value of the HTTP header.", - "type": "string" - } - }, - "type": "object" - }, - "optional": true, - "type": "array" - }, - "method": { - "description": "The HTTP method to use if the URL uses the HTTP[S] protocol.", - "enum": [ - "GET", - "POST" - ], - "optional": true, - "type": "string" - }, - "saveAs": { - "description": "Use a file-chooser to allow the user to select a filename.", - "optional": true, - "type": "boolean" - }, - "url": { - "description": "The URL to download.", - "type": "string" - } - }, - "type": "object" - }, - { - "name": "DownloadCallback", - "optional": true, - "parameters": [ - { - "name": "downloadId", - "type": "integer" - } - ], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "Find <a href='#type-DownloadItem'>DownloadItems</a>. Set <code>query</code> to the empty object to get all <a href='#type-DownloadItem'>DownloadItems</a>. To get a specific <a href='#type-DownloadItem'>DownloadItem</a>, set only the <code>id</code> field.", - "name": "search", - "parameters": [ - { - "name": "query", - "properties": { - "bytesReceived": { - "description": "Number of bytes received so far from the host, without considering file compression.", - "optional": true, - "type": "integer" - }, - "danger": { - "$ref": "DangerType", - "description": "Indication of whether this download is thought to be safe or known to be suspicious.", - "optional": true - }, - "dangerAccepted": { - "description": "True if the user has accepted the download's danger.", - "optional": true, - "type": "boolean" - }, - "endTime": { - "description": "Number of milliseconds between the unix epoch and when this download ended.", - "optional": true, - "type": "integer" - }, - "endedAfter": { - "description": "Limits results to downloads that ended after the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "endedBefore": { - "description": "Limits results to downloads that ended before the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "error": { - "description": "Number indicating why a download was interrupted.", - "optional": true, - "type": "integer" - }, - "fileSize": { - "description": "Number of bytes in the whole file post-decompression, or -1 if unknown.", - "optional": true, - "type": "integer" - }, - "filename": { - "description": "Absolute local path.", - "optional": true, - "type": "string" - }, - "filenameRegex": { - "description": "Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose <code>filename</code> matches the given regular expression.", - "optional": true, - "type": "string" - }, - "id": { - "description": "An identifier that is persistent across browser sessions.", - "optional": true, - "type": "integer" - }, - "limit": { - "description": "Setting this integer limits the number of results. Otherwise, all matching <a href='#type-DownloadItem'>DownloadItems</a> will be returned.", - "optional": true, - "type": "integer" - }, - "mime": { - "description": "The file's MIME type.", - "optional": true, - "type": "string" - }, - "orderBy": { - "description": "Setting this string to a <a href='#type-DownloadItem'>DownloadItem</a> property sorts the <a href='#type-DownloadItem'>DownloadItems</a> prior to applying the above filters. For example, setting <code>orderBy='startTime'</code> sorts the <a href='#type-DownloadItem'>DownloadItems</a> by their start time in ascending order. To specify descending order, prefix <code>orderBy</code> with a hyphen: '-startTime'.", - "optional": true, - "type": "string" - }, - "paused": { - "description": "True if the download has stopped reading data from the host, but kept the connection open.", - "optional": true, - "type": "boolean" - }, - "query": { - "description": "This space-separated string of search terms that may be grouped using quotation marks limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose <code>filename</code> or <code>url</code> contain all of the search terms that do not begin with a dash '-' and none of the search terms that do begin with a dash.", - "optional": true, - "type": "string" - }, - "startTime": { - "description": "Number of milliseconds between the unix epoch and when this download began.", - "optional": true, - "type": "integer" - }, - "startedAfter": { - "description": "Limits results to downloads that started after the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "startedBefore": { - "description": "Limits results to downloads that started before the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "state": { - "$ref": "State", - "description": "Indicates whether the download is progressing, interrupted, or complete.", - "optional": true - }, - "totalBytes": { - "description": "Number of bytes in the whole file, without considering file compression, or -1 if unknown.", - "optional": true, - "type": "integer" - }, - "totalBytesGreater": { - "description": "Limits results to downloads whose totalBytes is greater than the given integer.", - "optional": true, - "type": "integer" - }, - "totalBytesLess": { - "description": "Limits results to downloads whose totalBytes is less than the given integer.", - "optional": true, - "type": "integer" - }, - "url": { - "description": "Absolute URL.", - "optional": true, - "type": "string" - }, - "urlRegex": { - "description": "Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose <code>url</code> matches the given regular expression.", - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - { - "name": "SearchCallback", - "parameters": [ - { - "items": { - "$ref": "DownloadItem" - }, - "name": "results", - "type": "array" - } - ], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "Pause the download. If the request was successful the download is in a paused state. Otherwise <a href='extension.html#property-lastError'>chrome.extension.lastError</a> contains an error message. The request will fail if the download is not active.", - "name": "pause", - "parameters": [ - { - "description": "The id of the download to pause.", - "name": "downloadId", - "type": "integer" - }, - { - "name": "NullCallback", - "optional": true, - "parameters": [], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "Resume a paused download. If the request was successful the download is in progress and unpaused. Otherwise <a href='extension.html#property-lastError'>chrome.extension.lastError</a> contains an error message. The request will fail if the download is not active.", - "name": "resume", - "parameters": [ - { - "description": "The id of the download to resume.", - "name": "downloadId", - "type": "integer" - }, - { - "name": "NullCallback", - "optional": true, - "parameters": [], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "Cancel a download. When <code>callback</code> is run, the download is cancelled, completed, interrupted or doesn't exist anymore.", - "name": "cancel", - "parameters": [ - { - "description": "The id of the download to cancel.", - "name": "downloadId", - "type": "integer" - }, - { - "name": "NullCallback", - "optional": true, - "parameters": [], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "Retrieve an icon for the specified download. For new downloads, file icons are available after the <a href='#event-onCreated'>onCreated</a> event has been received. The image returned by this function while a download is in progress may be different from the image returned after the download is complete. Icon retrieval is done by querying the underlying operating system or toolkit depending on the platform. The icon that is returned will therefore depend on a number of factors including state of the download, platform, registered file types and visual theme. If a file icon cannot be determined, <a href='extension.html#property-lastError'>chrome.extension.lastError</a> will contain an error message.", - "name": "getFileIcon", - "parameters": [ - { - "description": "The identifier for the download.", - "name": "downloadId", - "type": "integer" - }, - { - "name": "options", - "optional": true, - "properties": { - "size": { - "description": "The size of the icon. The returned icon will be square with dimensions size * size pixels. The default size for the icon is 32x32 pixels.", - "enum": [ - 16, - 32 - ], - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - { - "name": "GetFileIconCallback", - "parameters": [ - { - "name": "iconURL", - "optional": true, - "type": "string" - } - ], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "Erase matching <a href='#type-DownloadItem'>DownloadItems</a> from history", - "name": "erase", - "nodoc": true, - "parameters": [ - { - "$ref": "DownloadQuery", - "name": "query" - }, - { - "name": "EraseCallback", - "optional": true, - "parameters": [ - { - "items": { - "type": "integer" - }, - "name": "erasedIds", - "type": "array" - } - ], - "type": "function" - } - ], - "type": "function" - }, - { - "description": "TODO(benjhayden) Comment.", - "name": "setDestination", - "nodoc": true, - "parameters": [ - { - "name": "downloadId", - "type": "integer" - }, - { - "name": "relativePath", - "type": "string" - } - ], - "type": "function" - }, - { - "description": "Prompt the user to either accept or cancel a dangerous download. <code>acceptDanger()</code> does not automatically accept dangerous downloads.", - "name": "acceptDanger", - "nodoc": true, - "parameters": [ - { - "name": "downloadId", - "type": "integer" - } - ], - "type": "function" - }, - { - "description": "Show the downloaded file in its folder in a file manager.", - "name": "show", - "nodoc": true, - "parameters": [ - { - "name": "downloadId", - "type": "integer" - } - ], - "type": "function" - }, - { - "description": "Open the downloaded file.", - "name": "open", - "nodoc": true, - "parameters": [ - { - "name": "downloadId", - "type": "integer" - } - ], - "type": "function" - }, - { - "description": "Initiate dragging the file to another application.", - "name": "drag", - "nodoc": true, - "parameters": [ - { - "name": "downloadId", - "type": "integer" - } - ], - "type": "function" - } - ], - "namespace": "downloads", - "nodoc": false, - "types": [ - { - "id": "HeaderNameValuePair", - "nodoc": true, - "properties": { - "name": { - "description": "Name of the HTTP header.", - "type": "string" - }, - "value": { - "description": "Value of the HTTP header.", - "type": "string" - } - }, - "type": "object" - }, - { - "description": "", - "enum": [ - "GET", - "POST" - ], - "id": "HttpMethod", - "nodoc": true, - "type": "string" - }, - { - "id": "DownloadOptions", - "nodoc": true, - "properties": { - "body": { - "description": "Post body.", - "optional": true, - "type": "string" - }, - "filename": { - "description": "A file path relative to the Downloads directory to contain the downloaded file.", - "optional": true, - "type": "string" - }, - "headers": { - "description": "Extra HTTP headers to send with the request if the URL uses the HTTP[s] protocol. Each header is represented as a dictionary containing the keys <code>name</code> and either <code>value</code> or <code>binaryValue</code>, restricted to those allowed by XMLHttpRequest.", - "items": { - "properties": { - "name": { - "description": "Name of the HTTP header.", - "type": "string" - }, - "value": { - "description": "Value of the HTTP header.", - "type": "string" - } - }, - "type": "object" - }, - "optional": true, - "type": "array" - }, - "method": { - "description": "The HTTP method to use if the URL uses the HTTP[S] protocol.", - "enum": [ - "GET", - "POST" - ], - "optional": true, - "type": "string" - }, - "saveAs": { - "description": "Use a file-chooser to allow the user to select a filename.", - "optional": true, - "type": "boolean" - }, - "url": { - "description": "The URL to download.", - "type": "string" - } - }, - "type": "object" - }, - { - "description": "<dl><dt>file</dt><dd>The download's filename is suspicious.</dd><dt>url</dt><dd>The download's URL is known to be malicious.</dd><dt>content</dt><dd>The downloaded file is known to be malicious.</dd><dt>uncommon</dt><dd>The download's URL is not commonly downloaded and could be dangerous.</dd><dt>safe</dt><dd>The download presents no known danger to the user's computer.</dd></dl>These string constants will never change, however the set of DangerTypes may change.", - "enum": [ - "file", - "url", - "content", - "uncommon", - "safe" - ], - "id": "DangerType", - "type": "string" - }, - { - "description": "<dl><dt>in_progress</dt><dd>The download is currently receiving data from the server.</dd><dt>interrupted</dt><dd>An error broke the connection with the file host.</dd><dt>complete</dt><dd>The download completed successfully.</dd></dl>These string constants will never change, however the set of States may change.", - "enum": [ - "in_progress", - "interrupted", - "complete" - ], - "id": "State", - "type": "string" - }, - { - "id": "DownloadItem", - "properties": { - "bytesReceived": { - "description": "Number of bytes received so far from the host, without considering file compression.", - "name": "bytesReceived", - "type": "integer" - }, - "danger": { - "$ref": "DangerType", - "description": "Indication of whether this download is thought to be safe or known to be suspicious.", - "name": "danger" - }, - "dangerAccepted": { - "description": "True if the user has accepted the download's danger.", - "name": "dangerAccepted", - "optional": true, - "type": "boolean" - }, - "endTime": { - "description": "Number of milliseconds between the unix epoch and when this download ended.", - "name": "endTime", - "optional": true, - "type": "integer" - }, - "error": { - "description": "Number indicating why a download was interrupted.", - "name": "error", - "optional": true, - "type": "integer" - }, - "fileSize": { - "description": "Number of bytes in the whole file post-decompression, or -1 if unknown.", - "name": "fileSize", - "type": "integer" - }, - "filename": { - "description": "Absolute local path.", - "name": "filename", - "type": "string" - }, - "id": { - "description": "An identifier that is persistent across browser sessions.", - "name": "id", - "type": "integer" - }, - "incognito": { - "description": "False if this download is recorded in the history, true if it is not recorded.", - "name": "incognito", - "type": "boolean" - }, - "mime": { - "description": "The file's MIME type.", - "name": "mime", - "type": "string" - }, - "paused": { - "description": "True if the download has stopped reading data from the host, but kept the connection open.", - "name": "paused", - "type": "boolean" - }, - "startTime": { - "description": "Number of milliseconds between the unix epoch and when this download began.", - "name": "startTime", - "type": "integer" - }, - "state": { - "$ref": "State", - "description": "Indicates whether the download is progressing, interrupted, or complete.", - "name": "state" - }, - "totalBytes": { - "description": "Number of bytes in the whole file, without considering file compression, or -1 if unknown.", - "name": "totalBytes", - "type": "integer" - }, - "url": { - "description": "Absolute URL.", - "name": "url", - "type": "string" - } - }, - "type": "object" - }, - { - "id": "DownloadQuery", - "nodoc": true, - "properties": { - "bytesReceived": { - "description": "Number of bytes received so far from the host, without considering file compression.", - "optional": true, - "type": "integer" - }, - "danger": { - "$ref": "DangerType", - "description": "Indication of whether this download is thought to be safe or known to be suspicious.", - "optional": true - }, - "dangerAccepted": { - "description": "True if the user has accepted the download's danger.", - "optional": true, - "type": "boolean" - }, - "endTime": { - "description": "Number of milliseconds between the unix epoch and when this download ended.", - "optional": true, - "type": "integer" - }, - "endedAfter": { - "description": "Limits results to downloads that ended after the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "endedBefore": { - "description": "Limits results to downloads that ended before the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "error": { - "description": "Number indicating why a download was interrupted.", - "optional": true, - "type": "integer" - }, - "fileSize": { - "description": "Number of bytes in the whole file post-decompression, or -1 if unknown.", - "optional": true, - "type": "integer" - }, - "filename": { - "description": "Absolute local path.", - "optional": true, - "type": "string" - }, - "filenameRegex": { - "description": "Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose <code>filename</code> matches the given regular expression.", - "optional": true, - "type": "string" - }, - "id": { - "description": "An identifier that is persistent across browser sessions.", - "optional": true, - "type": "integer" - }, - "limit": { - "description": "Setting this integer limits the number of results. Otherwise, all matching <a href='#type-DownloadItem'>DownloadItems</a> will be returned.", - "optional": true, - "type": "integer" - }, - "mime": { - "description": "The file's MIME type.", - "optional": true, - "type": "string" - }, - "orderBy": { - "description": "Setting this string to a <a href='#type-DownloadItem'>DownloadItem</a> property sorts the <a href='#type-DownloadItem'>DownloadItems</a> prior to applying the above filters. For example, setting <code>orderBy='startTime'</code> sorts the <a href='#type-DownloadItem'>DownloadItems</a> by their start time in ascending order. To specify descending order, prefix <code>orderBy</code> with a hyphen: '-startTime'.", - "optional": true, - "type": "string" - }, - "paused": { - "description": "True if the download has stopped reading data from the host, but kept the connection open.", - "optional": true, - "type": "boolean" - }, - "query": { - "description": "This space-separated string of search terms that may be grouped using quotation marks limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose <code>filename</code> or <code>url</code> contain all of the search terms that do not begin with a dash '-' and none of the search terms that do begin with a dash.", - "optional": true, - "type": "string" - }, - "startTime": { - "description": "Number of milliseconds between the unix epoch and when this download began.", - "optional": true, - "type": "integer" - }, - "startedAfter": { - "description": "Limits results to downloads that started after the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "startedBefore": { - "description": "Limits results to downloads that started before the given ms since the epoch.", - "optional": true, - "type": "integer" - }, - "state": { - "$ref": "State", - "description": "Indicates whether the download is progressing, interrupted, or complete.", - "optional": true - }, - "totalBytes": { - "description": "Number of bytes in the whole file, without considering file compression, or -1 if unknown.", - "optional": true, - "type": "integer" - }, - "totalBytesGreater": { - "description": "Limits results to downloads whose totalBytes is greater than the given integer.", - "optional": true, - "type": "integer" - }, - "totalBytesLess": { - "description": "Limits results to downloads whose totalBytes is less than the given integer.", - "optional": true, - "type": "integer" - }, - "url": { - "description": "Absolute URL.", - "optional": true, - "type": "string" - }, - "urlRegex": { - "description": "Limits results to <a href='#type-DownloadItem'>DownloadItems</a> whose <code>url</code> matches the given regular expression.", - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - { - "id": "DownloadStringDiff", - "nodoc": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - { - "id": "DownloadLongDiff", - "nodoc": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - { - "id": "DownloadBooleanDiff", - "nodoc": true, - "properties": { - "current": { - "optional": true, - "type": "boolean" - }, - "previous": { - "optional": true, - "type": "boolean" - } - }, - "type": "object" - }, - { - "id": "DownloadDelta", - "nodoc": true, - "properties": { - "danger": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>danger</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "dangerAccepted": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>dangerAccepted</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "boolean" - }, - "previous": { - "optional": true, - "type": "boolean" - } - }, - "type": "object" - }, - "endTime": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>endTime</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "error": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>error</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "fileSize": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>fileSize</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "filename": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>filename</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "id": { - "description": "The <code>id</code> of the <a href='#type-DownloadItem'>DownloadItem</a> that changed.", - "type": "integer" - }, - "mime": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>mime</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "paused": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>paused</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "boolean" - }, - "previous": { - "optional": true, - "type": "boolean" - } - }, - "type": "object" - }, - "startTime": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>startTime</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "state": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>state</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - }, - "totalBytes": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>totalBytes</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "integer" - }, - "previous": { - "optional": true, - "type": "integer" - } - }, - "type": "object" - }, - "url": { - "description": "Describes a change in a <a href='#type-DownloadItem'>DownloadItem</a>'s <code>url</code>.", - "optional": true, - "properties": { - "current": { - "optional": true, - "type": "string" - }, - "previous": { - "optional": true, - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - { - "id": "GetFileIconOptions", - "nodoc": true, - "properties": { - "size": { - "description": "The size of the icon. The returned icon will be square with dimensions size * size pixels. The default size for the icon is 32x32 pixels.", - "enum": [ - 16, - 32 - ], - "optional": true, - "type": "integer" - } - }, - "type": "object" - } - ] - } -] diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc index da8d69e2..5eb90ba 100644 --- a/chrome/common/extensions/api/extension_api.cc +++ b/chrome/common/extensions/api/extension_api.cc @@ -365,8 +365,6 @@ void ExtensionAPI::InitDefaultConfiguration() { IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST)); RegisterSchema("devtools", ReadFromResource( IDR_EXTENSION_API_JSON_DEVTOOLS)); - RegisterSchema("downloads", ReadFromResource( - IDR_EXTENSION_API_JSON_DOWNLOADS)); RegisterSchema("events", ReadFromResource( IDR_EXTENSION_API_JSON_EVENTS)); RegisterSchema("experimental.accessibility", ReadFromResource( diff --git a/chrome/common/extensions/docs/build/directory.py b/chrome/common/extensions/docs/build/directory.py index a751b5a..41d3d9e 100644 --- a/chrome/common/extensions/docs/build/directory.py +++ b/chrome/common/extensions/docs/build/directory.py @@ -83,13 +83,13 @@ def parse_idl_file(path): api_def = idl_schema.Load(path) for namespace_def in api_def: namespace_dot = namespace_def['namespace'] + '.' - types = dict((type_['id'], type_) - for type_ in namespace_def.get('types', []) - if type_) + inline_types = dict((type_['id'], type_) + for type_ in namespace_def.get('types', []) + if type_ and type_.get('inline_doc', False)) def SubstituteInlineDoc(prop): prop_ref_type = prop.get('$ref', '') - type_obj = types.get(namespace_dot + prop_ref_type, - types.get(prop_ref_type, {})) + type_obj = inline_types.get(namespace_dot + prop_ref_type, + inline_types.get(prop_ref_type, {})) if not type_obj: return if 'properties' in type_obj: @@ -113,17 +113,18 @@ def parse_idl_file(path): if (prop.get('type', '') == 'array' and prop.get('items', {}).get('$ref', '').startswith(namespace_dot)): prop['items']['$ref'] = prop['items']['$ref'][len(namespace_dot):] - if prop.get('inline_doc', False): - del prop['inline_doc'] - SubstituteInlineDoc(prop) - if 'items' in prop: - SubstituteInlineDoc(prop['items']) + SubstituteInlineDoc(prop) + if 'items' in prop: + SubstituteInlineDoc(prop['items']) for type_ in namespace_def.get('types', []): if type_.get('id', '').startswith(namespace_dot): type_['id'] = type_['id'][len(namespace_dot):] for prop in type_.get('properties', {}).values(): FixReferences(prop) + if type_.get('inline_doc', False): + del type_['inline_doc'] + type_['nodoc'] = True for func in namespace_def.get('functions', []): for param in func.get('parameters', []): FixReferences(param) diff --git a/chrome/common/extensions/docs/extensions/downloads.html b/chrome/common/extensions/docs/extensions/downloads.html index 2ed14e4..b63ea81 100644 --- a/chrome/common/extensions/docs/extensions/downloads.html +++ b/chrome/common/extensions/docs/extensions/downloads.html @@ -1258,7 +1258,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Limits results to downloads that ended after the given ms since the epoch.</dd> + <dd>Limits results to <a href="#type-DownloadItem">DownloadItems</a> that ended after the given ms since the epoch.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1282,7 +1282,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Limits results to downloads that ended before the given ms since the epoch.</dd> + <dd>Limits results to <a href="#type-DownloadItem">DownloadItems</a> that ended before the given ms since the epoch.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1402,7 +1402,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>An identifier that is persistent across browser sessions.</dd> + <dd>The <code>id</code> of the <a href="\"#type-DownloadItem\"">DownloadItem</a> that changed.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1570,7 +1570,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Limits results to downloads that started after the given ms since the epoch.</dd> + <dd>Limits results to <a href="#type-DownloadItem">DownloadItems</a> that started after the given ms since the epoch.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1594,7 +1594,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Limits results to downloads that started before the given ms since the epoch.</dd> + <dd>Limits results to <a href="#type-DownloadItem">DownloadItems</a> that started before the given ms since the epoch.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1666,7 +1666,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Limits results to downloads whose totalBytes is greater than the given integer.</dd> + <dd>Limits results to <a href="#type-DownloadItem">DownloadItems</a> whose <code>totalBytes</code> is greater than the given integer.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1690,7 +1690,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Limits results to downloads whose totalBytes is less than the given integer.</dd> + <dd>Limits results to <a href="#type-DownloadItem">DownloadItems</a> whose <code>totalBytes</code> is less than the given integer.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -1929,7 +1929,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>danger</code>.</dd> + <dd>The change in <code>danger</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2010,7 +2010,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>dangerAccepted</code>.</dd> + <dd>The change in <code>dangerAccepted</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2091,7 +2091,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>endTime</code>.</dd> + <dd>The change in <code>endTime</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2172,7 +2172,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>error</code>.</dd> + <dd>The change in <code>error</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2253,7 +2253,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>fileSize</code>.</dd> + <dd>The change in <code>fileSize</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2334,7 +2334,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>filename</code>.</dd> + <dd>The change in <code>filename</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2414,7 +2414,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>The <code>id</code> of the <a href="#type-DownloadItem">DownloadItem</a> that changed.</dd> + <dd>An identifier that is persistent across browser sessions.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -2438,7 +2438,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>mime</code>.</dd> + <dd>The change in <code>mime</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2519,7 +2519,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>paused</code>.</dd> + <dd>The change in <code>paused</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2600,7 +2600,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>startTime</code>.</dd> + <dd>The change in <code>startTime</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2681,7 +2681,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>state</code>.</dd> + <dd>The change in <code>state</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2762,7 +2762,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>totalBytes</code>.</dd> + <dd>The change in <code>totalBytes</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -2843,7 +2843,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd>Describes a change in a <a href="#type-DownloadItem">DownloadItem</a>'s <code>url</code>.</dd> + <dd>The change in <code>url</code>, if any.</dd> <!-- OBJECT PROPERTIES --> <dd> <dl> @@ -3041,7 +3041,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd><dl><dt>file</dt><dd>The download's filename is suspicious.</dd><dt>url</dt><dd>The download's URL is known to be malicious.</dd><dt>content</dt><dd>The downloaded file is known to be malicious.</dd><dt>uncommon</dt><dd>The download's URL is not commonly downloaded and could be dangerous.</dd><dt>safe</dt><dd>The download presents no known danger to the user's computer.</dd></dl>These string constants will never change, however the set of DangerTypes may change.</dd> + <dd><dl><dt>file</dt> <dd>The download's filename is suspicious.</dd> <dt>url</dt> <dd>The download's URL is known to be malicious.</dd> <dt>content</dt> <dd>The downloaded file is known to be malicious.</dd> <dt>uncommon</dt> <dd>The download's URL is not commonly downloaded and could be dangerous.</dd> <dt>safe</dt> <dd>The download presents no known danger to the user's computer.</dd> </dl> These string constants will never change, however the set of DangerTypes may change.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> @@ -3067,7 +3067,7 @@ directory. For other examples and for help in viewing the source code, see <a hr </div> </em> </dt> - <dd><dl><dt>in_progress</dt><dd>The download is currently receiving data from the server.</dd><dt>interrupted</dt><dd>An error broke the connection with the file host.</dd><dt>complete</dt><dd>The download completed successfully.</dd></dl>These string constants will never change, however the set of States may change.</dd> + <dd><dl><dt>in_progress</dt> <dd>The download is currently receiving data from the server.</dd> <dt>interrupted</dt> <dd>An error broke the connection with the file host.</dd> <dt>complete</dt> <dd>The download completed successfully.</dd> </dl> These string constants will never change, however the set of States may change.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json index cd64940..32bb3a8 100644 --- a/chrome/common/extensions/docs/samples.json +++ b/chrome/common/extensions/docs/samples.json @@ -150,7 +150,6 @@ "chrome.experimental.discovery.clearAllSuggestions": "experimental.discovery.html#method-clearAllSuggestions", "chrome.experimental.discovery.removeSuggestion": "experimental.discovery.html#method-removeSuggestion", "chrome.experimental.discovery.suggest": "experimental.discovery.html#method-suggest", - "chrome.experimental.dns.resolve": "experimental.dns.html#method-resolve", "chrome.experimental.fontSettings.clearDefaultFixedFontSize": "experimental.fontSettings.html#method-clearDefaultFixedFontSize", "chrome.experimental.fontSettings.clearDefaultFontSize": "experimental.fontSettings.html#method-clearDefaultFontSize", "chrome.experimental.fontSettings.clearFont": "experimental.fontSettings.html#method-clearFont", @@ -170,10 +169,6 @@ "chrome.experimental.fontSettings.setMinimumFontSize": "experimental.fontSettings.html#method-setMinimumFontSize", "chrome.experimental.identity.getAuthToken": "experimental.identity.html#method-getAuthToken", "chrome.experimental.identity.launchWebAuthFlow": "experimental.identity.html#method-launchWebAuthFlow", - "chrome.experimental.idltest.getArrayBuffer": "experimental.idltest.html#method-getArrayBuffer", - "chrome.experimental.idltest.nocompileFunc": "experimental.idltest.html#method-nocompileFunc", - "chrome.experimental.idltest.sendArrayBuffer": "experimental.idltest.html#method-sendArrayBuffer", - "chrome.experimental.idltest.sendArrayBufferView": "experimental.idltest.html#method-sendArrayBufferView", "chrome.experimental.infobars.show": "experimental.infobars.html#method-show", "chrome.experimental.keybinding.onCommand": "experimental.keybinding.html#event-onCommand", "chrome.experimental.mediaGalleries.assembleMediaFile": "experimental.mediaGalleries.html#method-assembleMediaFile", diff --git a/chrome/common/extensions_api_resources.grd b/chrome/common/extensions_api_resources.grd index 171d42ae..d90eafd 100644 --- a/chrome/common/extensions_api_resources.grd +++ b/chrome/common/extensions_api_resources.grd @@ -26,7 +26,6 @@ <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_ACCESSIBILITY" file="extensions\api\experimental_accessibility.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP" file="extensions\api\experimental_app.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER" file="extensions\api\experimental_bookmark_manager.json" type="BINDATA" /> - <include name="IDR_EXTENSION_API_JSON_DOWNLOADS" file="extensions\api\downloads.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTSSETTINGS" file="extensions\api\experimental_font_settings.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_IDENTITY" file="extensions\api\experimental_identity.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_INFOBARS" file="extensions\api\experimental_infobars.json" type="BINDATA" /> diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py index f1045c3..22517d0 100755 --- a/ppapi/generators/idl_parser.py +++ b/ppapi/generators/idl_parser.py @@ -221,6 +221,15 @@ class IDLParser(IDLLexer): p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4]) if self.parse_debug: DumpReduction('top', p) + def p_top_short(self, p): + """top : COMMENT ext_attr_block top_list""" + Copyright = self.BuildComment('Copyright', p, 1) + Filedoc = IDLNode('Comment', self.lexobj.filename, p.lineno(2)-1, + p.lexpos(2)-1, [self.BuildAttribute('NAME', ''), + self.BuildAttribute('FORM', 'cc')]) + p[0] = ListFromConcat(Copyright, Filedoc, p[2], p[3]) + if self.parse_debug: DumpReduction('top', p) + # Build a list of top level items. def p_top_list(self, p): """top_list : callback_decl top_list @@ -289,11 +298,11 @@ class IDLParser(IDLLexer): # # Dictionary # -# A dictionary contains is a named list of optional and required members. +# A dictionary is a named list of optional and required members. # def p_dictionary_block(self, p): """dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'""" - p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[5])) + p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[1], p[5])) # # Callback @@ -370,6 +379,29 @@ class IDLParser(IDLLexer): p[0] = ListFromConcat(self.BuildAttribute(p[1], 'True'), p[2]) if self.parse_debug: DumpReduction('ext_attribute_list', p) + def p_ext_attr_list_values(self, p): + """ext_attr_list : SYMBOL '=' '(' values ')' ext_attr_cont + | SYMBOL '=' '(' symbols ')' ext_attr_cont""" + p[0] = ListFromConcat(self.BuildAttribute(p[1], p[4]), p[6]) + + def p_values(self, p): + """values : value values_cont""" + p[0] = ListFromConcat(p[1], p[2]) + + def p_symbols(self, p): + """symbols : SYMBOL symbols_cont""" + p[0] = ListFromConcat(p[1], p[2]) + + def p_symbols_cont(self, p): + """symbols_cont : ',' SYMBOL symbols_cont + | """ + if len(p) > 1: p[0] = ListFromConcat(p[2], p[3]) + + def p_values_cont(self, p): + """values_cont : ',' value values_cont + | """ + if len(p) > 1: p[0] = ListFromConcat(p[2], p[3]) + def p_ext_attr_cont(self, p): """ext_attr_cont : ',' ext_attr_list |""" @@ -555,7 +587,7 @@ class IDLParser(IDLLexer): def p_param_item(self, p): """param_item : modifiers optional SYMBOL arrays identifier""" typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1],p[2], typeref, p[4]) + children = ListFromConcat(p[1], p[2], typeref, p[4]) p[0] = self.BuildNamed('Param', p, 5, children) if self.parse_debug: DumpReduction('param_item', p) diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index 1a7f80c..99e0eb3 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py @@ -42,12 +42,6 @@ class CCGenerator(object): ) (c.Append() - .Append('using base::Value;') - .Append('using base::DictionaryValue;') - .Append('using base::ListValue;') - .Append('using base::BinaryValue;') - .Append('using %s;' % any_helper.ANY_CLASS) - .Append() .Concat(self._cpp_type_generator.GetRootNamespaceStart()) .Concat(self._cpp_type_generator.GetNamespaceStart()) .Append() @@ -173,13 +167,13 @@ class CCGenerator(object): c = Code() (c.Append('// static') .Sblock('bool %(namespace)s::Populate' - '(const Value& value, %(name)s* out) {') - .Append('if (!value.IsType(Value::TYPE_DICTIONARY))') + '(const base::Value& value, %(name)s* out) {') + .Append('if (!value.IsType(base::Value::TYPE_DICTIONARY))') .Append(' return false;') ) if type_.properties: - (c.Append('const DictionaryValue* dict = ' - 'static_cast<const DictionaryValue*>(&value);') + (c.Append('const base::DictionaryValue* dict = ' + 'static_cast<const base::DictionaryValue*>(&value);') .Append() ) for prop in type_.properties.values(): @@ -204,12 +198,12 @@ class CCGenerator(object): def _GenerateTypePopulateProperty(self, prop, src, dst): """Generate the code to populate a single property in a type. - src: DictionaryValue* + src: base::DictionaryValue* dst: Type* """ c = Code() value_var = prop.unix_name + '_value' - c.Append('Value* %(value_var)s = NULL;') + c.Append('base::Value* %(value_var)s = NULL;') if prop.optional: (c.Sblock( 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' @@ -230,14 +224,16 @@ class CCGenerator(object): return c def _GenerateTypeToValue(self, cpp_namespace, type_): - """Generates a function that serializes the type into a |DictionaryValue|. + """Generates a function that serializes the type into a + |base::DictionaryValue|. E.g. for type "Foo" generates Foo::ToValue() """ c = Code() - (c.Sblock('scoped_ptr<DictionaryValue> %s::ToValue() const {' % + (c.Sblock('scoped_ptr<base::DictionaryValue> %s::ToValue() const {' % cpp_namespace) - .Append('scoped_ptr<DictionaryValue> value(new DictionaryValue());') + .Append('scoped_ptr<base::DictionaryValue> value(' + 'new base::DictionaryValue());') .Append() ) for prop in type_.properties.values(): @@ -287,27 +283,29 @@ class CCGenerator(object): return c def _GenerateCreateEnumValue(self, cpp_namespace, prop): - """Generates CreateEnumValue() that returns the |StringValue| + """Generates CreateEnumValue() that returns the |base::StringValue| representation of an enum. """ c = Code() c.Append('// static') - c.Sblock('scoped_ptr<Value> %(cpp_namespace)s::CreateEnumValue(%(arg)s) {') + c.Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' + '%(arg)s) {') c.Sblock('switch (%s) {' % prop.unix_name) if prop.optional: (c.Append('case %s: {' % self._cpp_type_generator.GetEnumNoneValue(prop)) - .Append(' return scoped_ptr<Value>();') + .Append(' return scoped_ptr<base::Value>();') .Append('}') ) for enum_value in prop.enum_values: (c.Append('case %s: {' % self._cpp_type_generator.GetEnumValue(prop, enum_value)) - .Append(' return scoped_ptr<Value>(Value::CreateStringValue("%s"));' % - enum_value) + .Append(' return scoped_ptr<base::Value>(' + 'base::Value::CreateStringValue("%s"));' % + enum_value) .Append('}') ) (c.Append('default: {') - .Append(' return scoped_ptr<Value>();') + .Append(' return scoped_ptr<base::Value>();') .Append('}') ) c.Eblock('}') @@ -320,20 +318,20 @@ class CCGenerator(object): return c def _CreateValueFromProperty(self, prop, var): - """Creates a Value given a property. Generated code passes ownership + """Creates a base::Value given a property. Generated code passes ownership to caller. var: variable or variable* - E.g for std::string, generate Value::CreateStringValue(var) + E.g for std::string, generate base::Value::CreateStringValue(var) """ if prop.type_ == PropertyType.CHOICES: # CHOICES conversion not implemented. If needed, write something to - # generate a function that returns a scoped_ptr<Value> and put it in + # generate a function that returns a scoped_ptr<base::Value> and put it in # _GeneratePropertyFunctions, then use it here. Look at CreateEnumValue() # for reference. raise NotImplementedError( - 'Conversion of CHOICES to Value not implemented') + 'Conversion of CHOICES to base::Value not implemented') if self._IsObjectOrObjectRef(prop): if prop.optional: return '%s->ToValue().release()' % var @@ -356,13 +354,13 @@ class CCGenerator(object): var = '*' + var prop = self._cpp_type_generator.GetReferencedProperty(prop); return { - PropertyType.STRING: 'Value::CreateStringValue(%s)', - PropertyType.BOOLEAN: 'Value::CreateBooleanValue(%s)', - PropertyType.INTEGER: 'Value::CreateIntegerValue(%s)', - PropertyType.DOUBLE: 'Value::CreateDoubleValue(%s)', + PropertyType.STRING: 'base::Value::CreateStringValue(%s)', + PropertyType.BOOLEAN: 'base::Value::CreateBooleanValue(%s)', + PropertyType.INTEGER: 'base::Value::CreateIntegerValue(%s)', + PropertyType.DOUBLE: 'base::Value::CreateDoubleValue(%s)', }[prop.type_] % var else: - raise NotImplementedError('Conversion of %s to Value not ' + raise NotImplementedError('Conversion of %s to base::Value not ' 'implemented' % repr(prop.type_)) def _GenerateParamsCheck(self, function, var): @@ -391,14 +389,14 @@ class CCGenerator(object): def _GenerateFunctionParamsCreate(self, cpp_namespace, function): """Generate function to create an instance of Params. The generated - function takes a ListValue of arguments. + function takes a base::ListValue of arguments. E.g for function "Bar", generate Bar::Params::Create() """ c = Code() (c.Append('// static') .Sblock('scoped_ptr<%(cpp_namespace)s::Params> ' - '%(cpp_namespace)s::Params::Create(const ListValue& args) {') + '%(cpp_namespace)s::Params::Create(const base::ListValue& args) {') .Concat(self._GenerateParamsCheck(function, 'args')) .Append('scoped_ptr<Params> params(new Params());') ) @@ -415,9 +413,9 @@ class CCGenerator(object): failure_value = 'scoped_ptr<Params>()' c.Append() value_var = param.unix_name + '_value' - (c.Append('Value* %(value_var)s = NULL;') - .Append('if (args.Get(%(i)s, &%(value_var)s) && ' - '!%(value_var)s->IsType(Value::TYPE_NULL))') + (c.Append('base::Value* %(value_var)s = NULL;') + .Append('if (args.Get(%(i)s, &%(value_var)s) &&\n' + ' !%(value_var)s->IsType(base::Value::TYPE_NULL))') .Sblock('{') .Concat(self._GeneratePopulatePropertyFromValue( param, value_var, 'params', failure_value)) @@ -439,16 +437,17 @@ class CCGenerator(object): def _GeneratePopulatePropertyFromValue( self, prop, value_var, dst, failure_value, check_type=True): - """Generates code to populate a model.Property given a Value*. The - existence of data inside the Value* is assumed so checks for existence + """Generates code to populate a model.Property given a base::Value*. The + existence of data inside the base::Value* is assumed so checks for existence should be performed before the code this generates. prop: the property the code is populating. - value_var: a Value* that should represent |prop|. + value_var: a base::Value* that should represent |prop|. dst: the object with |prop| as a member. failure_value: the value to return if |prop| cannot be extracted from |value_var| - check_type: if true, will check if |value_var| is the correct Value::Type + check_type: if true, will check if |value_var| is the correct + base::Value::Type """ c = Code() c.Sblock('{') @@ -474,7 +473,7 @@ class CCGenerator(object): ) elif self._IsObjectOrObjectRef(prop): if prop.optional: - (c.Append('DictionaryValue* dictionary = NULL;') + (c.Append('base::DictionaryValue* dictionary = NULL;') .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') .Append(' return %(failure_value)s;') .Append('scoped_ptr<%(ctype)s> temp(new %(ctype)s());') @@ -483,7 +482,7 @@ class CCGenerator(object): .Append('%(dst)s->%(name)s = temp.Pass();') ) else: - (c.Append('DictionaryValue* dictionary = NULL;') + (c.Append('base::DictionaryValue* dictionary = NULL;') .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') .Append(' return %(failure_value)s;') .Append( @@ -492,11 +491,11 @@ class CCGenerator(object): ) elif prop.type_ == PropertyType.ANY: if prop.optional: - c.Append('%(dst)s->%(name)s.reset(new Any());') + c.Append('%(dst)s->%(name)s.reset(new ' + any_helper.ANY_CLASS + '());') c.Append(self._any_helper.Init(prop, value_var, dst) + ';') elif self._IsArrayOrArrayRef(prop): # util_cc_helper deals with optional and required arrays - (c.Append('ListValue* list = NULL;') + (c.Append('base::ListValue* list = NULL;') .Append('if (!%(value_var)s->GetAsList(&list))') .Append(' return %(failure_value)s;')) if prop.item_type.type_ == PropertyType.ENUM: @@ -533,12 +532,13 @@ class CCGenerator(object): c.Eblock('}') elif prop.type_ == PropertyType.BINARY: # This is the same if the property is optional or not. We need a pointer - # to the BinaryValue to be able to populate it, so a scoped_ptr is used - # whether it is optional or required. + # to the base::BinaryValue to be able to populate it, so a scoped_ptr is + # used whether it is optional or required. (c.Append('if (!%(value_var)s->IsType(%(value_type)s))') .Append(' return %(failure_value)s;') .Append('%(dst)s->%(name)s.reset(') - .Append(' static_cast<BinaryValue*>(%(value_var)s)->DeepCopy());') + .Append(' static_cast<base::BinaryValue*>(%(value_var)s)' + '->DeepCopy());') ) else: raise NotImplementedError(prop.type_) @@ -632,8 +632,8 @@ class CCGenerator(object): params = function.callback.params if not params: - (c.Append('Value* %s::Result::Create() {' % cpp_namespace) - .Append(' return Value::CreateNullValue();') + (c.Append('base::Value* %s::Result::Create() {' % cpp_namespace) + .Append(' return base::Value::CreateNullValue();') .Append('}') ) else: @@ -648,13 +648,14 @@ class CCGenerator(object): # time. for param in expanded_params: if param.type_ == PropertyType.ANY: - # Generation of Value* Create(Value*) is redundant. + # Generation of base::Value* Create(base::Value*) is redundant. continue # We treat this argument as 'required' to avoid wrapping it in a # scoped_ptr if it's optional. param_copy = param.Copy() param_copy.optional = False - c.Sblock('Value* %(cpp_namespace)s::Result::Create(const %(arg)s) {') + c.Sblock('base::Value* %(cpp_namespace)s::Result::Create(' + 'const %(arg)s) {') c.Append('return %s;' % self._CreateValueFromProperty(param_copy, param_copy.unix_name)) c.Eblock('}') diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py index 55cb36e..28967b0 100644 --- a/tools/json_schema_compiler/cpp_type_generator.py +++ b/tools/json_schema_compiler/cpp_type_generator.py @@ -7,7 +7,6 @@ from model import PropertyType import any_helper import cpp_util import schema_util -import string class CppTypeGenerator(object): """Manages the types of properties and provides utilities for getting the @@ -191,9 +190,10 @@ class CppTypeGenerator(object): c.Append('typedef std::string %s;' % type_name) elif namespace.types[type_].type_ == PropertyType.ARRAY: c.Append('typedef std::vector<%(item_type)s> %(name)s;') - c.Substitute({'name': type_name, 'item_type': - self.GetType(namespace.types[type_].item_type, - wrap_optional=True)}) + c.Substitute({ + 'name': type_name, + 'item_type': self.GetType(namespace.types[type_].item_type, + wrap_optional=True)}) else: c.Append('struct %s;' % type_name) c.Append('}') diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py index b22c430..7c74fad 100755 --- a/tools/json_schema_compiler/cpp_type_generator_test.py +++ b/tools/json_schema_compiler/cpp_type_generator_test.py @@ -59,12 +59,14 @@ class CppTypeGeneratorTest(unittest.TestCase): def testGenerateIncludesAndForwardDeclarationsMultipleTypes(self): m = model.Model() self.tabs_json[0]['types'].append(self.permissions_json[0]['types'][0]) - tabs_namespace = m.AddNamespace(self.tabs_json[0], - 'path/to/tabs.json') self.windows_json[0]['functions'].append( self.permissions_json[0]['functions'][1]) + # Insert 'windows' before 'tabs' in order to test that they are sorted + # properly. windows = m.AddNamespace(self.windows_json[0], 'path/to/windows.json') + tabs_namespace = m.AddNamespace(self.tabs_json[0], + 'path/to/tabs.json') manager = CppTypeGenerator('', windows, self.windows.unix_name) manager.AddNamespace(tabs_namespace, self.tabs.unix_name) self.assertEquals('#include "path/to/tabs.h"', @@ -81,16 +83,18 @@ class CppTypeGeneratorTest(unittest.TestCase): def testGenerateIncludesAndForwardDeclarationsDependencies(self): m = model.Model() - browser_action_namespace = m.AddNamespace(self.browser_action_json[0], - 'path/to/browser_action.json') + # Insert 'font_settings' before 'browser_action' in order to test that + # CppTypeGenerator sorts them properly. font_settings_namespace = m.AddNamespace(self.font_settings_json[0], 'path/to/font_settings.json') + browser_action_namespace = m.AddNamespace(self.browser_action_json[0], + 'path/to/browser_action.json') manager = CppTypeGenerator('', self.dependency_tester, self.dependency_tester.unix_name) - manager.AddNamespace(browser_action_namespace, - self.browser_action.unix_name) manager.AddNamespace(font_settings_namespace, self.font_settings.unix_name) + manager.AddNamespace(browser_action_namespace, + self.browser_action.unix_name) self.assertEquals('#include "path/to/browser_action.h"\n' '#include "path/to/font_settings.h"', manager.GenerateIncludes().Render()) diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py index b5801ef..30a357d 100644 --- a/tools/json_schema_compiler/h_generator.py +++ b/tools/json_schema_compiler/h_generator.py @@ -5,8 +5,6 @@ from code import Code from model import PropertyType import cpp_util -import model -import os import schema_util class HGenerator(object): @@ -110,7 +108,8 @@ class HGenerator(object): raise ValueError("Illegal circular dependency via cycle " + ", ".join(map(lambda x: x.name, path + [type_]))) for prop in type_.properties.values(): - if not prop.optional and prop.type_ == PropertyType.REF: + if (prop.type_ == PropertyType.REF and + schema_util.GetNamespace(prop.ref_type) == self._namespace.name): ExpandType(path + [type_], self._namespace.types[prop.ref_type]) if not type_ in dependency_order: dependency_order.append(type_) @@ -177,7 +176,6 @@ class HGenerator(object): if type_.description: c.Comment(type_.description) c.Append('typedef std::string %(classname)s;') - c.Substitute({'classname': classname}) else: if type_.description: c.Comment(type_.description) @@ -189,18 +187,18 @@ class HGenerator(object): .Concat(self._GenerateFields(type_.properties.values())) ) if type_.from_json: - (c.Comment('Populates a %s object from a Value. Returns' + (c.Comment('Populates a %s object from a base::Value. Returns' ' whether |out| was successfully populated.' % classname) - .Append( - 'static bool Populate(const Value& value, %(classname)s* out);') + .Append('static bool Populate(const base::Value& value, ' + '%(classname)s* out);') .Append() ) if type_.from_client: - (c.Comment('Returns a new DictionaryValue representing the' + (c.Comment('Returns a new base::DictionaryValue representing the' ' serialized form of this %s object. Passes ' 'ownership to caller.' % classname) - .Append('scoped_ptr<DictionaryValue> ToValue() const;') + .Append('scoped_ptr<base::DictionaryValue> ToValue() const;') ) (c.Eblock() @@ -238,7 +236,8 @@ class HGenerator(object): .Concat(self._GenerateFields(function.params)) .Append('~Params();') .Append() - .Append('static scoped_ptr<Params> Create(const ListValue& args);') + .Append('static scoped_ptr<Params> Create(' + 'const base::ListValue& args);') .Eblock() .Sblock(' private:') .Append('Params();') @@ -273,7 +272,7 @@ class HGenerator(object): enum_name, prop, prop.enum_values)) - c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % + c.Append('static scoped_ptr<base::Value> CreateEnumValue(%s %s);' % (enum_name, prop.unix_name)) return c @@ -285,7 +284,7 @@ class HGenerator(object): c.Sblock('namespace Result {') params = function.callback.params if not params: - c.Append('Value* Create();') + c.Append('base::Value* Create();') else: c.Concat(self._GeneratePropertyStructures(params)) @@ -297,11 +296,12 @@ class HGenerator(object): if param.description: c.Comment(param.description) if param.type_ == PropertyType.ANY: - c.Comment("Value* Result::Create(Value*) not generated " + c.Comment("base::Value* Result::Create(base::Value*) not generated " "because it's redundant.") continue - c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( - param, self._cpp_type_generator.GetType(param))) + c.Append('base::Value* Create(const %s);' % + cpp_util.GetParameterDeclaration( + param, self._cpp_type_generator.GetType(param))) c.Eblock('};') return c diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py index 09b75a2..d59103b 100644 --- a/tools/json_schema_compiler/idl_schema.py +++ b/tools/json_schema_compiler/idl_schema.py @@ -55,7 +55,7 @@ def ProcessComment(comment): # Escape double quotes. comment = comment.replace('"', '\\"'); - # Find all the parameter comments of the form "|name|: comment". + # Find all the parameter comments of the form '|name|: comment'. parameter_starts = list(re.finditer(r'\n *\|([^|]*)\| *: *', comment)) # Get the parent comment (everything before the first parameter comment. @@ -104,9 +104,9 @@ class Param(object): self.node = param_node def process(self, callbacks): - return Typeref(self.node.GetProperty( 'TYPEREF'), + return Typeref(self.node.GetProperty('TYPEREF'), self.node, - { 'name': self.node.GetName() }).process(callbacks) + {'name': self.node.GetName()}).process(callbacks) class Dictionary(object): ''' @@ -122,30 +122,12 @@ class Dictionary(object): if node.cls == 'Member': k, v = Member(node).process(callbacks) properties[k] = v - return { 'id': self.node.GetName(), - 'properties': properties, - 'type': 'object' } - -class Enum(object): - ''' - Given an IDL Enum node, converts into a Python dictionary that the JSON - schema compiler expects to see. - ''' - def __init__(self, enum_node): - self.node = enum_node - - def process(self, callbacks): - enum = [] - for node in self.node.children: - if node.cls == 'EnumItem': - name = node.GetName() - enum.append(name) - else: - sys.exit("Did not process %s %s" % (node.cls, node)) - return { "id" : self.node.GetName(), - 'enum': enum, - 'type': 'string' } - + result = {'id': self.node.GetName(), + 'properties': properties, + 'type': 'object'} + if self.node.GetProperty('inline_doc'): + result['inline_doc'] = True + return result class Member(object): @@ -169,8 +151,7 @@ class Member(object): if node.cls == 'Comment': (parent_comment, parameter_comments) = ProcessComment(node.GetName()) properties['description'] = parent_comment - for node in self.node.children: - if node.cls == 'Callspec': + elif node.cls == 'Callspec': is_function = True name, parameters = Callspec(node, parameter_comments).process(callbacks) properties['parameters'] = parameters @@ -180,6 +161,13 @@ class Member(object): else: properties = Typeref(self.node.GetProperty('TYPEREF'), self.node, properties).process(callbacks) + enum_values = self.node.GetProperty('legalValues') + if enum_values: + if properties['type'] == 'integer': + enum_values = map(int, enum_values) + elif properties['type'] == 'double': + enum_values = map(float, enum_values) + properties['enum'] = enum_values return name, properties class Typeref(object): @@ -240,42 +228,70 @@ class Typeref(object): return result + +class Enum(object): + ''' + Given an IDL Enum node, converts into a Python dictionary that the JSON + schema compiler expects to see. + ''' + def __init__(self, enum_node): + self.node = enum_node + self.description = '' + + def process(self, callbacks): + enum = [] + for node in self.node.children: + if node.cls == 'EnumItem': + enum.append(node.GetName()) + elif node.cls == 'Comment': + self.description = ProcessComment(node.GetName())[0] + else: + sys.exit('Did not process %s %s' % (node.cls, node)) + result = {'id' : self.node.GetName(), + 'description': self.description, + 'type': 'string', + 'enum': enum} + if self.node.GetProperty('inline_doc'): + result['inline_doc'] = True + return result + + class Namespace(object): ''' Given an IDLNode representing an IDL namespace, converts into a Python dictionary that the JSON schema compiler expects to see. ''' - def __init__(self, namespace_node, nodoc=False): + def __init__(self, namespace_node, nodoc=False, permissions=None): self.namespace = namespace_node self.nodoc = nodoc self.events = [] self.functions = [] self.types = [] self.callbacks = {} + self.permissions = permissions or [] def process(self): for node in self.namespace.children: - cls = node.cls - if cls == "Dictionary": + if node.cls == 'Dictionary': self.types.append(Dictionary(node).process(self.callbacks)) - elif cls == "Callback": + elif node.cls == 'Callback': k, v = Member(node).process(self.callbacks) self.callbacks[k] = v - elif cls == "Interface" and node.GetName() == "Functions": + elif node.cls == 'Interface' and node.GetName() == 'Functions': self.functions = self.process_interface(node) - elif cls == "Interface" and node.GetName() == "Events": + elif node.cls == 'Interface' and node.GetName() == 'Events': self.events = self.process_interface(node) - elif cls == "Enum": + elif node.cls == 'Enum': self.types.append(Enum(node).process(self.callbacks)) else: - sys.exit("Did not process %s %s" % (node.cls, node)) - - return { 'events': self.events, - 'functions': self.functions, - 'types': self.types, - 'namespace': self.namespace.GetName(), - 'nodoc': self.nodoc } + sys.exit('Did not process %s %s' % (node.cls, node)) + return {'namespace': self.namespace.GetName(), + 'nodoc': self.nodoc, + 'documentation_permissions_required': self.permissions, + 'types': self.types, + 'functions': self.functions, + 'events': self.events} def process_interface(self, node): members = [] @@ -296,23 +312,25 @@ class IDLSchema(object): def process(self): namespaces = [] + nodoc = False + permissions = None for node in self.idl: - nodoc = False - cls = node.cls - if cls == 'Namespace': - namespace = Namespace(node, nodoc) + if node.cls == 'Namespace': + namespace = Namespace(node, nodoc, permissions) namespaces.append(namespace.process()) - elif cls == 'Copyright': + elif node.cls == 'Copyright': continue - elif cls == 'Comment': + elif node.cls == 'Comment': continue - elif cls == 'ExtAttribute': + elif node.cls == 'ExtAttribute': if node.name == 'nodoc': nodoc = bool(node.value) + elif node.name == 'permissions': + permission = node.value.split(',') else: continue else: - sys.exit("Did not process %s %s" % (node.cls, node)) + sys.exit('Did not process %s %s' % (node.cls, node)) schema_util.PrefixSchemasWithNamespace(namespaces) return namespaces diff --git a/tools/json_schema_compiler/idl_schema_test.py b/tools/json_schema_compiler/idl_schema_test.py index f83d616..71bf987 100755 --- a/tools/json_schema_compiler/idl_schema_test.py +++ b/tools/json_schema_compiler/idl_schema_test.py @@ -56,11 +56,18 @@ class IdlSchemaTest(unittest.TestCase): 'parameters':[{'type':'integer', 'name':'x'}]}}] self.assertEquals(expected, getParams(schema, 'whatever')) + def testLegalValues(self): + self.assertEquals({ + 'x': {'name': 'x', 'type': 'integer', 'enum': [1,2], + 'description': 'This comment tests \\\"double-quotes\\\".'}, + 'y': {'name': 'y', 'type': 'string'}}, + getType(self.idl_basics, 'idl_basics.MyType1')['properties']) + def testEnum(self): schema = self.idl_basics - expected = {'enum': ['name1', 'name2'], + expected = {'enum': ['name1', 'name2'], 'description': 'Enum description', 'type': 'string', 'id': 'idl_basics.EnumType'} - self.assertEquals(expected, getType(schema, 'idl_basics.EnumType')) + self.assertEquals(expected, getType(schema, expected['id'])) expected = [{'name':'type', '$ref':'idl_basics.EnumType'}, {'type':'function', 'name':'Callback5', diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py index 63973d4..bb3fe0e 100644 --- a/tools/json_schema_compiler/model.py +++ b/tools/json_schema_compiler/model.py @@ -193,7 +193,9 @@ class Property(object): elif '$ref' in json: self.ref_type = json['$ref'] self.type_ = PropertyType.REF - elif 'enum' in json: + elif 'enum' in json and json.get('type') == 'string': + # Non-string enums (as in the case of [legalValues=(1,2)]) should fall + # through to the next elif. self.enum_values = [] for value in json['enum']: self.enum_values.append(value) diff --git a/tools/json_schema_compiler/schema_util.py b/tools/json_schema_compiler/schema_util.py index 289d24d..177e77f 100644 --- a/tools/json_schema_compiler/schema_util.py +++ b/tools/json_schema_compiler/schema_util.py @@ -4,6 +4,10 @@ """Utilies for the processing of schema python structures. """ +def GetNamespace(ref_type): + if '.' in ref_type: + return ref_type[:ref_type.rindex('.')] + def StripSchemaNamespace(s): last_dot = s.rfind('.') if not last_dot == -1: diff --git a/tools/json_schema_compiler/test/idl_basics.idl b/tools/json_schema_compiler/test/idl_basics.idl index af5442e..39298ec 100644 --- a/tools/json_schema_compiler/test/idl_basics.idl +++ b/tools/json_schema_compiler/test/idl_basics.idl @@ -5,13 +5,15 @@ // Tests a variety of basic API definition features. namespace idl_basics { + // Enum description enum EnumType { name1, name2 }; dictionary MyType1 { - long x; // This comment tests "double-quotes". + // This comment tests "double-quotes". + [legalValues=(1,2)] long x; DOMString y; }; |