diff options
author | Iain Merrick <husky@google.com> | 2010-10-19 14:37:37 +0100 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-10-19 14:37:37 +0100 |
commit | 3345a6884c488ff3a535c2c9acdd33d74b37e311 (patch) | |
tree | 7784b988ef1698cb6967ea1bdf07616237716c6c /webkit | |
parent | efc8475837ec58186051f23bb03542620424f6ce (diff) | |
download | external_chromium-3345a6884c488ff3a535c2c9acdd33d74b37e311.zip external_chromium-3345a6884c488ff3a535c2c9acdd33d74b37e311.tar.gz external_chromium-3345a6884c488ff3a535c2c9acdd33d74b37e311.tar.bz2 |
Merge Chromium at 7.0.540.0 : Initial merge by git
Not including third_party/icu as it contains huge data files that break Gerrit, and aren't actually used.
Change-Id: I428a386e70f3b58cacd28677b8cfda282e891e15
Diffstat (limited to 'webkit')
215 files changed, 5386 insertions, 3384 deletions
diff --git a/webkit/glue/DEPS b/webkit/glue/DEPS index e59afec..0a36ef7 100644 --- a/webkit/glue/DEPS +++ b/webkit/glue/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+app", + "+gpu", "+media", "+skia/ext", "+skia/include", diff --git a/webkit/glue/context_menu.cc b/webkit/glue/context_menu.cc new file mode 100644 index 0000000..390d740 --- /dev/null +++ b/webkit/glue/context_menu.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/context_menu.h" + +ContextMenuParams::ContextMenuParams() { +} + +ContextMenuParams::ContextMenuParams(const WebKit::WebContextMenuData& data) + : media_type(data.mediaType), + x(data.mousePosition.x), + y(data.mousePosition.y), + link_url(data.linkURL), + unfiltered_link_url(data.linkURL), + src_url(data.srcURL), + is_image_blocked(data.isImageBlocked), + page_url(data.pageURL), + frame_url(data.frameURL), + media_flags(data.mediaFlags), + selection_text(UTF16ToWideHack(data.selectedText)), + misspelled_word(data.misspelledWord), + spellcheck_enabled(data.isSpellCheckingEnabled), + is_editable(data.isEditable), +#if defined(OS_MACOSX) + writing_direction_default(data.writingDirectionDefault), + writing_direction_left_to_right(data.writingDirectionLeftToRight), + writing_direction_right_to_left(data.writingDirectionRightToLeft), +#endif // OS_MACOSX + edit_flags(data.editFlags), + security_info(data.securityInfo), + frame_charset(data.frameEncoding.utf8()) { + for (size_t i = 0; i < data.customItems.size(); ++i) + custom_items.push_back(WebMenuItem(data.customItems[i])); +} + +ContextMenuParams::~ContextMenuParams() { +} diff --git a/webkit/glue/context_menu.h b/webkit/glue/context_menu.h index 764fb9d..b681a38 100644 --- a/webkit/glue/context_menu.h +++ b/webkit/glue/context_menu.h @@ -96,34 +96,9 @@ struct ContextMenuParams { std::vector<WebMenuItem> custom_items; - ContextMenuParams() {} - - ContextMenuParams(const WebKit::WebContextMenuData& data) - : media_type(data.mediaType), - x(data.mousePosition.x), - y(data.mousePosition.y), - link_url(data.linkURL), - unfiltered_link_url(data.linkURL), - src_url(data.srcURL), - is_image_blocked(data.isImageBlocked), - page_url(data.pageURL), - frame_url(data.frameURL), - media_flags(data.mediaFlags), - selection_text(UTF16ToWideHack(data.selectedText)), - misspelled_word(data.misspelledWord), - spellcheck_enabled(data.isSpellCheckingEnabled), - is_editable(data.isEditable), -#if defined(OS_MACOSX) - writing_direction_default(data.writingDirectionDefault), - writing_direction_left_to_right(data.writingDirectionLeftToRight), - writing_direction_right_to_left(data.writingDirectionRightToLeft), -#endif // OS_MACOSX - edit_flags(data.editFlags), - security_info(data.securityInfo), - frame_charset(data.frameEncoding.utf8()) { - for (size_t i = 0; i < data.customItems.size(); ++i) - custom_items.push_back(WebMenuItem(data.customItems[i])); - } + ContextMenuParams(); + ContextMenuParams(const WebKit::WebContextMenuData& data); + ~ContextMenuParams(); }; #endif // WEBKIT_GLUE_CONTEXT_MENU_H_ diff --git a/webkit/glue/cpp_bound_class.cc b/webkit/glue/cpp_bound_class.cc index 09c3f40..d58fc4e 100644 --- a/webkit/glue/cpp_bound_class.cc +++ b/webkit/glue/cpp_bound_class.cc @@ -173,6 +173,10 @@ NPClass CppNPObject::np_class_ = { return obj->bound_class->SetProperty(ident, value); } +CppBoundClass::CppBoundClass() + : bound_to_frame_(false) { +} + CppBoundClass::~CppBoundClass() { for (MethodList::iterator i = methods_.begin(); i != methods_.end(); ++i) delete i->second; diff --git a/webkit/glue/cpp_bound_class.h b/webkit/glue/cpp_bound_class.h index dcd5c3e..a446386 100644 --- a/webkit/glue/cpp_bound_class.h +++ b/webkit/glue/cpp_bound_class.h @@ -51,7 +51,7 @@ class CppBoundClass { // The constructor should call BindMethod, BindProperty, and // SetFallbackMethod as needed to set up the methods, properties, and // fallback method. - CppBoundClass() : bound_to_frame_(false) { } + CppBoundClass(); virtual ~CppBoundClass(); // Return a CppVariant representing this class, for use with BindProperty(). diff --git a/webkit/glue/cpp_variant.cc b/webkit/glue/cpp_variant.cc index a254669..8545bc1 100644 --- a/webkit/glue/cpp_variant.cc +++ b/webkit/glue/cpp_variant.cc @@ -9,6 +9,7 @@ #include "webkit/glue/cpp_variant.h" #include "base/logging.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "base/utf_string_conversions.h" using WebKit::WebBindings; @@ -228,11 +229,11 @@ std::vector<std::wstring> CppVariant::ToStringVector() const { length = NPVARIANT_TO_INT32(length_value); WebBindings::releaseVariantValue(&length_value); - // For sanity, only allow 100 items. - length = std::min(100, length); + // For sanity, only allow 60000 items. + length = std::min(60000, length); for (int i = 0; i < length; ++i) { // Get each of the items. - std::string index = StringPrintf("%d", i); + std::string index = base::StringPrintf("%d", i); NPIdentifier index_id = WebBindings::getStringIdentifier(index.c_str()); if (WebBindings::hasProperty(NULL, np_value, index_id)) { NPVariant index_value; diff --git a/webkit/glue/devtools_message_data.cc b/webkit/glue/devtools_message_data.cc deleted file mode 100644 index a9af3c5..0000000 --- a/webkit/glue/devtools_message_data.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/devtools_message_data.h" - -#include "third_party/WebKit/WebKit/chromium/public/WebCString.h" -#include "third_party/WebKit/WebKit/chromium/public/WebDevToolsMessageData.h" - -using WebKit::WebDevToolsMessageData; -using WebKit::WebString; -using WebKit::WebVector; - -DevToolsMessageData::DevToolsMessageData(const WebDevToolsMessageData& data) - : class_name(data.className.utf8()), - method_name(data.methodName.utf8()) { - for (size_t i = 0; i < data.arguments.size(); i++) - arguments.push_back(data.arguments[i].utf8()); -} - -WebDevToolsMessageData DevToolsMessageData::ToWebDevToolsMessageData() const { - WebDevToolsMessageData result; - result.className = WebString::fromUTF8(class_name); - result.methodName = WebString::fromUTF8(method_name); - WebVector<WebString> web_args(arguments.size()); - for (size_t i = 0; i < arguments.size(); i++) - web_args[i] = WebString::fromUTF8(arguments[i]); - result.arguments.swap(web_args); - return result; -} diff --git a/webkit/glue/devtools_message_data.h b/webkit/glue/devtools_message_data.h deleted file mode 100644 index 31daa14..0000000 --- a/webkit/glue/devtools_message_data.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_DEVTOOLS_MESSAGE_DATA_H_ -#define WEBKIT_GLUE_DEVTOOLS_MESSAGE_DATA_H_ - -#include <string> -#include <vector> - -namespace WebKit { -struct WebDevToolsMessageData; -} - -struct DevToolsMessageData { - DevToolsMessageData() {} - explicit DevToolsMessageData(const WebKit::WebDevToolsMessageData&); - WebKit::WebDevToolsMessageData ToWebDevToolsMessageData() const; - - std::string class_name; - std::string method_name; - std::vector<std::string> arguments; -}; - -#endif // WEBKIT_GLUE_DEVTOOLS_DEVTOOLS_MESSAGE_DATA_H_ diff --git a/webkit/glue/devtools_strings.grd b/webkit/glue/devtools_strings.grd index a21baf5..36f14ca 100644 --- a/webkit/glue/devtools_strings.grd +++ b/webkit/glue/devtools_strings.grd @@ -19,6 +19,7 @@ Google Chrome Developer Tools. --> <output filename="devtoolsStrings_es.js" type="js_map_format" lang="es" /> <output filename="devtoolsStrings_es-419.js" type="js_map_format" lang="es-419" /> <output filename="devtoolsStrings_et.js" type="js_map_format" lang="et" /> + <output filename="devtoolsStrings_fa.js" type="js_map_format" lang="fa" /> <output filename="devtoolsStrings_fi.js" type="js_map_format" lang="fi" /> <output filename="devtoolsStrings_fil.js" type="js_map_format" lang="fil" /> <output filename="devtoolsStrings_fr.js" type="js_map_format" lang="fr" /> diff --git a/webkit/glue/dom_operations.cc b/webkit/glue/dom_operations.cc index 82e5e3a..22e0e75 100644 --- a/webkit/glue/dom_operations.cc +++ b/webkit/glue/dom_operations.cc @@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "webkit/glue/dom_operations.h" + #include <set> #include "base/compiler_specific.h" -#include "base/string_util.h" +#include "base/string_number_conversions.h" +#include "base/string_split.h" #include "third_party/WebKit/WebKit/chromium/public/WebAnimationController.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebElement.h" @@ -17,7 +20,6 @@ #include "third_party/WebKit/WebKit/chromium/public/WebNodeList.h" #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" -#include "webkit/glue/dom_operations.h" #include "webkit/glue/form_data.h" #include "webkit/glue/password_form_dom_manager.h" #include "webkit/glue/webpasswordautocompletelistener_impl.h" @@ -184,7 +186,7 @@ static bool FillFormImpl(FormElements* fe, const FormData& data) { WebKit::WebInputElement& element = it->second; if (!element.value().isEmpty()) // Don't overwrite pre-filled values. continue; - if (element.inputType() == WebInputElement::Password && + if (element.isPasswordField() && (!element.isEnabledFormControl() || element.hasAttribute("readonly"))) { continue; // Don't fill uneditable password fields. } @@ -312,7 +314,7 @@ WebString GetSubResourceLinkFromElement(const WebElement& element) { attribute_name = "src"; } else if (element.hasTagName("input")) { const WebInputElement input = element.toConst<WebInputElement>(); - if (input.inputType() == WebInputElement::Image) { + if (input.isImageButton()) { attribute_name = "src"; } } else if (element.hasTagName("body") || @@ -405,7 +407,7 @@ static int ParseSingleIconSize(const string16& text) { return 0; } int output; - if (!StringToInt(text, &output)) + if (!base::StringToInt(text, &output)) return 0; return output; } @@ -415,7 +417,7 @@ static int ParseSingleIconSize(const string16& text) { // If the input couldn't be parsed, a size with a width/height < 0 is returned. static gfx::Size ParseIconSize(const string16& text) { std::vector<string16> sizes; - SplitStringDontTrim(text, L'x', &sizes); + base::SplitStringDontTrim(text, L'x', &sizes); if (sizes.size() != 2) return gfx::Size(); @@ -591,9 +593,10 @@ int NumberOfActiveAnimations(WebView* view) { return controller->numberOfActiveAnimations(); } -void GetMetaElementsWithName(WebDocument* document, - const string16& name, - std::vector<WebElement>* meta_elements) { +void GetMetaElementsWithAttribute(WebDocument* document, + const string16& attribute_name, + const string16& attribute_value, + std::vector<WebElement>* meta_elements) { DCHECK(document); DCHECK(meta_elements); meta_elements->clear(); @@ -609,8 +612,8 @@ void GetMetaElementsWithName(WebDocument* document, WebElement element = node.to<WebElement>(); if (!element.hasTagName("meta")) continue; - WebString meta_name = element.getAttribute("name"); - if (meta_name.isNull() || meta_name != name) + WebString value = element.getAttribute(attribute_name); + if (value.isNull() || value != attribute_value) continue; meta_elements->push_back(element); } diff --git a/webkit/glue/dom_operations.h b/webkit/glue/dom_operations.h index 664add0..20084f7 100644 --- a/webkit/glue/dom_operations.h +++ b/webkit/glue/dom_operations.h @@ -6,7 +6,6 @@ #define WEBKIT_GLUE_DOM_OPERATIONS_H__ #include <string> -#include <map> #include <vector> #include "gfx/size.h" @@ -133,11 +132,12 @@ int NumberOfActiveAnimations(WebKit::WebView* view); WebKit::WebString GetSubResourceLinkFromElement( const WebKit::WebElement& element); -// Puts the meta-elements of |document| that have the specified |name| in -// |meta_elements|. -void GetMetaElementsWithName(WebKit::WebDocument* document, - const string16& name, - std::vector<WebKit::WebElement>* meta_elements); +// Puts the meta-elements of |document| that have the attribute |attribute_name| +// with a value of |attribute_value| in |meta_elements|. +void GetMetaElementsWithAttribute(WebKit::WebDocument* document, + const string16& attribute_name, + const string16& atribute_value, + std::vector<WebKit::WebElement>* meta_elements); } // namespace webkit_glue diff --git a/webkit/glue/dom_operations_unittest.cc b/webkit/glue/dom_operations_unittest.cc index e9f590c..c57e943 100644 --- a/webkit/glue/dom_operations_unittest.cc +++ b/webkit/glue/dom_operations_unittest.cc @@ -5,6 +5,7 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" diff --git a/webkit/glue/dom_serializer_unittest.cc b/webkit/glue/dom_serializer_unittest.cc index a1846f3..62b5a3d 100644 --- a/webkit/glue/dom_serializer_unittest.cc +++ b/webkit/glue/dom_serializer_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,7 @@ #include "base/file_path.h" #include "base/file_util.h" #include "base/hash_tables.h" +#include "base/string_util.h" #include "base/utf_string_conversions.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context.h" @@ -582,6 +583,7 @@ TEST_F(DomSerializerTests, SerializeHTMLDOMWithEntitiesInText) { // Test situation of html entities in attribute value when serializing // HTML DOM. +// This test started to fail at WebKit r65388. See http://crbug.com/52279. TEST_F(DomSerializerTests, SerializeHTMLDOMWithEntitiesInAttributeValue) { FilePath page_file_path = data_dir_; page_file_path = page_file_path.AppendASCII( @@ -631,6 +633,7 @@ TEST_F(DomSerializerTests, SerializeHTMLDOMWithEntitiesInAttributeValue) { } // Test situation of non-standard HTML entities when serializing HTML DOM. +// This test started to fail at WebKit r65351. See http://crbug.com/52279. TEST_F(DomSerializerTests, SerializeHTMLDOMWithNonStandardEntities) { // Make a test file URL and load it. FilePath page_file_path = data_dir_; @@ -644,7 +647,7 @@ TEST_F(DomSerializerTests, SerializeHTMLDOMWithNonStandardEntities) { WebDocument doc = web_frame->document(); ASSERT_TRUE(doc.isHTMLDocument()); WebElement body_element = doc.body(); - // Unescaped string for "%⊅&supl;'". + // Unescaped string for "%⊅¹'". static const wchar_t parsed_value[] = { '%', 0x2285, 0x00b9, '\'', 0 }; @@ -661,7 +664,7 @@ TEST_F(DomSerializerTests, SerializeHTMLDOMWithNonStandardEntities) { // Confirm that the serialized string has no non-standard HTML entities. ASSERT_EQ(std::string::npos, serialized_contents.find("%")); ASSERT_EQ(std::string::npos, serialized_contents.find("⊅")); - ASSERT_EQ(std::string::npos, serialized_contents.find("&supl;")); + ASSERT_EQ(std::string::npos, serialized_contents.find("¹")); ASSERT_EQ(std::string::npos, serialized_contents.find("'")); } diff --git a/webkit/glue/form_data.cc b/webkit/glue/form_data.cc new file mode 100644 index 0000000..4e1a6ea --- /dev/null +++ b/webkit/glue/form_data.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/form_data.h" + +namespace webkit_glue { + +FormData::FormData() + : user_submitted(false) { +} + +FormData::FormData(const FormData& data) + : name(data.name), + method(data.method), + origin(data.origin), + action(data.action), + user_submitted(data.user_submitted), + fields(data.fields) { +} + +FormData::~FormData() { +} + +bool FormData::operator==(const FormData& form) const { + return (name == form.name && + StringToLowerASCII(method) == StringToLowerASCII(form.method) && + origin == form.origin && + action == form.action && + user_submitted == form.user_submitted && + fields == form.fields); +} + +} // namespace webkit_glue diff --git a/webkit/glue/form_data.h b/webkit/glue/form_data.h index 2bb7115..063b021 100644 --- a/webkit/glue/form_data.h +++ b/webkit/glue/form_data.h @@ -27,17 +27,17 @@ struct FormData { GURL origin; // The action target of the form. GURL action; + // true if this form was submitted by a user gesture and not javascript. + bool user_submitted; // A vector of all the input fields in the form. std::vector<FormField> fields; + FormData(); + FormData(const FormData& data); + ~FormData(); + // Used by FormStructureTest. - inline bool operator==(const FormData& form) const { - return (name == form.name && - StringToLowerASCII(method) == StringToLowerASCII(form.method) && - origin == form.origin && - action == form.action && - fields == form.fields); - } + bool operator==(const FormData& form) const; }; } // namespace webkit_glue diff --git a/webkit/glue/form_field.cc b/webkit/glue/form_field.cc index a0fbdef..30d22ad 100644 --- a/webkit/glue/form_field.cc +++ b/webkit/glue/form_field.cc @@ -66,6 +66,9 @@ FormField::FormField(const string16& label, size_(size) { } +FormField::~FormField() { +} + bool FormField::operator==(const FormField& field) const { // A FormField stores a value, but the value is not part of the identity of // the field, so we don't want to compare the values. diff --git a/webkit/glue/form_field.h b/webkit/glue/form_field.h index 2a1ffcf..56d8969 100644 --- a/webkit/glue/form_field.h +++ b/webkit/glue/form_field.h @@ -22,6 +22,7 @@ class FormField { const string16& value, const string16& form_control_type, int size); + ~FormField(); const string16& label() const { return label_; } const string16& name() const { return name_; } diff --git a/webkit/glue/ftp_directory_listing_response_delegate.h b/webkit/glue/ftp_directory_listing_response_delegate.h index 1218da9..e259c1e 100644 --- a/webkit/glue/ftp_directory_listing_response_delegate.h +++ b/webkit/glue/ftp_directory_listing_response_delegate.h @@ -61,6 +61,8 @@ class FtpDirectoryListingResponseDelegate { // True if we got an error when parsing the response. bool had_parsing_error_; + + DISALLOW_COPY_AND_ASSIGN(FtpDirectoryListingResponseDelegate); }; } // namespace webkit_glue diff --git a/webkit/glue/glue_serialize.cc b/webkit/glue/glue_serialize.cc index caf37b4..835ae78 100644 --- a/webkit/glue/glue_serialize.cc +++ b/webkit/glue/glue_serialize.cc @@ -15,11 +15,11 @@ #include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" #include "third_party/WebKit/WebKit/chromium/public/WebSerializedScriptValue.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "webkit/glue/webkit_glue.h" using WebKit::WebData; -using WebKit::WebFileInfo; using WebKit::WebHistoryItem; using WebKit::WebHTTPBody; using WebKit::WebPoint; @@ -56,12 +56,13 @@ struct SerializeObject { // 7: Adds support for stateObject // 8: Adds support for file range and modification time // 9: Adds support for itemSequenceNumbers +// 10: Adds support for blob // Should be const, but unit tests may modify it. // // NOTE: If the version is -1, then the pickle contains only a URL string. // See CreateHistoryStateForURL. // -int kVersion = 9; +int kVersion = 10; // A bunch of convenience functions to read/write to SerializeObjects. // The serializers assume the input data is in the correct format and so does @@ -191,7 +192,9 @@ inline WebString ReadString(const SerializeObject* obj) { // In version 2, the length field was the length in WebUChars. // In version 1 and 3 it is the length in bytes. - int bytes = ((obj->version == 2) ? length * sizeof(WebUChar) : length); + int bytes = length; + if (obj->version == 2) + bytes *= sizeof(WebUChar); const void* data; if (!ReadBytes(obj, &data, bytes)) @@ -232,11 +235,13 @@ static void WriteFormData(const WebHTTPBody& http_body, SerializeObject* obj) { if (element.type == WebHTTPBody::Element::TypeData) { WriteData(element.data.data(), static_cast<int>(element.data.size()), obj); - } else { + } else if (element.type == WebHTTPBody::Element::TypeFile) { WriteString(element.filePath, obj); WriteInteger64(element.fileStart, obj); WriteInteger64(element.fileLength, obj); - WriteReal(element.fileInfo.modificationTime, obj); + WriteReal(element.modificationTime, obj); + } else { + WriteGURL(element.blobURL, obj); } } WriteInteger64(http_body.identifier(), obj); @@ -263,17 +268,21 @@ static WebHTTPBody ReadFormData(const SerializeObject* obj) { ReadData(obj, &data, &length); if (length >= 0) http_body.appendData(WebData(static_cast<const char*>(data), length)); - } else { + } else if (type == WebHTTPBody::Element::TypeFile) { WebString file_path = ReadString(obj); long long file_start = 0; long long file_length = -1; - WebFileInfo file_info; + double modification_time = 0.0; if (obj->version >= 8) { file_start = ReadInteger64(obj); file_length = ReadInteger64(obj); - file_info.modificationTime = ReadReal(obj); + modification_time = ReadReal(obj); } - http_body.appendFileRange(file_path, file_start, file_length, file_info); + http_body.appendFileRange(file_path, file_start, file_length, + modification_time); + } else if (obj->version >= 10) { + GURL blob_url = ReadGURL(obj); + http_body.appendBlob(blob_url); } } if (obj->version >= 4) diff --git a/webkit/glue/idb_bindings.cc b/webkit/glue/idb_bindings.cc new file mode 100644 index 0000000..fd26130 --- /dev/null +++ b/webkit/glue/idb_bindings.cc @@ -0,0 +1,69 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/idb_bindings.h" + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "base/string16.h" +#include "base/utf_string_conversions.h" +#include "third_party/WebKit/WebKit/chromium/public/WebIDBKey.h" +#include "third_party/WebKit/WebKit/chromium/public/WebIDBKeyPath.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSerializedScriptValue.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "v8/include/v8.h" + +namespace webkit_glue { + +using WebKit::WebIDBKey; +using WebKit::WebIDBKeyPath; +using WebKit::WebSerializedScriptValue; + +namespace { + +class LocalContext { + public: + LocalContext() + : context_(v8::Context::New()) { + context_->Enter(); + } + + virtual ~LocalContext() { + context_->Exit(); + context_.Dispose(); + } + + private: + v8::Locker lock_; + v8::HandleScope scope_; + v8::Persistent<v8::Context> context_; + + DISALLOW_COPY_AND_ASSIGN(LocalContext); +}; + +} // namespace + +bool IDBKeysFromValuesAndKeyPath( + const std::vector<WebSerializedScriptValue>& serialized_script_values, + const string16& idb_key_path, + std::vector<WebIDBKey>* values) { + LocalContext env; + WebIDBKeyPath web_idb_key_path = WebIDBKeyPath::create(idb_key_path); + bool error = web_idb_key_path.parseError() != 0; + // TODO(bulach): what to do when we have a parse error? For now, setting + // all values back as invalid and returning a boolean. + for (std::vector<WebSerializedScriptValue>::const_iterator i = + serialized_script_values.begin(); + i != serialized_script_values.end(); ++i) { + if (error) { + values->push_back(WebIDBKey::createInvalid()); + } else { + values->push_back( + WebIDBKey::createFromValueAndKeyPath(*i, web_idb_key_path)); + } + } + return error; +} + +} // namespace webkit_glue diff --git a/webkit/glue/idb_bindings.h b/webkit/glue/idb_bindings.h new file mode 100644 index 0000000..074595d --- /dev/null +++ b/webkit/glue/idb_bindings.h @@ -0,0 +1,25 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/basictypes.h" +#include "base/string16.h" + +namespace WebKit { +class WebIDBKey; +class WebSerializedScriptValue; +} + +namespace webkit_glue { + +// Warning: this method holds a V8 lock, it should only be called within a +// sandbox. +bool IDBKeysFromValuesAndKeyPath( + const std::vector<WebKit::WebSerializedScriptValue>& + serialized_script_values, + const string16& idb_key_path, + std::vector<WebKit::WebIDBKey>* values); + +} // namespace webkit_glue diff --git a/webkit/glue/inspector_strings.grd b/webkit/glue/inspector_strings.grd index 9d634b7..22f147d 100644 --- a/webkit/glue/inspector_strings.grd +++ b/webkit/glue/inspector_strings.grd @@ -55,6 +55,7 @@ so we include the original license below: <output filename="inspectorStrings_es.js" type="js_map_format" lang="es" /> <output filename="inspectorStrings_es-419.js" type="js_map_format" lang="es-419" /> <output filename="inspectorStrings_et.js" type="js_map_format" lang="et" /> + <output filename="inspectorStrings_fa.js" type="js_map_format" lang="fa" /> <output filename="inspectorStrings_fi.js" type="js_map_format" lang="fi" /> <output filename="inspectorStrings_fil.js" type="js_map_format" lang="fil" /> <output filename="inspectorStrings_fr.js" type="js_map_format" lang="fr" /> diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc index dfac588..f4aad57 100644 --- a/webkit/glue/media/buffered_data_source.cc +++ b/webkit/glue/media/buffered_data_source.cc @@ -350,7 +350,9 @@ void BufferedResourceLoader::OnReceivedData(const char* data, int len) { } void BufferedResourceLoader::OnCompletedRequest( - const URLRequestStatus& status, const std::string& security_info) { + const URLRequestStatus& status, + const std::string& security_info, + const base::Time& completion_time) { DCHECK(bridge_.get()); // Saves the information that the request has completed. diff --git a/webkit/glue/media/buffered_data_source.h b/webkit/glue/media/buffered_data_source.h index 0dc2115..b520418 100644 --- a/webkit/glue/media/buffered_data_source.h +++ b/webkit/glue/media/buffered_data_source.h @@ -5,9 +5,7 @@ #ifndef WEBKIT_GLUE_MEDIA_BUFFERED_DATA_SOURCE_H_ #define WEBKIT_GLUE_MEDIA_BUFFERED_DATA_SOURCE_H_ -#include <algorithm> #include <string> -#include <vector> #include "base/callback.h" #include "base/lock.h" @@ -118,9 +116,12 @@ class BufferedResourceLoader : virtual void OnReceivedResponse( const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, bool content_filtered); + virtual void OnDownloadedData(int len) {} virtual void OnReceivedData(const char* data, int len); - virtual void OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info); + virtual void OnCompletedRequest( + const URLRequestStatus& status, + const std::string& security_info, + const base::Time& completion_time); GURL GetURLForDebugging() const { return url_; } protected: diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc index ce42437..7254c92 100644 --- a/webkit/glue/media/buffered_data_source_unittest.cc +++ b/webkit/glue/media/buffered_data_source_unittest.cc @@ -6,7 +6,9 @@ #include "base/callback.h" #include "base/format_macros.h" +#include "base/message_loop.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "media/base/filters.h" #include "media/base/mock_filter_host.h" #include "media/base/mock_filters.h" @@ -51,7 +53,7 @@ ACTION_P(RequestCanceled, loader) { URLRequestStatus status; status.set_status(URLRequestStatus::CANCELED); status.set_os_error(net::ERR_ABORTED); - loader->OnCompletedRequest(status, ""); + loader->OnCompletedRequest(status, "", base::Time()); } class BufferedResourceLoaderTest : public testing::Test { @@ -98,9 +100,9 @@ class BufferedResourceLoaderTest : public testing::Test { void FullResponse(int64 instance_size) { EXPECT_CALL(*this, StartCallback(net::OK)); ResourceLoaderBridge::ResponseInfo info; - std::string header = StringPrintf("HTTP/1.1 200 OK\n" - "Content-Length: %" PRId64, - instance_size); + std::string header = base::StringPrintf("HTTP/1.1 200 OK\n" + "Content-Length: %" PRId64, + instance_size); replace(header.begin(), header.end(), '\n', '\0'); info.headers = new net::HttpResponseHeaders(header); info.content_length = instance_size; @@ -115,12 +117,12 @@ class BufferedResourceLoaderTest : public testing::Test { EXPECT_CALL(*this, StartCallback(net::OK)); int64 content_length = last_position - first_position + 1; ResourceLoaderBridge::ResponseInfo info; - std::string header = StringPrintf("HTTP/1.1 206 Partial Content\n" - "Content-Range: bytes " - "%" PRId64 "-%" PRId64 "/%" PRId64, - first_position, - last_position, - instance_size); + std::string header = base::StringPrintf("HTTP/1.1 206 Partial Content\n" + "Content-Range: bytes " + "%" PRId64 "-%" PRId64 "/%" PRId64, + first_position, + last_position, + instance_size); replace(header.begin(), header.end(), '\n', '\0'); info.headers = new net::HttpResponseHeaders(header); info.content_length = content_length; @@ -267,9 +269,9 @@ TEST_F(BufferedResourceLoaderTest, InvalidPartialResponse) { .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); ResourceLoaderBridge::ResponseInfo info; - std::string header = StringPrintf("HTTP/1.1 206 Partial Content\n" - "Content-Range: bytes %d-%d/%d", - 1, 10, 1024); + std::string header = base::StringPrintf("HTTP/1.1 206 Partial Content\n" + "Content-Range: bytes %d-%d/%d", + 1, 10, 1024); replace(header.begin(), header.end(), '\n', '\0'); info.headers = new net::HttpResponseHeaders(header); info.content_length = 10; @@ -315,7 +317,7 @@ TEST_F(BufferedResourceLoaderTest, BufferAndRead) { .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); URLRequestStatus status; status.set_status(URLRequestStatus::SUCCESS); - loader_->OnCompletedRequest(status, ""); + loader_->OnCompletedRequest(status, "", base::Time()); // Try to read 10 from position 25 will just return with 5 bytes. EXPECT_CALL(*this, ReadCallback(5)); @@ -361,7 +363,7 @@ TEST_F(BufferedResourceLoaderTest, ReadOutsideBuffer) { .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); URLRequestStatus status; status.set_status(URLRequestStatus::SUCCESS); - loader_->OnCompletedRequest(status, ""); + loader_->OnCompletedRequest(status, "", base::Time()); } TEST_F(BufferedResourceLoaderTest, RequestFailedWhenRead) { @@ -379,7 +381,7 @@ TEST_F(BufferedResourceLoaderTest, RequestFailedWhenRead) { .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); URLRequestStatus status; status.set_status(URLRequestStatus::FAILED); - loader_->OnCompletedRequest(status, ""); + loader_->OnCompletedRequest(status, "", base::Time()); } // Tests the logic of caching data to disk when media is paused. diff --git a/webkit/glue/media/media_resource_loader_bridge_factory.cc b/webkit/glue/media/media_resource_loader_bridge_factory.cc index 1961bcc..9d8d547 100644 --- a/webkit/glue/media/media_resource_loader_bridge_factory.cc +++ b/webkit/glue/media/media_resource_loader_bridge_factory.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,7 @@ #include "base/format_macros.h" #include "base/string_util.h" +#include "base/stringprintf.h" namespace { @@ -61,12 +62,13 @@ const std::string MediaResourceLoaderBridgeFactory::GenerateHeaders ( if (first_byte_position > kPositionNotSpecified && last_byte_position > kPositionNotSpecified) { if (first_byte_position <= last_byte_position) { - header = StringPrintf("Range: bytes=%" PRId64 "-%" PRId64, - first_byte_position, - last_byte_position); + header = base::StringPrintf("Range: bytes=%" PRId64 "-%" PRId64, + first_byte_position, + last_byte_position); } } else if (first_byte_position > kPositionNotSpecified) { - header = StringPrintf("Range: bytes=%" PRId64 "-", first_byte_position); + header = base::StringPrintf("Range: bytes=%" PRId64 "-", + first_byte_position); } else if (last_byte_position > kPositionNotSpecified) { NOTIMPLEMENTED() << "Suffix range not implemented"; } diff --git a/webkit/glue/media/media_resource_loader_bridge_factory.h b/webkit/glue/media/media_resource_loader_bridge_factory.h index 6408949..5f09235 100644 --- a/webkit/glue/media/media_resource_loader_bridge_factory.h +++ b/webkit/glue/media/media_resource_loader_bridge_factory.h @@ -5,7 +5,7 @@ #ifndef WEBKIT_GLUE_MEDIA_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ #define WEBKIT_GLUE_MEDIA_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ -#include "testing/gtest/include/gtest/gtest_prod.h" +#include "base/gtest_prod_util.h" #include "webkit/glue/resource_loader_bridge.h" namespace webkit_glue { @@ -44,7 +44,8 @@ class MediaResourceLoaderBridgeFactory { } private: - FRIEND_TEST(MediaResourceLoaderBridgeFactoryTest, GenerateHeaders); + FRIEND_TEST_ALL_PREFIXES(MediaResourceLoaderBridgeFactoryTest, + GenerateHeaders); // Returns a range request header using parameters |first_byte_position| and // |last_byte_position|. diff --git a/webkit/glue/media/mock_media_resource_loader_bridge_factory.h b/webkit/glue/media/mock_media_resource_loader_bridge_factory.h index 7bb27fe..3c0a3ae 100644 --- a/webkit/glue/media/mock_media_resource_loader_bridge_factory.h +++ b/webkit/glue/media/mock_media_resource_loader_bridge_factory.h @@ -1,9 +1,9 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ -#define WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ +#ifndef WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ +#define WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ #include "testing/gmock/include/gmock/gmock.h" #include "webkit/glue/media/media_resource_loader_bridge_factory.h" @@ -33,4 +33,4 @@ class MockMediaResourceLoaderBridgeFactory } // namespace webkit_glue -#endif // WEBKIT_GLUE_MEDIA_MOCK_RESOURCE_LOADER_BRIDGE_H_ +#endif // WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc index 20bf0af..56deaeb 100644 --- a/webkit/glue/media/simple_data_source.cc +++ b/webkit/glue/media/simple_data_source.cc @@ -120,10 +120,6 @@ bool SimpleDataSource::IsStreaming() { return false; } -void SimpleDataSource::OnDownloadProgress(uint64 position, uint64 size) {} - -void SimpleDataSource::OnUploadProgress(uint64 position, uint64 size) {} - bool SimpleDataSource::OnReceivedRedirect( const GURL& new_url, const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, @@ -146,7 +142,8 @@ void SimpleDataSource::OnReceivedData(const char* data, int len) { } void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info) { + const std::string& security_info, + const base::Time& completion_time) { AutoLock auto_lock(lock_); // It's possible this gets called after Stop(), in which case |host_| is no // longer valid. diff --git a/webkit/glue/media/simple_data_source.h b/webkit/glue/media/simple_data_source.h index 577d973..d238f61 100644 --- a/webkit/glue/media/simple_data_source.h +++ b/webkit/glue/media/simple_data_source.h @@ -51,8 +51,7 @@ class SimpleDataSource : public media::DataSource, virtual bool IsStreaming(); // webkit_glue::ResourceLoaderBridge::Peer implementation. - virtual void OnDownloadProgress(uint64 position, uint64 size); - virtual void OnUploadProgress(uint64 position, uint64 size); + virtual void OnUploadProgress(uint64 position, uint64 size) {} virtual bool OnReceivedRedirect( const GURL& new_url, const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, @@ -61,9 +60,11 @@ class SimpleDataSource : public media::DataSource, virtual void OnReceivedResponse( const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, bool content_filtered); + virtual void OnDownloadedData(int len) {} virtual void OnReceivedData(const char* data, int len); virtual void OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info); + const std::string& security_info, + const base::Time& completion_time); virtual GURL GetURLForDebugging() const; private: diff --git a/webkit/glue/media/simple_data_source_unittest.cc b/webkit/glue/media/simple_data_source_unittest.cc index e6acba9..d05bb72 100644 --- a/webkit/glue/media/simple_data_source_unittest.cc +++ b/webkit/glue/media/simple_data_source_unittest.cc @@ -105,7 +105,7 @@ class SimpleDataSourceTest : public testing::Test { URLRequestStatus status; status.set_status(URLRequestStatus::SUCCESS); status.set_os_error(0); - data_source_->OnCompletedRequest(status, ""); + data_source_->OnCompletedRequest(status, "", base::Time()); // Let the tasks to be executed. MessageLoop::current()->RunAllPending(); @@ -122,7 +122,7 @@ class SimpleDataSourceTest : public testing::Test { URLRequestStatus status; status.set_status(URLRequestStatus::FAILED); status.set_os_error(100); - data_source_->OnCompletedRequest(status, ""); + data_source_->OnCompletedRequest(status, "", base::Time()); // Let the tasks to be executed. MessageLoop::current()->RunAllPending(); diff --git a/webkit/glue/media/video_renderer_impl.cc b/webkit/glue/media/video_renderer_impl.cc index 796d07f..6d7323d 100644 --- a/webkit/glue/media/video_renderer_impl.cc +++ b/webkit/glue/media/video_renderer_impl.cc @@ -95,6 +95,16 @@ void VideoRendererImpl::Paint(skia::PlatformCanvas* canvas, PutCurrentFrame(video_frame); } +void VideoRendererImpl::GetCurrentFrame( + scoped_refptr<media::VideoFrame>* frame_out) { + VideoRendererBase::GetCurrentFrame(frame_out); +} + +void VideoRendererImpl::PutCurrentFrame( + scoped_refptr<media::VideoFrame> frame) { + VideoRendererBase::PutCurrentFrame(frame); +} + // CanFastPaint is a helper method to determine the conditions for fast // painting. The conditions are: // 1. No skew in canvas matrix. diff --git a/webkit/glue/media/video_renderer_impl.h b/webkit/glue/media/video_renderer_impl.h index 30f2e38..39ce1b2 100644 --- a/webkit/glue/media/video_renderer_impl.h +++ b/webkit/glue/media/video_renderer_impl.h @@ -27,6 +27,8 @@ class VideoRendererImpl : public WebVideoRenderer { // WebVideoRenderer implementation. virtual void SetRect(const gfx::Rect& rect); virtual void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect); + virtual void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out); + virtual void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame); // Static method for creating factory for this object. static media::FilterFactory* CreateFactory(WebMediaPlayerImpl::Proxy* proxy, diff --git a/webkit/glue/media/web_video_renderer.h b/webkit/glue/media/web_video_renderer.h index 8bafb1a..d8b47ad 100644 --- a/webkit/glue/media/web_video_renderer.h +++ b/webkit/glue/media/web_video_renderer.h @@ -1,10 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this -// source code is governed by a BSD-style license that can be found in the -// LICENSE file. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. #ifndef WEBKIT_GLUE_MEDIA_WEB_VIDEO_RENDERER_H_ #define WEBKIT_GLUE_MEDIA_WEB_VIDEO_RENDERER_H_ +#include "media/base/video_frame.h" #include "media/filters/video_renderer_base.h" namespace webkit_glue { @@ -30,6 +31,15 @@ class WebVideoRenderer : public media::VideoRendererBase { virtual void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect) = 0; + // Clients of this class (painter/compositor) should use GetCurrentFrame() + // obtain ownership of VideoFrame, it should always relinquish the ownership + // by use PutCurrentFrame(). Current frame is not guaranteed to be non-NULL. + // It expects clients to use color-fill the background if current frame + // is NULL. This could happen when before pipeline is pre-rolled or during + // pause/flush/seek. + virtual void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out) {} + virtual void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame) {} + private: DISALLOW_COPY_AND_ASSIGN(WebVideoRenderer); }; diff --git a/webkit/glue/mimetype_unittest.cc b/webkit/glue/mimetype_unittest.cc index 152d20d..1c2e5f4 100644 --- a/webkit/glue/mimetype_unittest.cc +++ b/webkit/glue/mimetype_unittest.cc @@ -25,18 +25,17 @@ class MimeTypeTests : public TestShellTest { void CheckMimeType(const char* mimetype, const std::wstring& expected) { std::string path("contenttype?"); - GURL url = server_->TestServerPage(path + mimetype); + GURL url(test_server_.GetURL(path + mimetype)); LoadURL(url); WebFrame* frame = test_shell_->webView()->mainFrame(); EXPECT_EQ(expected, webkit_glue::DumpDocumentText(frame)); } - scoped_refptr<UnittestTestServer> server_; + UnittestTestServer test_server_; }; TEST_F(MimeTypeTests, MimeTypeTests) { - server_ = UnittestTestServer::CreateServer(); - ASSERT_TRUE(NULL != server_.get()); + ASSERT_TRUE(test_server_.Start()); std::wstring expected_src(L"<html>\n<body>\n" L"<p>HTML text</p>\n</body>\n</html>\n"); diff --git a/webkit/glue/mock_resource_loader_bridge.h b/webkit/glue/mock_resource_loader_bridge.h index 7176e04..49c41ed 100644 --- a/webkit/glue/mock_resource_loader_bridge.h +++ b/webkit/glue/mock_resource_loader_bridge.h @@ -1,14 +1,15 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ -#define WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ +#ifndef WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ +#define WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ -#include "base/file_path.h" #include "testing/gmock/include/gmock/gmock.h" #include "webkit/glue/resource_loader_bridge.h" +class FilePath; + namespace webkit_glue { class MockResourceLoaderBridge : public webkit_glue::ResourceLoaderBridge { @@ -21,11 +22,12 @@ class MockResourceLoaderBridge : public webkit_glue::ResourceLoaderBridge { } MOCK_METHOD2(AppendDataToUpload, void(const char* data, int data_len)); - MOCK_METHOD4(AppendFileRangeToUpload, + MOCK_METHOD4(AppendFileRangeToUpload, void(const FilePath& file_path, uint64 offset, uint64 length, const base::Time& expected_modification_time)); + MOCK_METHOD1(AppendBlobToUpload, void(const GURL& blob_url)); MOCK_METHOD1(SetUploadIdentifier, void(int64 identifier)); MOCK_METHOD1(Start, bool(ResourceLoaderBridge::Peer* peer)); MOCK_METHOD0(Cancel, void()); @@ -39,4 +41,4 @@ class MockResourceLoaderBridge : public webkit_glue::ResourceLoaderBridge { } // namespace webkit_glue -#endif // WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ +#endif // WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc index 0b37050..4839a91 100644 --- a/webkit/glue/multipart_response_delegate.cc +++ b/webkit/glue/multipart_response_delegate.cc @@ -5,6 +5,7 @@ #include "webkit/glue/multipart_response_delegate.h" #include "base/logging.h" +#include "base/string_number_conversions.h" #include "base/string_util.h" #include "net/base/net_util.h" #include "net/http/http_util.h" @@ -125,13 +126,13 @@ void MultipartResponseDelegate::OnReceivedData(const char* data, size_t boundary_pos; while ((boundary_pos = FindBoundary()) != std::string::npos) { - if (boundary_pos > 0 && client_) { + if (client_) { // Strip out trailing \n\r characters in the buffer preceding the // boundary on the same lines as Firefox. size_t data_length = boundary_pos; - if (data_[boundary_pos - 1] == '\n') { + if (boundary_pos > 0 && data_[boundary_pos - 1] == '\n') { data_length--; - if (data_[boundary_pos - 2] == '\r') { + if (boundary_pos > 1 && data_[boundary_pos - 2] == '\r') { data_length--; } } @@ -363,9 +364,9 @@ bool MultipartResponseDelegate::ReadContentRanges( content_range.substr(byte_range_upper_bound_start_offset, byte_range_upper_bound_characters); - if (!StringToInt(byte_range_lower_bound, content_range_lower_bound)) + if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) return false; - if (!StringToInt(byte_range_upper_bound, content_range_upper_bound)) + if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) return false; return true; } diff --git a/webkit/glue/multipart_response_delegate_unittest.cc b/webkit/glue/multipart_response_delegate_unittest.cc index 0433b52..ffacfb3 100644 --- a/webkit/glue/multipart_response_delegate_unittest.cc +++ b/webkit/glue/multipart_response_delegate_unittest.cc @@ -72,7 +72,7 @@ class MockWebURLLoaderClient : public WebURLLoaderClient { data_.append(data, data_length); } - virtual void didFinishLoading(WebURLLoader*) {} + virtual void didFinishLoading(WebURLLoader*, double finishTime) {} virtual void didFail(WebURLLoader*, const WebURLError&) {} void Reset() { @@ -97,11 +97,9 @@ TEST(MultipartResponseTest, Functions) { WebURLResponse response; response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response.setHTTPHeaderField(WebString::fromUTF8("Foo"), - WebString::fromUTF8("Bar")); - response.setHTTPHeaderField(WebString::fromUTF8("Content-type"), - WebString::fromUTF8("text/plain")); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Foo", "Bar"); + response.setHTTPHeaderField("Content-type", "text/plain"); MockWebURLLoaderClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); MultipartResponseDelegateTester delegate_tester(&delegate); @@ -203,11 +201,9 @@ TEST(MultipartResponseTest, Functions) { TEST(MultipartResponseTest, MissingBoundaries) { WebURLResponse response; response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response.setHTTPHeaderField(WebString::fromUTF8("Foo"), - WebString::fromUTF8("Bar")); - response.setHTTPHeaderField(WebString::fromUTF8("Content-type"), - WebString::fromUTF8("text/plain")); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Foo", "Bar"); + response.setHTTPHeaderField("Content-type", "text/plain"); MockWebURLLoaderClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); @@ -270,11 +266,9 @@ TEST(MultipartResponseTest, MalformedBoundary) { WebURLResponse response; response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response.setHTTPHeaderField(WebString::fromUTF8("Foo"), - WebString::fromUTF8("Bar")); - response.setHTTPHeaderField(WebString::fromUTF8("Content-type"), - WebString::fromUTF8("text/plain")); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Foo", "Bar"); + response.setHTTPHeaderField("Content-type", "text/plain"); MockWebURLLoaderClient client; MultipartResponseDelegate delegate(&client, NULL, response, "--bound"); @@ -318,7 +312,7 @@ void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size, WebURLResponse response; response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); + response.setMIMEType("multipart/x-mixed-replace"); MockWebURLLoaderClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); @@ -428,11 +422,37 @@ TEST(MultipartResponseTest, BreakInData) { 2, 2, "foof"); } +TEST(MultipartResponseTest, SmallChunk) { + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Content-type", "text/plain"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + + // Test chunks of size 1, 2, and 0. + string data( + "--boundContent-type: text/plain\n\n" + "\n--boundContent-type: text/plain\n\n" + "\n\n--boundContent-type: text/plain\n\n" + "--boundContent-type: text/plain\n\n" + "end--bound--"); + delegate.OnReceivedData(data.c_str(), + static_cast<int>(data.length())); + EXPECT_EQ(4, client.received_response_); + EXPECT_EQ(2, client.received_data_); + EXPECT_EQ(string("end"), client.data_); + + delegate.OnCompletedRequest(); + EXPECT_EQ(4, client.received_response_); + EXPECT_EQ(2, client.received_data_); +} + TEST(MultipartResponseTest, MultipleBoundaries) { // Test multiple boundaries back to back WebURLResponse response; response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); + response.setMIMEType("multipart/x-mixed-replace"); MockWebURLLoaderClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); @@ -450,12 +470,10 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { // Test multipart/byteranges based boundary parsing. WebURLResponse response1; response1.initialize(); - response1.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response1.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); - response1.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8("multipart/byteranges; boundary=--bound--")); + response1.setMIMEType("multipart/x-mixed-replace"); + response1.setHTTPHeaderField("Content-Length", "200"); + response1.setHTTPHeaderField("Content-type", + "multipart/byteranges; boundary=--bound--"); std::string multipart_boundary; bool result = MultipartResponseDelegate::ReadMultipartBoundary( @@ -466,16 +484,12 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { WebURLResponse response2; response2.initialize(); - response2.setMIMEType(WebString::fromUTF8("image/png")); + response2.setMIMEType("image/png"); - response2.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("300")); - response2.setHTTPHeaderField( - WebString::fromUTF8("Last-Modified"), - WebString::fromUTF8("Mon, 04 Apr 2005 20:36:01 GMT")); - response2.setHTTPHeaderField( - WebString::fromUTF8("Date"), - WebString::fromUTF8("Thu, 11 Sep 2008 18:21:42 GMT")); + response2.setHTTPHeaderField("Content-Length", "300"); + response2.setHTTPHeaderField("Last-Modified", + "Mon, 04 Apr 2005 20:36:01 GMT"); + response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT"); multipart_boundary.clear(); result = MultipartResponseDelegate::ReadMultipartBoundary( @@ -484,19 +498,13 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { WebURLResponse response3; response3.initialize(); - response3.setMIMEType(WebString::fromUTF8("multipart/byteranges")); - - response3.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("300")); - response3.setHTTPHeaderField( - WebString::fromUTF8("Last-Modified"), - WebString::fromUTF8("Mon, 04 Apr 2005 20:36:01 GMT")); - response3.setHTTPHeaderField( - WebString::fromUTF8("Date"), - WebString::fromUTF8("Thu, 11 Sep 2008 18:21:42 GMT")); - response3.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8("multipart/byteranges")); + response3.setMIMEType("multipart/byteranges"); + + response3.setHTTPHeaderField("Content-Length", "300"); + response3.setHTTPHeaderField("Last-Modified", + "Mon, 04 Apr 2005 20:36:01 GMT"); + response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT"); + response3.setHTTPHeaderField("Content-type", "multipart/byteranges"); multipart_boundary.clear(); result = MultipartResponseDelegate::ReadMultipartBoundary( @@ -506,13 +514,10 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { WebURLResponse response4; response4.initialize(); - response4.setMIMEType(WebString::fromUTF8("multipart/byteranges")); - response4.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); - response4.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8( - "multipart/byteranges; boundary=--bound--; charSet=utf8")); + response4.setMIMEType("multipart/byteranges"); + response4.setHTTPHeaderField("Content-Length", "200"); + response4.setHTTPHeaderField("Content-type", + "multipart/byteranges; boundary=--bound--; charSet=utf8"); multipart_boundary.clear(); @@ -523,13 +528,10 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { WebURLResponse response5; response5.initialize(); - response5.setMIMEType(WebString::fromUTF8("multipart/byteranges")); - response5.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); - response5.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8( - "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8")); + response5.setMIMEType("multipart/byteranges"); + response5.setHTTPHeaderField("Content-Length", "200"); + response5.setHTTPHeaderField("Content-type", + "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8"); multipart_boundary.clear(); @@ -607,7 +609,7 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) { TEST(MultipartResponseTest, MultipartPayloadSet) { WebURLResponse response; response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); + response.setMIMEType("multipart/x-mixed-replace"); MockWebURLLoaderClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); diff --git a/webkit/glue/password_form.cc b/webkit/glue/password_form.cc new file mode 100644 index 0000000..97777dc --- /dev/null +++ b/webkit/glue/password_form.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/password_form.h" + +namespace webkit_glue { + +PasswordForm::PasswordForm() + : scheme(SCHEME_HTML), + ssl_valid(false), + preferred(false), + blacklisted_by_user(false) { +} + +PasswordForm::PasswordForm(const WebKit::WebPasswordFormData& web_password_form) + : scheme(SCHEME_HTML), + signon_realm(web_password_form.signonRealm.utf8()), + origin(web_password_form.origin), + action(web_password_form.action), + submit_element(web_password_form.submitElement), + username_element(web_password_form.userNameElement), + username_value(web_password_form.userNameValue), + password_element(web_password_form.passwordElement), + password_value(web_password_form.passwordValue), + old_password_element(web_password_form.oldPasswordElement), + old_password_value(web_password_form.oldPasswordValue), + ssl_valid(false), + preferred(false), + blacklisted_by_user(false) { +} + +PasswordForm::~PasswordForm() { +} + +} // namespace webkit_glue diff --git a/webkit/glue/password_form.h b/webkit/glue/password_form.h index 57a54c1..c2967a4 100644 --- a/webkit/glue/password_form.h +++ b/webkit/glue/password_form.h @@ -32,9 +32,9 @@ namespace webkit_glue { // about a particular "saved password entry" to our PasswordForm // representation. // -// The field descriptions in the struct specification below are -// intended to describe which fields are not strictly required when adding a saved -// password entry to the database and how they can affect the matching process. +// The field descriptions in the struct specification below are intended to +// describe which fields are not strictly required when adding a saved password +// entry to the database and how they can affect the matching process. struct PasswordForm { // Enum to differentiate between HTML form based authentication, and dialogs @@ -135,29 +135,9 @@ struct PasswordForm { // When parsing an HTML form, this is not used. bool blacklisted_by_user; - PasswordForm() - : scheme(SCHEME_HTML), - ssl_valid(false), - preferred(false), - blacklisted_by_user(false) { - } - - PasswordForm(const WebKit::WebPasswordFormData& web_password_form) - : scheme(SCHEME_HTML), - signon_realm(web_password_form.signonRealm.utf8()), - origin(web_password_form.origin), - action(web_password_form.action), - submit_element(web_password_form.submitElement), - username_element(web_password_form.userNameElement), - username_value(web_password_form.userNameValue), - password_element(web_password_form.passwordElement), - password_value(web_password_form.passwordValue), - old_password_element(web_password_form.oldPasswordElement), - old_password_value(web_password_form.oldPasswordValue), - ssl_valid(false), - preferred(false), - blacklisted_by_user(false) { - } + PasswordForm(); + PasswordForm(const WebKit::WebPasswordFormData& web_password_form); + ~PasswordForm(); }; // Map username to PasswordForm* for convenience. See password_form_manager.h. diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.cc b/webkit/glue/plugins/gtk_plugin_container_manager.cc index 9d9ee4b..f26b44c 100644 --- a/webkit/glue/plugins/gtk_plugin_container_manager.cc +++ b/webkit/glue/plugins/gtk_plugin_container_manager.cc @@ -65,17 +65,21 @@ void GtkPluginContainerManager::MovePluginContainer( return; } - DCHECK(GTK_WIDGET_REALIZED(widget)); gtk_widget_show(widget); if (!move.rects_valid) return; - GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle(); - GdkRegion* clip_region = gdk_region_rectangle(&clip_rect); - gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects); - gdk_window_shape_combine_region(widget->window, clip_region, 0, 0); - gdk_region_destroy(clip_region); + // TODO(piman): if the widget hasn't been realized (e.g. the tab has been + // torn off and the parent gtk widget has been detached from the hierarchy), + // we lose the cutout information. + if (GTK_WIDGET_REALIZED(widget)) { + GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle(); + GdkRegion* clip_region = gdk_region_rectangle(&clip_rect); + gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects); + gdk_window_shape_combine_region(widget->window, clip_region, 0, 0); + gdk_region_destroy(clip_region); + } // Update the window position. Resizing is handled by WebPluginDelegate. // TODO(deanm): Verify that we only need to move and not resize. diff --git a/webkit/glue/plugins/pepper_buffer.cc b/webkit/glue/plugins/pepper_buffer.cc index 1c0bdd8..c3acef8 100644 --- a/webkit/glue/plugins/pepper_buffer.cc +++ b/webkit/glue/plugins/pepper_buffer.cc @@ -8,10 +8,10 @@ #include "base/logging.h" #include "base/scoped_ptr.h" +#include "third_party/ppapi/c/dev/ppb_buffer_dev.h" #include "third_party/ppapi/c/pp_instance.h" #include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/pp_resource.h" -#include "third_party/ppapi/c/ppb_buffer.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -22,11 +22,11 @@ namespace { PP_Resource Create(PP_Module module_id, int32_t size) { PluginModule* module = PluginModule::FromPPModule(module_id); if (!module) - return NULL; + return 0; scoped_refptr<Buffer> buffer(new Buffer(module)); if (!buffer->Init(size)) - return NULL; + return 0; return buffer->GetReference(); } @@ -57,7 +57,7 @@ void Unmap(PP_Resource resource) { return buffer->Unmap(); } -const PPB_Buffer ppb_buffer = { +const PPB_Buffer_Dev ppb_buffer = { &Create, &IsBuffer, &Describe, @@ -76,7 +76,7 @@ Buffer::~Buffer() { } // static -const PPB_Buffer* Buffer::GetInterface() { +const PPB_Buffer_Dev* Buffer::GetInterface() { return &ppb_buffer; } diff --git a/webkit/glue/plugins/pepper_buffer.h b/webkit/glue/plugins/pepper_buffer.h index 5d750ec..2f20e55 100644 --- a/webkit/glue/plugins/pepper_buffer.h +++ b/webkit/glue/plugins/pepper_buffer.h @@ -7,9 +7,10 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/ppb_buffer.h" #include "webkit/glue/plugins/pepper_resource.h" +struct PPB_Buffer_Dev; + namespace pepper { class PluginInstance; @@ -28,7 +29,7 @@ class Buffer : public Resource { // Returns a pointer to the interface implementing PPB_Buffer that is // exposed to the plugin. - static const PPB_Buffer* GetInterface(); + static const PPB_Buffer_Dev* GetInterface(); // Resource overrides. Buffer* AsBuffer() { return this; } diff --git a/webkit/glue/plugins/pepper_device_context_2d.cc b/webkit/glue/plugins/pepper_device_context_2d.cc deleted file mode 100644 index 45ed9ee..0000000 --- a/webkit/glue/plugins/pepper_device_context_2d.cc +++ /dev/null @@ -1,553 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/plugins/pepper_device_context_2d.h" - -#include <iterator> - -#include "base/logging.h" -#include "base/message_loop.h" -#include "base/task.h" -#include "gfx/blit.h" -#include "gfx/point.h" -#include "gfx/rect.h" -#include "skia/ext/platform_canvas.h" -#include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/pp_module.h" -#include "third_party/ppapi/c/pp_rect.h" -#include "third_party/ppapi/c/pp_resource.h" -#include "third_party/ppapi/c/ppb_device_context_2d.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "webkit/glue/plugins/pepper_image_data.h" -#include "webkit/glue/plugins/pepper_plugin_instance.h" -#include "webkit/glue/plugins/pepper_plugin_module.h" - -#if defined(OS_MACOSX) -#include "base/mac_util.h" -#include "base/scoped_cftyperef.h" -#endif - -namespace pepper { - -namespace { - -// Converts a rect inside an image of the given dimensions. The rect may be -// NULL to indicate it should be the entire image. If the rect is outside of -// the image, this will do nothing and return false. -bool ValidateAndConvertRect(const PP_Rect* rect, - int image_width, int image_height, - gfx::Rect* dest) { - if (!rect) { - // Use the entire image area. - *dest = gfx::Rect(0, 0, image_width, image_height); - } else { - // Validate the passed-in area. - if (rect->point.x < 0 || rect->point.y < 0 || - rect->size.width <= 0 || rect->size.height <= 0) - return false; - - // Check the max bounds, being careful of overflow. - if (static_cast<int64>(rect->point.x) + - static_cast<int64>(rect->size.width) > - static_cast<int64>(image_width)) - return false; - if (static_cast<int64>(rect->point.y) + - static_cast<int64>(rect->size.height) > - static_cast<int64>(image_height)) - return false; - - *dest = gfx::Rect(rect->point.x, rect->point.y, - rect->size.width, rect->size.height); - } - return true; -} - -PP_Resource Create(PP_Module module_id, - const PP_Size* size, - bool is_always_opaque) { - PluginModule* module = PluginModule::FromPPModule(module_id); - if (!module) - return NULL; - - scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module)); - if (!context->Init(size->width, size->height, is_always_opaque)) - return NULL; - return context->GetReference(); -} - -bool IsDeviceContext2D(PP_Resource resource) { - return !!Resource::GetAs<DeviceContext2D>(resource); -} - -bool Describe(PP_Resource device_context, - PP_Size* size, - bool* is_always_opaque) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(device_context)); - if (!context) - return false; - return context->Describe(size, is_always_opaque); -} - -bool PaintImageData(PP_Resource device_context, - PP_Resource image, - const PP_Point* top_left, - const PP_Rect* src_rect) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(device_context)); - if (!context) - return false; - return context->PaintImageData(image, top_left, src_rect); -} - -bool Scroll(PP_Resource device_context, - const PP_Rect* clip_rect, - const PP_Point* amount) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(device_context)); - if (!context) - return false; - return context->Scroll(clip_rect, amount); -} - -bool ReplaceContents(PP_Resource device_context, PP_Resource image) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(device_context)); - if (!context) - return false; - return context->ReplaceContents(image); -} - -int32_t Flush(PP_Resource device_context, - PP_CompletionCallback callback) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(device_context)); - if (!context) - return PP_ERROR_BADRESOURCE; - return context->Flush(callback); -} - -const PPB_DeviceContext2D ppb_devicecontext2d = { - &Create, - &IsDeviceContext2D, - &Describe, - &PaintImageData, - &Scroll, - &ReplaceContents, - &Flush -}; - -} // namespace - -struct DeviceContext2D::QueuedOperation { - enum Type { - PAINT, - SCROLL, - REPLACE - }; - - QueuedOperation(Type t) - : type(t), - paint_x(0), - paint_y(0), - scroll_dx(0), - scroll_dy(0) { - } - - Type type; - - // Valid when type == PAINT. - scoped_refptr<ImageData> paint_image; - int paint_x, paint_y; - gfx::Rect paint_src_rect; - - // Valid when type == SCROLL. - gfx::Rect scroll_clip_rect; - int scroll_dx, scroll_dy; - - // Valid when type == REPLACE. - scoped_refptr<ImageData> replace_image; -}; - -DeviceContext2D::DeviceContext2D(PluginModule* module) - : Resource(module), - bound_instance_(NULL), - flushed_any_data_(false), - offscreen_flush_pending_(false) { -} - -DeviceContext2D::~DeviceContext2D() { -} - -// static -const PPB_DeviceContext2D* DeviceContext2D::GetInterface() { - return &ppb_devicecontext2d; -} - -bool DeviceContext2D::Init(int width, int height, bool is_always_opaque) { - // The underlying ImageData will validate the dimensions. - image_data_ = new ImageData(module()); - if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || - !image_data_->Map()) { - image_data_ = NULL; - return false; - } - - return true; -} - -bool DeviceContext2D::Describe(PP_Size* size, bool* is_always_opaque) { - size->width = image_data_->width(); - size->height = image_data_->height(); - *is_always_opaque = false; // TODO(brettw) implement this. - return true; -} - -bool DeviceContext2D::PaintImageData(PP_Resource image, - const PP_Point* top_left, - const PP_Rect* src_rect) { - if (!top_left) - return false; - - scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); - if (!image_resource) - return false; - - QueuedOperation operation(QueuedOperation::PAINT); - operation.paint_image = image_resource; - if (!ValidateAndConvertRect(src_rect, image_resource->width(), - image_resource->height(), - &operation.paint_src_rect)) - return false; - - // Validate the bitmap position using the previously-validated rect, there - // should be no painted area outside of the image. - int64 x64 = static_cast<int64>(top_left->x); - int64 y64 = static_cast<int64>(top_left->y); - if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || - x64 + static_cast<int64>(operation.paint_src_rect.right()) > - image_data_->width()) - return false; - if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || - y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > - image_data_->height()) - return false; - operation.paint_x = top_left->x; - operation.paint_y = top_left->y; - - queued_operations_.push_back(operation); - return true; -} - -bool DeviceContext2D::Scroll(const PP_Rect* clip_rect, - const PP_Point* amount) { - QueuedOperation operation(QueuedOperation::SCROLL); - if (!ValidateAndConvertRect(clip_rect, - image_data_->width(), - image_data_->height(), - &operation.scroll_clip_rect)) - return false; - - // If we're being asked to scroll by more than the clip rect size, just - // ignore this scroll command and say it worked. - int32 dx = amount->x; - int32 dy = amount->y; - if (dx <= -image_data_->width() || dx >= image_data_->width() || - dx <= -image_data_->height() || dy >= image_data_->height()) - return true; - - operation.scroll_dx = dx; - operation.scroll_dy = dy; - - queued_operations_.push_back(operation); - return false; -} - -bool DeviceContext2D::ReplaceContents(PP_Resource image) { - scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); - if (!image_resource) - return false; - if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) - return false; - - if (image_resource->width() != image_data_->width() || - image_resource->height() != image_data_->height()) - return false; - - QueuedOperation operation(QueuedOperation::REPLACE); - operation.replace_image = image_resource; - queued_operations_.push_back(operation); - - return true; -} - -int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) { - // Don't allow more than one pending flush at a time. - if (HasPendingFlush()) - return PP_ERROR_INPROGRESS; - - // TODO(brettw) check that the current thread is not the main one and - // implement blocking flushes in this case. - if (!callback.func) - return PP_ERROR_BADARGUMENT; - - gfx::Rect changed_rect; - for (size_t i = 0; i < queued_operations_.size(); i++) { - QueuedOperation& operation = queued_operations_[i]; - gfx::Rect op_rect; - switch (operation.type) { - case QueuedOperation::PAINT: - ExecutePaintImageData(operation.paint_image, - operation.paint_x, operation.paint_y, - operation.paint_src_rect, - &op_rect); - break; - case QueuedOperation::SCROLL: - ExecuteScroll(operation.scroll_clip_rect, - operation.scroll_dx, operation.scroll_dy, - &op_rect); - break; - case QueuedOperation::REPLACE: - ExecuteReplaceContents(operation.replace_image, &op_rect); - break; - } - changed_rect = changed_rect.Union(op_rect); - } - queued_operations_.clear(); - flushed_any_data_ = true; - - // We need the rect to be in terms of the current clip rect of the plugin - // since that's what will actually be painted. If we issue an invalidate - // for a clipped-out region, WebKit will do nothing and we won't get any - // ViewInitiatedPaint/ViewFlushedPaint calls, leaving our callback stranded. - gfx::Rect visible_changed_rect; - if (bound_instance_ && !changed_rect.IsEmpty()) - visible_changed_rect = bound_instance_->clip().Intersect(changed_rect); - - if (bound_instance_ && !visible_changed_rect.IsEmpty()) { - unpainted_flush_callback_.Set(callback); - bound_instance_->InvalidateRect(visible_changed_rect); - } else { - // There's nothing visible to invalidate so just schedule the callback to - // execute in the next round of the message loop. - ScheduleOffscreenCallback(FlushCallbackData(callback)); - } - return PP_ERROR_WOULDBLOCK; -} - -bool DeviceContext2D::ReadImageData(PP_Resource image, - const PP_Point* top_left) { - // Get and validate the image object to paint into. - scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); - if (!image_resource) - return false; - if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) - return false; // Must be in the right format. - - // Validate the bitmap position. - int x = top_left->x; - if (x < 0 || - static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > - image_data_->width()) - return false; - int y = top_left->y; - if (y < 0 || - static_cast<int64>(y) + static_cast<int64>(image_resource->height()) > - image_data_->height()) - return false; - - ImageDataAutoMapper auto_mapper(image_resource); - if (!auto_mapper.is_valid()) - return false; - skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); - - SkIRect src_irect = { x, y, - x + image_resource->width(), - y + image_resource->height() }; - SkRect dest_rect = { SkIntToScalar(0), - SkIntToScalar(0), - SkIntToScalar(image_resource->width()), - SkIntToScalar(image_resource->height()) }; - - // We want to replace the contents of the bitmap rather than blend. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); - dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), - &src_irect, dest_rect, &paint); - return true; -} - -bool DeviceContext2D::BindToInstance(PluginInstance* new_instance) { - if (bound_instance_ == new_instance) - return true; // Rebinding the same device, nothing to do. - if (bound_instance_ && new_instance) - return false; // Can't change a bound device. - - if (!new_instance) { - // When the device is detached, we'll not get any more paint callbacks so - // we need to clear the list, but we still want to issue any pending - // callbacks to the plugin. - if (!unpainted_flush_callback_.is_null()) { - ScheduleOffscreenCallback(unpainted_flush_callback_); - unpainted_flush_callback_.Clear(); - } - if (!painted_flush_callback_.is_null()) { - ScheduleOffscreenCallback(painted_flush_callback_); - painted_flush_callback_.Clear(); - } - } else if (flushed_any_data_) { - // Only schedule a paint if this backing store has had any data flushed to - // it. This is an optimization. A "normal" plugin will first allocated a - // backing store, bind it, and then execute their normal painting and - // update loop. If binding a device always invalidated, it would mean we - // would get one paint for the bind, and one for the first time the plugin - // actually painted something. By not bothering to schedule an invalidate - // when an empty device is initially bound, we can save an extra paint for - // many plugins during the critical page initialization phase. - new_instance->InvalidateRect(gfx::Rect()); - } - - bound_instance_ = new_instance; - return true; -} - -void DeviceContext2D::Paint(WebKit::WebCanvas* canvas, - const gfx::Rect& plugin_rect, - const gfx::Rect& paint_rect) { - // We're guaranteed to have a mapped canvas since we mapped it in Init(). - const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); - -#if defined(OS_MACOSX) - SkAutoLockPixels lock(backing_bitmap); - - scoped_cftyperef<CGDataProviderRef> data_provider( - CGDataProviderCreateWithData( - NULL, backing_bitmap.getAddr32(0, 0), - backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); - scoped_cftyperef<CGImageRef> image( - CGImageCreate( - backing_bitmap.width(), backing_bitmap.height(), - 8, 32, backing_bitmap.rowBytes(), - mac_util::GetSystemColorSpace(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, - data_provider, NULL, false, kCGRenderingIntentDefault)); - - // Flip the transform - CGContextSaveGState(canvas); - float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas)); - CGContextTranslateCTM(canvas, 0, window_height); - CGContextScaleCTM(canvas, 1.0, -1.0); - - CGRect bounds; - bounds.origin.x = plugin_rect.origin().x(); - bounds.origin.y = window_height - plugin_rect.origin().y() - - backing_bitmap.height(); - bounds.size.width = backing_bitmap.width(); - bounds.size.height = backing_bitmap.height(); - - CGContextDrawImage(canvas, bounds, image); - CGContextRestoreGState(canvas); -#else - gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); - canvas->drawBitmap(backing_bitmap, - SkIntToScalar(plugin_rect.origin().x()), - SkIntToScalar(plugin_rect.origin().y())); -#endif -} - -void DeviceContext2D::ViewInitiatedPaint() { - // Move any "unpainted" callback to the painted state. See - // |unpainted_flush_callback_| in the header for more. - if (!unpainted_flush_callback_.is_null()) { - DCHECK(painted_flush_callback_.is_null()); - std::swap(painted_flush_callback_, unpainted_flush_callback_); - } -} - -void DeviceContext2D::ViewFlushedPaint() { - // Notify any "painted" callback. See |unpainted_flush_callback_| in the - // header for more. - if (!painted_flush_callback_.is_null()) { - // We must clear this variable before issuing the callback. It will be - // common for the plugin to issue another invalidate in response to a flush - // callback, and we don't want to think that a callback is already pending. - FlushCallbackData callback; - std::swap(callback, painted_flush_callback_); - callback.Execute(PP_OK); - } -} - -void DeviceContext2D::ExecutePaintImageData(ImageData* image, - int x, int y, - const gfx::Rect& src_rect, - gfx::Rect* invalidated_rect) { - // Ensure the source image is mapped to read from it. - ImageDataAutoMapper auto_mapper(image); - if (!auto_mapper.is_valid()) - return; - - // Portion within the source image to cut out. - SkIRect src_irect = { src_rect.x(), src_rect.y(), - src_rect.right(), src_rect.bottom() }; - - // Location within the backing store to copy to. - *invalidated_rect = src_rect; - invalidated_rect->Offset(x, y); - SkRect dest_rect = { SkIntToScalar(invalidated_rect->x()), - SkIntToScalar(invalidated_rect->y()), - SkIntToScalar(invalidated_rect->right()), - SkIntToScalar(invalidated_rect->bottom()) }; - - // We're guaranteed to have a mapped canvas since we mapped it in Init(). - skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); - - // We want to replace the contents of the bitmap rather than blend. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); - backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), - &src_irect, dest_rect, &paint); -} - -void DeviceContext2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, - gfx::Rect* invalidated_rect) { - gfx::ScrollCanvas(image_data_->mapped_canvas(), - clip, gfx::Point(dx, dy)); - *invalidated_rect = clip; -} - -void DeviceContext2D::ExecuteReplaceContents(ImageData* image, - gfx::Rect* invalidated_rect) { - image_data_->Swap(image); - *invalidated_rect = gfx::Rect(0, 0, - image_data_->width(), image_data_->height()); -} - -void DeviceContext2D::ScheduleOffscreenCallback( - const FlushCallbackData& callback) { - DCHECK(!HasPendingFlush()); - offscreen_flush_pending_ = true; - MessageLoop::current()->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &DeviceContext2D::ExecuteOffscreenCallback, - callback)); -} - -void DeviceContext2D::ExecuteOffscreenCallback(FlushCallbackData data) { - DCHECK(offscreen_flush_pending_); - - // We must clear this flag before issuing the callback. It will be - // common for the plugin to issue another invalidate in response to a flush - // callback, and we don't want to think that a callback is already pending. - offscreen_flush_pending_ = false; - data.Execute(PP_OK); -} - -bool DeviceContext2D::HasPendingFlush() const { - return !unpainted_flush_callback_.is_null() || - !painted_flush_callback_.is_null() || - offscreen_flush_pending_; -} - -} // namespace pepper diff --git a/webkit/glue/plugins/pepper_device_context_2d.h b/webkit/glue/plugins/pepper_device_context_2d.h deleted file mode 100644 index 603bd52..0000000 --- a/webkit/glue/plugins/pepper_device_context_2d.h +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_ -#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_ - -#include <vector> - -#include "base/basictypes.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/ppb_device_context_2d.h" -#include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h" -#include "webkit/glue/plugins/pepper_resource.h" - -typedef struct _ppb_DeviceContext2D PPB_DeviceContext2D; - -namespace gfx { -class Rect; -} - -namespace pepper { - -class ImageData; -class PluginInstance; -class PluginModule; - -class DeviceContext2D : public Resource { - public: - DeviceContext2D(PluginModule* module); - virtual ~DeviceContext2D(); - - // Returns a pointer to the interface implementing PPB_ImageData that is - // exposed to the plugin. - static const PPB_DeviceContext2D* GetInterface(); - - bool Init(int width, int height, bool is_always_opaque); - - // Resource override. - virtual DeviceContext2D* AsDeviceContext2D() { return this; } - - // PPB_DeviceContext2D functions. - bool Describe(PP_Size* size, bool* is_always_opaque); - bool PaintImageData(PP_Resource image, - const PP_Point* top_left, - const PP_Rect* src_rect); - bool Scroll(const PP_Rect* clip_rect, const PP_Point* amount); - bool ReplaceContents(PP_Resource image); - int32_t Flush(const PP_CompletionCallback& callback); - - bool ReadImageData(PP_Resource image, const PP_Point* top_left); - - // Assciates this device with the given plugin instance. You can pass NULL to - // clear the existing device. Returns true on success. In this case, a - // repaint of the page will also be scheduled. Failure means that the device - // is already bound to a different instance, and nothing will happen. - bool BindToInstance(PluginInstance* new_instance); - - // Paints the current backing store to the web page. - void Paint(WebKit::WebCanvas* canvas, - const gfx::Rect& plugin_rect, - const gfx::Rect& paint_rect); - - // Notifications that the view has rendered the page and that it has been - // flushed to the screen. These messages are used to send Flush callbacks to - // the plugin. See - void ViewInitiatedPaint(); - void ViewFlushedPaint(); - - ImageData* image_data() { return image_data_.get(); } - - private: - // Tracks a call to flush that requires a callback. - class FlushCallbackData { - public: - FlushCallbackData() { - Clear(); - } - - FlushCallbackData(const PP_CompletionCallback& callback) { - Set(callback); - } - - bool is_null() const { return !callback_.func; } - - void Set(const PP_CompletionCallback& callback) { - callback_ = callback; - } - - void Clear() { - callback_ = PP_MakeCompletionCallback(NULL, 0); - } - - void Execute(int32_t result) { - PP_RunCompletionCallback(&callback_, result); - } - - private: - PP_CompletionCallback callback_; - }; - - // Called internally to execute the different queued commands. The - // parameters to these functions will have already been validated. The last - // rect argument will be filled by each function with the area affected by - // the update that requires invalidation. If there were no pixels changed, - // this rect can be untouched. - void ExecutePaintImageData(ImageData* image, - int x, int y, - const gfx::Rect& src_rect, - gfx::Rect* invalidated_rect); - void ExecuteScroll(const gfx::Rect& clip, int dx, int dy, - gfx::Rect* invalidated_rect); - void ExecuteReplaceContents(ImageData* image, - gfx::Rect* invalidated_rect); - - // Schedules the offscreen callback to be fired at a future time. This - // will add the given item to the offscreen_flush_callbacks_ vector. - void ScheduleOffscreenCallback(const FlushCallbackData& callback); - - // Function scheduled to execute by ScheduleOffscreenCallback that actually - // issues the offscreen callbacks. - void ExecuteOffscreenCallback(FlushCallbackData data); - - // Returns true if there is any type of flush callback pending. - bool HasPendingFlush() const; - - scoped_refptr<ImageData> image_data_; - - // Non-owning pointer to the plugin instance this device context is currently - // bound to, if any. If the device context is currently unbound, this will - // be NULL. - PluginInstance* bound_instance_; - - // Keeps track of all drawing commands queued before a Flush call. - struct QueuedOperation; - typedef std::vector<QueuedOperation> OperationQueue; - OperationQueue queued_operations_; - - // Indicates whether any changes have been flushed to the backing store. - // This is initially false and is set to true at the first Flush() call. - bool flushed_any_data_; - - // The plugin can give us one "Flush" at a time. This flush will either be in - // the "unpainted" state (in which case unpainted_flush_callback_ will be - // non-NULL) or painted, in which case painted_flush_callback_ will be - // non-NULL). There can also be an offscreen callback which is handled - // separately (see offscreen_callback_pending_). Only one of these three - // things may be set at a time to enforce the "only one pending flush at a - // time" constraint. - // - // "Unpainted" ones are flush requests which have never been painted. These - // could have been done while the RenderView was already waiting for an ACK - // from a previous paint, so won't generate a new one yet. - // - // "Painted" ones are those flushes that have been painted by RenderView, but - // for which the ACK from the browser has not yet been received. - // - // When we get updates from a plugin with a callback, it is first added to - // the unpainted callbacks. When the renderer has initiated a paint, we'll - // move it to the painted callbacks list. When the renderer receives a flush, - // we'll execute the callback and remove it from the list. - FlushCallbackData unpainted_flush_callback_; - FlushCallbackData painted_flush_callback_; - - // When doing offscreen flushes, we issue a task that issues the callback - // later. This is set when one of those tasks is pending so that we can - // enforce the "only one pending flush at a time" constraint in the API. - bool offscreen_flush_pending_; - - DISALLOW_COPY_AND_ASSIGN(DeviceContext2D); -}; - -} // namespace pepper - -#endif // WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_ diff --git a/webkit/glue/plugins/pepper_directory_reader.cc b/webkit/glue/plugins/pepper_directory_reader.cc index 93f19ee..bcf2533 100644 --- a/webkit/glue/plugins/pepper_directory_reader.cc +++ b/webkit/glue/plugins/pepper_directory_reader.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "third_party/ppapi/c/pp_completion_callback.h" +#include "third_party/ppapi/c/dev/ppb_directory_reader_dev.h" #include "third_party/ppapi/c/pp_errors.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" @@ -29,7 +30,7 @@ bool IsDirectoryReader(PP_Resource resource) { } int32_t GetNextEntry(PP_Resource reader_id, - PP_DirectoryEntry* entry, + PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback) { scoped_refptr<DirectoryReader> reader( Resource::GetAs<DirectoryReader>(reader_id)); @@ -39,7 +40,7 @@ int32_t GetNextEntry(PP_Resource reader_id, return reader->GetNextEntry(entry, callback); } -const PPB_DirectoryReader ppb_directoryreader = { +const PPB_DirectoryReader_Dev ppb_directoryreader = { &Create, &IsDirectoryReader, &GetNextEntry @@ -55,11 +56,11 @@ DirectoryReader::DirectoryReader(FileRef* directory_ref) DirectoryReader::~DirectoryReader() { } -const PPB_DirectoryReader* DirectoryReader::GetInterface() { +const PPB_DirectoryReader_Dev* DirectoryReader::GetInterface() { return &ppb_directoryreader; } -int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry* entry, +int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback) { NOTIMPLEMENTED(); // TODO(darin): Implement me! return PP_ERROR_FAILED; diff --git a/webkit/glue/plugins/pepper_directory_reader.h b/webkit/glue/plugins/pepper_directory_reader.h index c477a3e..a56d546 100644 --- a/webkit/glue/plugins/pepper_directory_reader.h +++ b/webkit/glue/plugins/pepper_directory_reader.h @@ -5,9 +5,12 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_ -#include "third_party/ppapi/c/ppb_directory_reader.h" #include "webkit/glue/plugins/pepper_resource.h" +struct PP_CompletionCallback; +struct PP_DirectoryEntry_Dev; +struct PPB_DirectoryReader_Dev; + namespace pepper { class FileRef; @@ -19,13 +22,13 @@ class DirectoryReader : public Resource { // Returns a pointer to the interface implementing PPB_DirectoryReader that // is exposed to the plugin. - static const PPB_DirectoryReader* GetInterface(); + static const PPB_DirectoryReader_Dev* GetInterface(); // Resource overrides. DirectoryReader* AsDirectoryReader() { return this; } // PPB_DirectoryReader implementation. - int32_t GetNextEntry(PP_DirectoryEntry* entry, + int32_t GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback); private: diff --git a/webkit/glue/plugins/pepper_event_conversion.cc b/webkit/glue/plugins/pepper_event_conversion.cc index 033ac93..b88041e 100644 --- a/webkit/glue/plugins/pepper_event_conversion.cc +++ b/webkit/glue/plugins/pepper_event_conversion.cc @@ -4,9 +4,13 @@ #include "webkit/glue/plugins/pepper_event_conversion.h" +#include "base/i18n/char_iterator.h" #include "base/logging.h" #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/pp_event.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "base/utf_string_conversion_utils.h" +#include "third_party/ppapi/c/pp_input_event.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" using WebKit::WebInputEvent; @@ -15,153 +19,216 @@ using WebKit::WebMouseEvent; using WebKit::WebMouseWheelEvent; namespace { -// Anonymous namespace for functions converting WebInputEvent to PP_Event and -// back. -PP_Event_Type ConvertEventTypes(WebInputEvent::Type wetype) { + +PP_InputEvent_Type ConvertEventTypes(WebInputEvent::Type wetype) { switch (wetype) { case WebInputEvent::MouseDown: - return PP_EVENT_TYPE_MOUSEDOWN; + return PP_INPUTEVENT_TYPE_MOUSEDOWN; case WebInputEvent::MouseUp: - return PP_EVENT_TYPE_MOUSEUP; + return PP_INPUTEVENT_TYPE_MOUSEUP; case WebInputEvent::MouseMove: - return PP_EVENT_TYPE_MOUSEMOVE; + return PP_INPUTEVENT_TYPE_MOUSEMOVE; case WebInputEvent::MouseEnter: - return PP_EVENT_TYPE_MOUSEENTER; + return PP_INPUTEVENT_TYPE_MOUSEENTER; case WebInputEvent::MouseLeave: - return PP_EVENT_TYPE_MOUSELEAVE; + return PP_INPUTEVENT_TYPE_MOUSELEAVE; case WebInputEvent::MouseWheel: - return PP_EVENT_TYPE_MOUSEWHEEL; + return PP_INPUTEVENT_TYPE_MOUSEWHEEL; case WebInputEvent::RawKeyDown: - return PP_EVENT_TYPE_RAWKEYDOWN; + return PP_INPUTEVENT_TYPE_RAWKEYDOWN; case WebInputEvent::KeyDown: - return PP_EVENT_TYPE_KEYDOWN; + return PP_INPUTEVENT_TYPE_KEYDOWN; case WebInputEvent::KeyUp: - return PP_EVENT_TYPE_KEYUP; + return PP_INPUTEVENT_TYPE_KEYUP; case WebInputEvent::Char: - return PP_EVENT_TYPE_CHAR; + return PP_INPUTEVENT_TYPE_CHAR; case WebInputEvent::Undefined: default: - return PP_EVENT_TYPE_UNDEFINED; + return PP_INPUTEVENT_TYPE_UNDEFINED; } } -void BuildKeyEvent(const WebInputEvent* event, PP_Event* pp_event) { - const WebKeyboardEvent* key_event = - reinterpret_cast<const WebKeyboardEvent*>(event); - pp_event->u.key.modifier = key_event->modifiers; - pp_event->u.key.normalizedKeyCode = key_event->windowsKeyCode; +// Generates a PP_InputEvent with the fields common to all events, as well as +// the event type from the given web event. Event-specific fields will be zero +// initialized. +PP_InputEvent GetPPEventWithCommonFieldsAndType( + const WebInputEvent& web_event) { + PP_InputEvent result; + memset(&result, 0, sizeof(PP_InputEvent)); + result.type = ConvertEventTypes(web_event.type); + result.time_stamp_seconds = web_event.timeStampSeconds; + return result; +} + +void AppendKeyEvent(const WebInputEvent& event, + std::vector<PP_InputEvent>* pp_events) { + const WebKeyboardEvent& key_event = + reinterpret_cast<const WebKeyboardEvent&>(event); + PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event); + result.u.key.modifier = key_event.modifiers; + result.u.key.key_code = key_event.windowsKeyCode; + pp_events->push_back(result); } -void BuildCharEvent(const WebInputEvent* event, PP_Event* pp_event) { - const WebKeyboardEvent* key_event = - reinterpret_cast<const WebKeyboardEvent*>(event); - pp_event->u.character.modifier = key_event->modifiers; - // For consistency, check that the sizes of the texts agree. - DCHECK(sizeof(pp_event->u.character.text) == sizeof(key_event->text)); - DCHECK(sizeof(pp_event->u.character.unmodifiedText) == - sizeof(key_event->unmodifiedText)); - for (size_t i = 0; i < WebKeyboardEvent::textLengthCap; ++i) { - pp_event->u.character.text[i] = key_event->text[i]; - pp_event->u.character.unmodifiedText[i] = key_event->unmodifiedText[i]; +void AppendCharEvent(const WebInputEvent& event, + std::vector<PP_InputEvent>* pp_events) { + const WebKeyboardEvent& key_event = + reinterpret_cast<const WebKeyboardEvent&>(event); + + // This is a bit complex, the input event will normally just have one 16-bit + // character in it, but may be zero or more than one. The text array is + // just padded with 0 values for the unused ones, but is not necessarily + // null-terminated. + // + // Here we see how many UTF-16 characters we have. + size_t utf16_char_count = 0; + while (utf16_char_count < WebKeyboardEvent::textLengthCap && + key_event.text[utf16_char_count]) + utf16_char_count++; + + // Make a separate PP_InputEvent for each Unicode character in the input. + base::UTF16CharIterator iter(key_event.text, utf16_char_count); + while (!iter.end()) { + PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event); + result.u.character.modifier = key_event.modifiers; + + std::string utf8_char; + base::WriteUnicodeCharacter(iter.get(), &utf8_char); + base::strlcpy(result.u.character.text, utf8_char.c_str(), + sizeof(result.u.character.text)); + + pp_events->push_back(result); + iter.Advance(); } } -void BuildMouseEvent(const WebInputEvent* event, PP_Event* pp_event) { - const WebMouseEvent* mouse_event = - reinterpret_cast<const WebMouseEvent*>(event); - pp_event->u.mouse.modifier = mouse_event->modifiers; - pp_event->u.mouse.button = mouse_event->button; - pp_event->u.mouse.x = mouse_event->x; - pp_event->u.mouse.y = mouse_event->y; - pp_event->u.mouse.clickCount = mouse_event->clickCount; +void AppendMouseEvent(const WebInputEvent& event, + std::vector<PP_InputEvent>* pp_events) { + COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone) == + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE), + MouseNone); + COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft) == + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT), + MouseLeft); + COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight) == + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT), + MouseRight); + COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle) == + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE), + MouseMiddle); + + const WebMouseEvent& mouse_event = + reinterpret_cast<const WebMouseEvent&>(event); + PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event); + result.u.mouse.modifier = mouse_event.modifiers; + result.u.mouse.button = + static_cast<PP_InputEvent_MouseButton>(mouse_event.button); + result.u.mouse.x = static_cast<float>(mouse_event.x); + result.u.mouse.y = static_cast<float>(mouse_event.y); + result.u.mouse.click_count = mouse_event.clickCount; + pp_events->push_back(result); } -void BuildMouseWheelEvent(const WebInputEvent* event, PP_Event* pp_event) { - const WebMouseWheelEvent* mouse_wheel_event = - reinterpret_cast<const WebMouseWheelEvent*>(event); - pp_event->u.wheel.modifier = mouse_wheel_event->modifiers; - pp_event->u.wheel.deltaX = mouse_wheel_event->deltaX; - pp_event->u.wheel.deltaY = mouse_wheel_event->deltaY; - pp_event->u.wheel.wheelTicksX = mouse_wheel_event->wheelTicksX; - pp_event->u.wheel.wheelTicksY = mouse_wheel_event->wheelTicksY; - pp_event->u.wheel.scrollByPage = mouse_wheel_event->scrollByPage; +void AppendMouseWheelEvent(const WebInputEvent& event, + std::vector<PP_InputEvent>* pp_events) { + const WebMouseWheelEvent& mouse_wheel_event = + reinterpret_cast<const WebMouseWheelEvent&>(event); + PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event); + result.u.wheel.modifier = mouse_wheel_event.modifiers; + result.u.wheel.delta_x = mouse_wheel_event.deltaX; + result.u.wheel.delta_y = mouse_wheel_event.deltaY; + result.u.wheel.wheel_ticks_x = mouse_wheel_event.wheelTicksX; + result.u.wheel.wheel_ticks_y = mouse_wheel_event.wheelTicksY; + result.u.wheel.scroll_by_page = !!mouse_wheel_event.scrollByPage; + pp_events->push_back(result); } -WebKeyboardEvent* BuildKeyEvent(const PP_Event& event) { +WebKeyboardEvent* BuildKeyEvent(const PP_InputEvent& event) { WebKeyboardEvent* key_event = new WebKeyboardEvent(); switch (event.type) { - case PP_EVENT_TYPE_RAWKEYDOWN: + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: key_event->type = WebInputEvent::RawKeyDown; break; - case PP_EVENT_TYPE_KEYDOWN: + case PP_INPUTEVENT_TYPE_KEYDOWN: key_event->type = WebInputEvent::KeyDown; break; - case PP_EVENT_TYPE_KEYUP: + case PP_INPUTEVENT_TYPE_KEYUP: key_event->type = WebInputEvent::KeyUp; break; + default: + NOTREACHED(); } key_event->timeStampSeconds = event.time_stamp_seconds; key_event->modifiers = event.u.key.modifier; - key_event->windowsKeyCode = event.u.key.normalizedKeyCode; + key_event->windowsKeyCode = event.u.key.key_code; return key_event; } -WebKeyboardEvent* BuildCharEvent(const PP_Event& event) { +WebKeyboardEvent* BuildCharEvent(const PP_InputEvent& event) { WebKeyboardEvent* key_event = new WebKeyboardEvent(); key_event->type = WebInputEvent::Char; key_event->timeStampSeconds = event.time_stamp_seconds; key_event->modifiers = event.u.character.modifier; - // For consistency, check that the sizes of the texts agree. - DCHECK(sizeof(event.u.character.text) == sizeof(key_event->text)); - DCHECK(sizeof(event.u.character.unmodifiedText) == - sizeof(key_event->unmodifiedText)); - for (size_t i = 0; i < WebKeyboardEvent::textLengthCap; ++i) { - key_event->text[i] = event.u.character.text[i]; - key_event->unmodifiedText[i] = event.u.character.unmodifiedText[i]; - } + + // Make sure to not read beyond the buffer in case some bad code doesn't + // NULL-terminate it (this is called from plugins). + size_t text_length_cap = WebKeyboardEvent::textLengthCap; + size_t text_len = 0; + while (text_len < text_length_cap && event.u.character.text[text_len]) + text_len++; + string16 text16 = UTF8ToUTF16(std::string(event.u.character.text, text_len)); + + memset(key_event->text, 0, text_length_cap); + memset(key_event->unmodifiedText, 0, text_length_cap); + for (size_t i = 0; + i < std::min(text_length_cap, text16.size()); + ++i) + key_event->text[i] = text16[i]; return key_event; } -WebMouseEvent* BuildMouseEvent(const PP_Event& event) { +WebMouseEvent* BuildMouseEvent(const PP_InputEvent& event) { WebMouseEvent* mouse_event = new WebMouseEvent(); switch (event.type) { - case PP_EVENT_TYPE_MOUSEDOWN: + case PP_INPUTEVENT_TYPE_MOUSEDOWN: mouse_event->type = WebInputEvent::MouseDown; break; - case PP_EVENT_TYPE_MOUSEUP: + case PP_INPUTEVENT_TYPE_MOUSEUP: mouse_event->type = WebInputEvent::MouseUp; break; - case PP_EVENT_TYPE_MOUSEMOVE: + case PP_INPUTEVENT_TYPE_MOUSEMOVE: mouse_event->type = WebInputEvent::MouseMove; break; - case PP_EVENT_TYPE_MOUSEENTER: + case PP_INPUTEVENT_TYPE_MOUSEENTER: mouse_event->type = WebInputEvent::MouseEnter; break; - case PP_EVENT_TYPE_MOUSELEAVE: + case PP_INPUTEVENT_TYPE_MOUSELEAVE: mouse_event->type = WebInputEvent::MouseLeave; break; + default: + NOTREACHED(); } mouse_event->timeStampSeconds = event.time_stamp_seconds; mouse_event->modifiers = event.u.mouse.modifier; mouse_event->button = static_cast<WebMouseEvent::Button>(event.u.mouse.button); - mouse_event->x = event.u.mouse.x; - mouse_event->y = event.u.mouse.y; - mouse_event->clickCount = event.u.mouse.clickCount; + mouse_event->x = static_cast<int>(event.u.mouse.x); + mouse_event->y = static_cast<int>(event.u.mouse.y); + mouse_event->clickCount = event.u.mouse.click_count; return mouse_event; } -WebMouseWheelEvent* BuildMouseWheelEvent(const PP_Event& event) { +WebMouseWheelEvent* BuildMouseWheelEvent(const PP_InputEvent& event) { WebMouseWheelEvent* mouse_wheel_event = new WebMouseWheelEvent(); mouse_wheel_event->type = WebInputEvent::MouseWheel; mouse_wheel_event->timeStampSeconds = event.time_stamp_seconds; mouse_wheel_event->modifiers = event.u.wheel.modifier; - mouse_wheel_event->deltaX = event.u.wheel.deltaX; - mouse_wheel_event->deltaY = event.u.wheel.deltaY; - mouse_wheel_event->wheelTicksX = event.u.wheel.wheelTicksX; - mouse_wheel_event->wheelTicksY = event.u.wheel.wheelTicksY; - mouse_wheel_event->scrollByPage = event.u.wheel.scrollByPage; + mouse_wheel_event->deltaX = event.u.wheel.delta_x; + mouse_wheel_event->deltaY = event.u.wheel.delta_y; + mouse_wheel_event->wheelTicksX = event.u.wheel.wheel_ticks_x; + mouse_wheel_event->wheelTicksY = event.u.wheel.wheel_ticks_y; + mouse_wheel_event->scrollByPage = event.u.wheel.scroll_by_page; return mouse_wheel_event; } @@ -169,64 +236,58 @@ WebMouseWheelEvent* BuildMouseWheelEvent(const PP_Event& event) { namespace pepper { -PP_Event* CreatePP_Event(const WebInputEvent& event) { - scoped_ptr<PP_Event> pp_event(new PP_Event); +void CreatePPEvent(const WebInputEvent& event, + std::vector<PP_InputEvent>* pp_events) { + pp_events->clear(); - pp_event->type = ConvertEventTypes(event.type); - pp_event->size = sizeof(pp_event); - pp_event->time_stamp_seconds = event.timeStampSeconds; - switch (pp_event->type) { - case PP_EVENT_TYPE_UNDEFINED: - return NULL; - case PP_EVENT_TYPE_MOUSEDOWN: - case PP_EVENT_TYPE_MOUSEUP: - case PP_EVENT_TYPE_MOUSEMOVE: - case PP_EVENT_TYPE_MOUSEENTER: - case PP_EVENT_TYPE_MOUSELEAVE: - BuildMouseEvent(&event, pp_event.get()); + switch (event.type) { + case WebInputEvent::MouseDown: + case WebInputEvent::MouseUp: + case WebInputEvent::MouseMove: + case WebInputEvent::MouseEnter: + case WebInputEvent::MouseLeave: + AppendMouseEvent(event, pp_events); break; - case PP_EVENT_TYPE_MOUSEWHEEL: - BuildMouseWheelEvent(&event, pp_event.get()); + case WebInputEvent::MouseWheel: + AppendMouseWheelEvent(event, pp_events); break; - case PP_EVENT_TYPE_RAWKEYDOWN: - case PP_EVENT_TYPE_KEYDOWN: - case PP_EVENT_TYPE_KEYUP: - BuildKeyEvent(&event, pp_event.get()); + case WebInputEvent::RawKeyDown: + case WebInputEvent::KeyDown: + case WebInputEvent::KeyUp: + AppendKeyEvent(event, pp_events); break; - case PP_EVENT_TYPE_CHAR: - BuildCharEvent(&event, pp_event.get()); + case WebInputEvent::Char: + AppendCharEvent(event, pp_events); + break; + case WebInputEvent::Undefined: + default: break; } - - return pp_event.release(); } -WebInputEvent* CreateWebInputEvent(const PP_Event& event) { +WebInputEvent* CreateWebInputEvent(const PP_InputEvent& event) { scoped_ptr<WebInputEvent> web_input_event; switch (event.type) { - case PP_EVENT_TYPE_UNDEFINED: + case PP_INPUTEVENT_TYPE_UNDEFINED: return NULL; - case PP_EVENT_TYPE_MOUSEDOWN: - case PP_EVENT_TYPE_MOUSEUP: - case PP_EVENT_TYPE_MOUSEMOVE: - case PP_EVENT_TYPE_MOUSEENTER: - case PP_EVENT_TYPE_MOUSELEAVE: + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + case PP_INPUTEVENT_TYPE_MOUSEUP: + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + case PP_INPUTEVENT_TYPE_MOUSEENTER: + case PP_INPUTEVENT_TYPE_MOUSELEAVE: web_input_event.reset(BuildMouseEvent(event)); break; - case PP_EVENT_TYPE_MOUSEWHEEL: + case PP_INPUTEVENT_TYPE_MOUSEWHEEL: web_input_event.reset(BuildMouseWheelEvent(event)); break; - case PP_EVENT_TYPE_RAWKEYDOWN: - case PP_EVENT_TYPE_KEYDOWN: - case PP_EVENT_TYPE_KEYUP: + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + case PP_INPUTEVENT_TYPE_KEYDOWN: + case PP_INPUTEVENT_TYPE_KEYUP: web_input_event.reset(BuildKeyEvent(event)); break; - case PP_EVENT_TYPE_CHAR: + case PP_INPUTEVENT_TYPE_CHAR: web_input_event.reset(BuildCharEvent(event)); break; - case PP_EVENT_TYPE_FOCUS: - // NOTIMPLEMENTED(); - return NULL; } return web_input_event.release(); diff --git a/webkit/glue/plugins/pepper_event_conversion.h b/webkit/glue/plugins/pepper_event_conversion.h index 2d699cd..9eab3e4 100644 --- a/webkit/glue/plugins/pepper_event_conversion.h +++ b/webkit/glue/plugins/pepper_event_conversion.h @@ -5,7 +5,9 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_EVENT_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_EVENT_H_ -typedef struct _pp_Event PP_Event; +#include <vector> + +struct PP_InputEvent; namespace WebKit { class WebInputEvent; @@ -13,13 +15,15 @@ class WebInputEvent; namespace pepper { -// Creates a PP_Event from the given WebInputEvent. If it fails, returns NULL. -// The caller owns the created object on success. -PP_Event* CreatePP_Event(const WebKit::WebInputEvent& event); +// Converts the given WebKit event to one or possibly multiple PP_InputEvents. +// The generated events will be filled into the given vector. On failure, no +// events will ge generated and the vector will be empty. +void CreatePPEvent(const WebKit::WebInputEvent& event, + std::vector<PP_InputEvent>* pp_events); -// Creates a WebInputEvent from the given PP_Event. If it fails, returns NULL. -// The caller owns the created object on success. -WebKit::WebInputEvent* CreateWebInputEvent(const PP_Event& event); +// Creates a WebInputEvent from the given PP_InputEvent. If it fails, returns +// NULL. The caller owns the created object on success. +WebKit::WebInputEvent* CreateWebInputEvent(const PP_InputEvent& event); } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_chooser.cc b/webkit/glue/plugins/pepper_file_chooser.cc index 5e45600..138efd7 100644 --- a/webkit/glue/plugins/pepper_file_chooser.cc +++ b/webkit/glue/plugins/pepper_file_chooser.cc @@ -4,19 +4,35 @@ #include "webkit/glue/plugins/pepper_file_chooser.h" +#include <string> +#include <vector> + #include "base/logging.h" #include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_errors.h" +#include "third_party/WebKit/WebKit/chromium/public/WebCString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "webkit/glue/plugins/pepper_file_ref.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" +#include "webkit/glue/webkit_glue.h" + +using WebKit::WebCString; +using WebKit::WebFileChooserCompletion; +using WebKit::WebFileChooserParams; +using WebKit::WebString; +using WebKit::WebVector; namespace pepper { namespace { PP_Resource Create(PP_Instance instance_id, - const PP_FileChooserOptions* options) { + const PP_FileChooserOptions_Dev* options) { PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); if (!instance) return 0; @@ -51,38 +67,89 @@ PP_Resource GetNextChosenFile(PP_Resource chooser_id) { return file_ref->GetReference(); } -const PPB_FileChooser ppb_filechooser = { +const PPB_FileChooser_Dev ppb_filechooser = { &Create, &IsFileChooser, &Show, &GetNextChosenFile }; +class FileChooserCompletionImpl : public WebFileChooserCompletion { + public: + FileChooserCompletionImpl(pepper::FileChooser* file_chooser) + : file_chooser_(file_chooser) { + DCHECK(file_chooser_); + } + + virtual ~FileChooserCompletionImpl() {} + + virtual void didChooseFile(const WebVector<WebString>& file_names) { + std::vector<std::string> files; + for (size_t i = 0; i < file_names.size(); i++) + files.push_back(file_names[i].utf8().data()); + + file_chooser_->StoreChosenFiles(files); + } + + private: + FileChooser* file_chooser_; +}; + } // namespace FileChooser::FileChooser(PluginInstance* instance, - const PP_FileChooserOptions* options) + const PP_FileChooserOptions_Dev* options) : Resource(instance->module()), + delegate_(instance->delegate()), mode_(options->mode), - accept_mime_types_(options->accept_mime_types) { + accept_mime_types_(options->accept_mime_types), + completion_callback_() { } FileChooser::~FileChooser() { } // static -const PPB_FileChooser* FileChooser::GetInterface() { +const PPB_FileChooser_Dev* FileChooser::GetInterface() { return &ppb_filechooser; } +void FileChooser::StoreChosenFiles(const std::vector<std::string>& files) { + next_chosen_file_index_ = 0; + std::vector<std::string>::const_iterator end_it = files.end(); + for (std::vector<std::string>::const_iterator it = files.begin(); + it != end_it; it++) + chosen_files_.push_back( + new FileRef(module(), PP_FILESYSTEMTYPE_LOCALPERSISTENT, *it, "")); + + if (!completion_callback_.func) + return; + + PP_CompletionCallback callback = {0}; + std::swap(callback, completion_callback_); + PP_RunCompletionCallback(&callback, 0); +} + int32_t FileChooser::Show(PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + DCHECK((mode_ == PP_FILECHOOSERMODE_OPEN) || + (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE)); + DCHECK(!completion_callback_.func); + completion_callback_ = callback; + + WebFileChooserParams params; + params.multiSelect = (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE); + params.acceptTypes = WebString::fromUTF8(accept_mime_types_); + params.directory = false; + + return delegate_->RunFileChooser( + params, new FileChooserCompletionImpl(this)); } scoped_refptr<FileRef> FileChooser::GetNextChosenFile() { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return NULL; + if (next_chosen_file_index_ >= chosen_files_.size()) + return NULL; + + return chosen_files_[next_chosen_file_index_++]; } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_chooser.h b/webkit/glue/plugins/pepper_file_chooser.h index 8474188..eafdd0e 100644 --- a/webkit/glue/plugins/pepper_file_chooser.h +++ b/webkit/glue/plugins/pepper_file_chooser.h @@ -6,33 +6,45 @@ #define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_CHOOSER_H_ #include <string> +#include <vector> -#include "third_party/ppapi/c/ppb_file_chooser.h" +#include "base/scoped_ptr.h" +#include "third_party/ppapi/c/dev/ppb_file_chooser_dev.h" +#include "third_party/ppapi/c/pp_completion_callback.h" #include "webkit/glue/plugins/pepper_resource.h" namespace pepper { +class PluginDelegate; class PluginInstance; class FileChooser : public Resource { public: - FileChooser(PluginInstance* instance, const PP_FileChooserOptions* options); + FileChooser(PluginInstance* instance, + const PP_FileChooserOptions_Dev* options); virtual ~FileChooser(); // Returns a pointer to the interface implementing PPB_FileChooser that is // exposed to the plugin. - static const PPB_FileChooser* GetInterface(); + static const PPB_FileChooser_Dev* GetInterface(); // Resource overrides. FileChooser* AsFileChooser() { return this; } + // Stores the list of selected files. + void StoreChosenFiles(const std::vector<std::string>& files); + // PPB_FileChooser implementation. int32_t Show(PP_CompletionCallback callback); scoped_refptr<FileRef> GetNextChosenFile(); private: - PP_FileChooserMode mode_; + PluginDelegate* delegate_; + PP_FileChooserMode_Dev mode_; std::string accept_mime_types_; + PP_CompletionCallback completion_callback_; + std::vector< scoped_refptr<FileRef> > chosen_files_; + size_t next_chosen_file_index_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_io.cc b/webkit/glue/plugins/pepper_file_io.cc index 46f7276..9090f88 100644 --- a/webkit/glue/plugins/pepper_file_io.cc +++ b/webkit/glue/plugins/pepper_file_io.cc @@ -4,12 +4,19 @@ #include "webkit/glue/plugins/pepper_file_io.h" +#include "base/callback.h" +#include "base/file_util.h" +#include "base/file_util_proxy.h" +#include "base/message_loop_proxy.h" +#include "base/platform_file.h" #include "base/logging.h" +#include "base/time.h" +#include "third_party/ppapi/c/dev/ppb_file_io_dev.h" +#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h" #include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/ppb_file_io.h" -#include "third_party/ppapi/c/ppb_file_io_trusted.h" #include "webkit/glue/plugins/pepper_file_ref.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" @@ -46,12 +53,11 @@ int32_t Open(PP_Resource file_io_id, } int32_t Query(PP_Resource file_io_id, - PP_FileInfo* info, + PP_FileInfo_Dev* info, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->Query(info, callback); } @@ -62,7 +68,6 @@ int32_t Touch(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->Touch(last_access_time, last_modified_time, callback); } @@ -74,7 +79,6 @@ int32_t Read(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->Read(offset, buffer, bytes_to_read, callback); } @@ -86,7 +90,6 @@ int32_t Write(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->Write(offset, buffer, bytes_to_write, callback); } @@ -96,7 +99,6 @@ int32_t SetLength(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->SetLength(length, callback); } @@ -105,7 +107,6 @@ int32_t Flush(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->Flush(callback); } @@ -113,11 +114,10 @@ void Close(PP_Resource file_io_id) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return; - file_io->Close(); } -const PPB_FileIO ppb_fileio = { +const PPB_FileIO_Dev ppb_fileio = { &Create, &IsFileIO, &Open, @@ -134,7 +134,6 @@ int32_t GetOSFileDescriptor(PP_Resource file_io_id) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->GetOSFileDescriptor(); } @@ -145,7 +144,6 @@ int32_t WillWrite(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->WillWrite(offset, bytes_to_write, callback); } @@ -155,101 +153,281 @@ int32_t WillSetLength(PP_Resource file_io_id, scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; - return file_io->WillSetLength(length, callback); } -const PPB_FileIOTrusted ppb_fileiotrusted = { +const PPB_FileIOTrusted_Dev ppb_fileiotrusted = { &GetOSFileDescriptor, &WillWrite, &WillSetLength }; +int PlatformFileErrorToPepperError(base::PlatformFileError error_code) { + switch (error_code) { + case base::PLATFORM_FILE_OK: + return PP_OK; + case base::PLATFORM_FILE_ERROR_EXISTS: + return PP_ERROR_FILEEXISTS; + case base::PLATFORM_FILE_ERROR_NOT_FOUND: + return PP_ERROR_FILENOTFOUND; + case base::PLATFORM_FILE_ERROR_ACCESS_DENIED: + return PP_ERROR_NOACCESS; + case base::PLATFORM_FILE_ERROR_NO_MEMORY: + return PP_ERROR_NOMEMORY; + case base::PLATFORM_FILE_ERROR_NO_SPACE: + return PP_ERROR_NOSPACE; + case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY: + NOTREACHED(); + return PP_ERROR_FAILED; + default: + return PP_ERROR_FAILED; + } +} + } // namespace -FileIO::FileIO(PluginModule* module) : Resource(module) { +FileIO::FileIO(PluginModule* module) + : Resource(module), + delegate_(module->GetSomeInstance()->delegate()), + ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)), + file_(base::kInvalidPlatformFileValue), + callback_(), + info_(NULL) { } FileIO::~FileIO() { + Close(); } // static -const PPB_FileIO* FileIO::GetInterface() { +const PPB_FileIO_Dev* FileIO::GetInterface() { return &ppb_fileio; } // static -const PPB_FileIOTrusted* FileIO::GetTrustedInterface() { +const PPB_FileIOTrusted_Dev* FileIO::GetTrustedInterface() { return &ppb_fileiotrusted; } int32_t FileIO::Open(FileRef* file_ref, int32_t open_flags, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ != base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + int flags = 0; + if (open_flags & PP_FILEOPENFLAG_READ) + flags |= base::PLATFORM_FILE_READ; + if (open_flags & PP_FILEOPENFLAG_WRITE) { + flags |= base::PLATFORM_FILE_WRITE; + flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES; + } + if (open_flags & PP_FILEOPENFLAG_TRUNCATE) { + DCHECK(flags & PP_FILEOPENFLAG_WRITE); + flags |= base::PLATFORM_FILE_TRUNCATE; + } + + if (open_flags & PP_FILEOPENFLAG_CREATE) { + if (open_flags & PP_FILEOPENFLAG_EXCLUSIVE) + flags |= base::PLATFORM_FILE_CREATE; + else + flags |= base::PLATFORM_FILE_OPEN_ALWAYS; + } else + flags |= base::PLATFORM_FILE_OPEN; + + file_system_type_ = file_ref->file_system_type(); + if (!delegate_->AsyncOpenFile( + file_ref->system_path(), flags, + callback_factory_.NewCallback(&FileIO::AsyncOpenFileCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } -int32_t FileIO::Query(PP_FileInfo* info, +int32_t FileIO::Query(PP_FileInfo_Dev* info, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + DCHECK(!info_); + DCHECK(info); + info_ = info; + + if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( + delegate_->GetFileThreadMessageLoopProxy(), file_, + callback_factory_.NewCallback(&FileIO::QueryInfoCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } int32_t FileIO::Touch(PP_Time last_access_time, PP_Time last_modified_time, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + if (!base::FileUtilProxy::Touch( + delegate_->GetFileThreadMessageLoopProxy(), + file_, base::Time::FromDoubleT(last_access_time), + base::Time::FromDoubleT(last_modified_time), + callback_factory_.NewCallback(&FileIO::StatusCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } int32_t FileIO::Read(int64_t offset, char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + if (!base::FileUtilProxy::Read( + delegate_->GetFileThreadMessageLoopProxy(), + file_, offset, buffer, bytes_to_read, + callback_factory_.NewCallback(&FileIO::ReadWriteCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } int32_t FileIO::Write(int64_t offset, const char* buffer, int32_t bytes_to_write, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + if (!base::FileUtilProxy::Write( + delegate_->GetFileThreadMessageLoopProxy(), + file_, offset, buffer, bytes_to_write, + callback_factory_.NewCallback(&FileIO::ReadWriteCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } int32_t FileIO::SetLength(int64_t length, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + if (!base::FileUtilProxy::Truncate( + delegate_->GetFileThreadMessageLoopProxy(), + file_, length, + callback_factory_.NewCallback(&FileIO::StatusCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } int32_t FileIO::Flush(PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + + DCHECK(!callback_.func); + callback_ = callback; + + if (!base::FileUtilProxy::Flush( + delegate_->GetFileThreadMessageLoopProxy(), file_, + callback_factory_.NewCallback(&FileIO::StatusCallback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } void FileIO::Close() { - NOTIMPLEMENTED(); // TODO(darin): Implement me! + if (file_ != base::kInvalidPlatformFileValue) + base::FileUtilProxy::Close( + delegate_->GetFileThreadMessageLoopProxy(), file_, NULL); } int32_t FileIO::GetOSFileDescriptor() { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; +#if defined(OS_POSIX) + return file_; +#elif defined(OS_WIN) + return reinterpret_cast<uintptr_t>(file_); +#else +#error "Platform not supported." +#endif } int32_t FileIO::WillWrite(int64_t offset, int32_t bytes_to_write, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + // TODO(dumi): implement me + return PP_OK; } int32_t FileIO::WillSetLength(int64_t length, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + // TODO(dumi): implement me + return PP_OK; +} + +void FileIO::RunPendingCallback(int result) { + if (!callback_.func) + return; + + PP_CompletionCallback callback = {0}; + std::swap(callback, callback_); + PP_RunCompletionCallback(&callback, result); +} + +void FileIO::StatusCallback(base::PlatformFileError error_code) { + RunPendingCallback(PlatformFileErrorToPepperError(error_code)); +} + +void FileIO::AsyncOpenFileCallback(base::PlatformFileError error_code, + base::PlatformFile file) { + DCHECK(file_ == base::kInvalidPlatformFileValue); + file_ = file; + RunPendingCallback(PlatformFileErrorToPepperError(error_code)); +} + +void FileIO::QueryInfoCallback(base::PlatformFileError error_code, + const base::PlatformFileInfo& file_info) { + DCHECK(info_); + if (error_code == base::PLATFORM_FILE_OK) { + info_->size = file_info.size; + info_->creation_time = file_info.creation_time.ToDoubleT(); + info_->last_access_time = file_info.last_accessed.ToDoubleT(); + info_->last_modified_time = file_info.last_modified.ToDoubleT(); + info_->system_type = file_system_type_; + if (file_info.is_directory) + info_->type = PP_FILETYPE_DIRECTORY; + else + info_->type = PP_FILETYPE_REGULAR; + } + RunPendingCallback(PlatformFileErrorToPepperError(error_code)); +} + +void FileIO::ReadWriteCallback(base::PlatformFileError error_code, + int bytes_read_or_written) { + if (error_code != base::PLATFORM_FILE_OK) + RunPendingCallback(PlatformFileErrorToPepperError(error_code)); + else + RunPendingCallback(bytes_read_or_written); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_io.h b/webkit/glue/plugins/pepper_file_io.h index 4af6f2b..bda8ed6 100644 --- a/webkit/glue/plugins/pepper_file_io.h +++ b/webkit/glue/plugins/pepper_file_io.h @@ -5,13 +5,20 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_FILE_IO_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_IO_H_ +#include "base/file_path.h" +#include "base/platform_file.h" +#include "base/scoped_callback_factory.h" +#include "base/scoped_ptr.h" +#include "third_party/ppapi/c/dev/pp_file_info_dev.h" +#include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_time.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_resource.h" -typedef struct _pp_CompletionCallback PP_CompletionCallback; -typedef struct _pp_FileInfo PP_FileInfo; -typedef struct _ppb_FileIO PPB_FileIO; -typedef struct _ppb_FileIOTrusted PPB_FileIOTrusted; +struct PP_CompletionCallback; +struct PP_FileInfo_Dev; +struct PPB_FileIO_Dev; +struct PPB_FileIOTrusted_Dev; namespace pepper { @@ -24,11 +31,11 @@ class FileIO : public Resource { // Returns a pointer to the interface implementing PPB_FileIO that is exposed // to the plugin. - static const PPB_FileIO* GetInterface(); + static const PPB_FileIO_Dev* GetInterface(); // Returns a pointer to the interface implementing PPB_FileIOTrusted that is // exposed to the plugin. - static const PPB_FileIOTrusted* GetTrustedInterface(); + static const PPB_FileIOTrusted_Dev* GetTrustedInterface(); // Resource overrides. FileIO* AsFileIO() { return this; } @@ -37,7 +44,7 @@ class FileIO : public Resource { int32_t Open(FileRef* file_ref, int32_t open_flags, PP_CompletionCallback callback); - int32_t Query(PP_FileInfo* info, + int32_t Query(PP_FileInfo_Dev* info, PP_CompletionCallback callback); int32_t Touch(PP_Time last_access_time, PP_Time last_modified_time, @@ -62,6 +69,25 @@ class FileIO : public Resource { PP_CompletionCallback callback); int32_t WillSetLength(int64_t length, PP_CompletionCallback callback); + + void RunPendingCallback(int result); + void StatusCallback(base::PlatformFileError error_code); + void AsyncOpenFileCallback(base::PlatformFileError error_code, + base::PlatformFile file); + void QueryInfoCallback(base::PlatformFileError error_code, + const base::PlatformFileInfo& file_info); + void ReadWriteCallback(base::PlatformFileError error_code, + int bytes_read_or_written); + + private: + PluginDelegate* delegate_; + base::ScopedCallbackFactory<FileIO> callback_factory_; + + base::PlatformFile file_; + PP_FileSystemType_Dev file_system_type_; + + PP_CompletionCallback callback_; + PP_FileInfo_Dev* info_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc index 9b42cff..7cb65a4 100644 --- a/webkit/glue/plugins/pepper_file_ref.cc +++ b/webkit/glue/plugins/pepper_file_ref.cc @@ -4,6 +4,8 @@ #include "webkit/glue/plugins/pepper_file_ref.h" +#include "base/base_paths.h" +#include "base/path_service.h" #include "base/string_util.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_var.h" @@ -33,7 +35,7 @@ void TrimTrailingSlash(std::string* path) { } PP_Resource CreateFileRef(PP_Instance instance_id, - PP_FileSystemType fs_type, + PP_FileSystemType_Dev fs_type, const char* path) { PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); if (!instance) @@ -65,11 +67,10 @@ bool IsFileRef(PP_Resource resource) { return !!Resource::GetAs<FileRef>(resource); } -PP_FileSystemType GetFileSystemType(PP_Resource file_ref_id) { +PP_FileSystemType_Dev GetFileSystemType(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); if (!file_ref) return PP_FILESYSTEMTYPE_EXTERNAL; - return file_ref->file_system_type(); } @@ -77,8 +78,7 @@ PP_Var GetName(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); if (!file_ref) return PP_MakeVoid(); - - return StringToPPVar(file_ref->GetName()); + return StringVar::StringToPPVar(file_ref->module(), file_ref->GetName()); } PP_Var GetPath(PP_Resource file_ref_id) { @@ -89,7 +89,7 @@ PP_Var GetPath(PP_Resource file_ref_id) { if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) return PP_MakeVoid(); - return StringToPPVar(file_ref->path()); + return StringVar::StringToPPVar(file_ref->module(), file_ref->path()); } PP_Resource GetParent(PP_Resource file_ref_id) { @@ -107,7 +107,7 @@ PP_Resource GetParent(PP_Resource file_ref_id) { return parent_ref->GetReference(); } -const PPB_FileRef ppb_fileref = { +const PPB_FileRef_Dev ppb_fileref = { &CreatePersistentFileRef, &CreateTemporaryFileRef, &IsFileRef, @@ -120,7 +120,7 @@ const PPB_FileRef ppb_fileref = { } // namespace FileRef::FileRef(PluginModule* module, - PP_FileSystemType file_system_type, + PP_FileSystemType_Dev file_system_type, const std::string& validated_path, const std::string& origin) : Resource(module), @@ -130,11 +130,18 @@ FileRef::FileRef(PluginModule* module, // TODO(darin): Need to initialize system_path_. } +FileRef::FileRef(PluginModule* module, + const FilePath& external_file_path) + : Resource(module), + system_path_(external_file_path), + fs_type_(PP_FILESYSTEMTYPE_EXTERNAL) { +} + FileRef::~FileRef() { } // static -const PPB_FileRef* FileRef::GetInterface() { +const PPB_FileRef_Dev* FileRef::GetInterface() { return &ppb_fileref; } @@ -166,4 +173,21 @@ scoped_refptr<FileRef> FileRef::GetParent() { return parent_ref; } +// static +FileRef* FileRef::GetInaccessibleFileRef(PluginModule* module) { + FilePath inaccessible_path; + if (!PathService::Get(base::FILE_MODULE, &inaccessible_path)) + return NULL; + return new FileRef(module, inaccessible_path); +} + +// static +FileRef* FileRef::GetNonexistentFileRef(PluginModule* module) { + FilePath dir_module_path; + if (!PathService::Get(base::DIR_MODULE, &dir_module_path)) + return NULL; + return new FileRef(module, dir_module_path.Append( + FILE_PATH_LITERAL("nonexistent_file"))); +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_ref.h b/webkit/glue/plugins/pepper_file_ref.h index 34e4c3e..0ab0e65 100644 --- a/webkit/glue/plugins/pepper_file_ref.h +++ b/webkit/glue/plugins/pepper_file_ref.h @@ -8,7 +8,7 @@ #include <string> #include "base/file_path.h" -#include "third_party/ppapi/c/ppb_file_ref.h" +#include "third_party/ppapi/c/dev/ppb_file_ref_dev.h" #include "webkit/glue/plugins/pepper_resource.h" namespace pepper { @@ -18,14 +18,16 @@ class PluginModule; class FileRef : public Resource { public: FileRef(PluginModule* module, - PP_FileSystemType file_system_type, + PP_FileSystemType_Dev file_system_type, const std::string& validated_path, const std::string& origin); + FileRef(PluginModule* module, + const FilePath& external_file_path); virtual ~FileRef(); // Returns a pointer to the interface implementing PPB_FileRef that is // exposed to the plugin. - static const PPB_FileRef* GetInterface(); + static const PPB_FileRef_Dev* GetInterface(); // Resource overrides. FileRef* AsFileRef() { return this; } @@ -34,7 +36,7 @@ class FileRef : public Resource { std::string GetName() const; scoped_refptr<FileRef> GetParent(); - PP_FileSystemType file_system_type() const { return fs_type_; } + PP_FileSystemType_Dev file_system_type() const { return fs_type_; } // Returns the virtual path (i.e., the path that the pepper plugin sees) // corresponding to this file. @@ -43,9 +45,17 @@ class FileRef : public Resource { // Returns the system path corresponding to this file. const FilePath& system_path() const { return system_path_; } + // Returns a FileRef instance pointing to a file that should not be + // accessible by the plugin. Should be used for testing only. + static FileRef* GetInaccessibleFileRef(PluginModule* module); + + // Returns a FileRef instance pointing to a nonexistent file. + // Should be used for testing only. + static FileRef* GetNonexistentFileRef(PluginModule* module); + private: FilePath system_path_; - PP_FileSystemType fs_type_; + PP_FileSystemType_Dev fs_type_; std::string path_; // UTF-8 encoded. std::string origin_; }; diff --git a/webkit/glue/plugins/pepper_file_system.cc b/webkit/glue/plugins/pepper_file_system.cc index 678399e..82a2fc8 100644 --- a/webkit/glue/plugins/pepper_file_system.cc +++ b/webkit/glue/plugins/pepper_file_system.cc @@ -4,45 +4,235 @@ #include "webkit/glue/plugins/pepper_file_system.h" +#include "base/logging.h" +#include "base/ref_counted.h" +#include "base/weak_ptr.h" +#include "third_party/ppapi/c/dev/ppb_file_system_dev.h" #include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/ppb_file_system.h" +#include "third_party/ppapi/c/pp_time.h" +#include "webkit/fileapi/file_system_callback_dispatcher.h" +#include "webkit/glue/plugins/pepper_resource.h" +#include "webkit/glue/plugins/pepper_error_util.h" +#include "webkit/glue/plugins/pepper_file_ref.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/pepper_plugin_module.h" +#include "webkit/glue/plugins/pepper_resource.h" namespace pepper { namespace { -int32_t MakeDirectory(PP_Resource directory_ref, +// Instances of this class are deleted when RunCallback() is called. +class StatusCallback : public fileapi::FileSystemCallbackDispatcher { + public: + StatusCallback(base::WeakPtr<pepper::PluginModule> module, + PP_CompletionCallback callback) + : module_(module), + callback_(callback) { + } + + // FileSystemCallbackDispatcher implementation. + virtual void DidSucceed() { + RunCallback(base::PLATFORM_FILE_OK); + } + + virtual void DidReadMetadata(const base::PlatformFileInfo&) { + NOTREACHED(); + } + + virtual void DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>&, bool) { + NOTREACHED(); + } + + virtual void DidOpenFileSystem(const std::string&, const FilePath&) { + NOTREACHED(); + } + + virtual void DidFail(base::PlatformFileError error_code) { + RunCallback(error_code); + } + + private: + void RunCallback(base::PlatformFileError error_code) { + if (!module_.get() || !callback_.func) + return; + + PP_RunCompletionCallback( + &callback_, pepper::PlatformFileErrorToPepperError(error_code)); + + delete this; + } + + base::WeakPtr<pepper::PluginModule> module_; + PP_CompletionCallback callback_; +}; + +// Instances of this class are deleted when RunCallback() is called. +class QueryInfoCallback : public fileapi::FileSystemCallbackDispatcher { + public: + QueryInfoCallback(base::WeakPtr<pepper::PluginModule> module, + PP_CompletionCallback callback, + PP_FileInfo_Dev* info, + PP_FileSystemType_Dev file_system_type) + : module_(module), + callback_(callback), + info_(info), + file_system_type_(file_system_type) { + DCHECK(info_); + } + + // FileSystemCallbackDispatcher implementation. + virtual void DidSucceed() { + NOTREACHED(); + } + + virtual void DidReadMetadata(const base::PlatformFileInfo& file_info) { + RunCallback(base::PLATFORM_FILE_OK, file_info); + } + + virtual void DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>&, bool) { + NOTREACHED(); + } + + virtual void DidOpenFileSystem(const std::string&, const FilePath&) { + NOTREACHED(); + } + + virtual void DidFail(base::PlatformFileError error_code) { + RunCallback(error_code, base::PlatformFileInfo()); + } + + private: + void RunCallback(base::PlatformFileError error_code, + const base::PlatformFileInfo& file_info) { + if (!module_.get() || !callback_.func) + return; + + if (error_code == base::PLATFORM_FILE_OK) { + info_->size = file_info.size; + info_->creation_time = file_info.creation_time.ToDoubleT(); + info_->last_access_time = file_info.last_accessed.ToDoubleT(); + info_->last_modified_time = file_info.last_modified.ToDoubleT(); + info_->system_type = file_system_type_; + if (file_info.is_directory) + info_->type = PP_FILETYPE_DIRECTORY; + else + info_->type = PP_FILETYPE_REGULAR; + } + PP_RunCompletionCallback( + &callback_, pepper::PlatformFileErrorToPepperError(error_code)); + + delete this; + } + + base::WeakPtr<pepper::PluginModule> module_; + PP_CompletionCallback callback_; + PP_FileInfo_Dev* info_; + PP_FileSystemType_Dev file_system_type_; +}; + +int32_t MakeDirectory(PP_Resource directory_ref_id, bool make_ancestors, PP_CompletionCallback callback) { - return PP_ERROR_FAILED; // TODO(darin): Implement me! + scoped_refptr<FileRef> directory_ref( + Resource::GetAs<FileRef>(directory_ref_id)); + if (!directory_ref) + return PP_ERROR_BADRESOURCE; + + if (directory_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; + + PluginModule* module = directory_ref->module(); + if (!module->GetSomeInstance()->delegate()->MakeDirectory( + directory_ref->system_path(), make_ancestors, + new StatusCallback(module->AsWeakPtr(), callback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } -int32_t Query(PP_Resource file_ref, - PP_FileInfo* info, +int32_t Query(PP_Resource file_ref_id, + PP_FileInfo_Dev* info, PP_CompletionCallback callback) { - return PP_ERROR_FAILED; // TODO(darin): Implement me! + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + PluginModule* module = file_ref->module(); + if (!module->GetSomeInstance()->delegate()->Query( + file_ref->system_path(), + new QueryInfoCallback(module->AsWeakPtr(), callback, + info, file_ref->file_system_type()))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } -int32_t Touch(PP_Resource file_ref, +int32_t Touch(PP_Resource file_ref_id, PP_Time last_access_time, PP_Time last_modified_time, PP_CompletionCallback callback) { - return PP_ERROR_FAILED; // TODO(darin): Implement me! + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + PluginModule* module = file_ref->module(); + if (!module->GetSomeInstance()->delegate()->Touch( + file_ref->system_path(), base::Time::FromDoubleT(last_access_time), + base::Time::FromDoubleT(last_modified_time), + new StatusCallback(module->AsWeakPtr(), callback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } -int32_t Delete(PP_Resource file_ref, +int32_t Delete(PP_Resource file_ref_id, PP_CompletionCallback callback) { - return PP_ERROR_FAILED; // TODO(darin): Implement me! + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; + + PluginModule* module = file_ref->module(); + if (!module->GetSomeInstance()->delegate()->Delete( + file_ref->system_path(), + new StatusCallback(module->AsWeakPtr(), callback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } -int32_t Rename(PP_Resource file_ref, - PP_Resource new_file_ref, +int32_t Rename(PP_Resource file_ref_id, + PP_Resource new_file_ref_id, PP_CompletionCallback callback) { - return PP_ERROR_FAILED; // TODO(darin): Implement me! + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileRef> new_file_ref( + Resource::GetAs<FileRef>(new_file_ref_id)); + if (!new_file_ref) + return PP_ERROR_BADRESOURCE; + + if ((file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) || + (file_ref->file_system_type() != new_file_ref->file_system_type())) + return PP_ERROR_FAILED; + + PluginModule* module = file_ref->module(); + if (!module->GetSomeInstance()->delegate()->Rename( + file_ref->system_path(), new_file_ref->system_path(), + new StatusCallback(module->AsWeakPtr(), callback))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; } -const PPB_FileSystem ppb_filesystem = { +const PPB_FileSystem_Dev ppb_filesystem = { &MakeDirectory, &Query, &Touch, @@ -52,7 +242,7 @@ const PPB_FileSystem ppb_filesystem = { } // namespace -const PPB_FileSystem* FileSystem::GetInterface() { +const PPB_FileSystem_Dev* FileSystem::GetInterface() { return &ppb_filesystem; } diff --git a/webkit/glue/plugins/pepper_file_system.h b/webkit/glue/plugins/pepper_file_system.h index b8ad01a..1abfc52 100644 --- a/webkit/glue/plugins/pepper_file_system.h +++ b/webkit/glue/plugins/pepper_file_system.h @@ -5,7 +5,9 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_FILE_SYSTEM_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_SYSTEM_H_ -typedef struct _ppb_FileSystem PPB_FileSystem; +#include "base/basictypes.h" + +struct PPB_FileSystem_Dev; namespace pepper { @@ -13,7 +15,10 @@ class FileSystem { public: // Returns a pointer to the interface implementing PPB_FileSystem that is // exposed to the plugin. - static const PPB_FileSystem* GetInterface(); + static const PPB_FileSystem_Dev* GetInterface(); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystem); }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_font.cc b/webkit/glue/plugins/pepper_font.cc index af4cb81..82bf369 100644 --- a/webkit/glue/plugins/pepper_font.cc +++ b/webkit/glue/plugins/pepper_font.cc @@ -2,98 +2,290 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "build/build_config.h" - #include "webkit/glue/plugins/pepper_font.h" -#if defined(OS_LINUX) -#include <unistd.h> -#endif - #include "base/logging.h" -#include "third_party/ppapi/c/ppb_font.h" +#include "base/utf_string_conversions.h" +#include "third_party/ppapi/c/dev/ppb_font_dev.h" +#include "third_party/ppapi/c/pp_rect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFont.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFontDescription.h" +#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFloatPoint.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFloatRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebTextRun.h" +#include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_module.h" +#include "webkit/glue/plugins/pepper_string.h" +#include "webkit/glue/plugins/pepper_var.h" #include "webkit/glue/webkit_glue.h" +using WebKit::WebFloatPoint; +using WebKit::WebFloatRect; +using WebKit::WebFont; +using WebKit::WebFontDescription; +using WebKit::WebRect; +using WebKit::WebTextRun; + namespace pepper { namespace { -PP_Resource MatchFontWithFallback(PP_Module module_id, - const PP_FontDescription* description) { -#if defined(OS_LINUX) +bool IsPPFontDescriptionValid(const PP_FontDescription_Dev& desc) { + // Check validity of UTF-8. + if (desc.face.type != PP_VARTYPE_STRING && desc.face.type != PP_VARTYPE_VOID) + return false; + + // Check enum ranges. + if (static_cast<int>(desc.family) < PP_FONTFAMILY_DEFAULT || + static_cast<int>(desc.family) > PP_FONTFAMILY_MONOSPACE) + return false; + if (static_cast<int>(desc.weight) < PP_FONTWEIGHT_100 || + static_cast<int>(desc.weight) > PP_FONTWEIGHT_900) + return false; + + // Check for excessive sizes which may cause layout to get confused. + if (desc.size > 200) + return false; + + return true; +} + +// The PP_* version lacks "None", so is just one value shifted from the +// WebFontDescription version. These values are checked in +// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a +// macro so it can also be used in the COMPILE_ASSERTS. +#define PP_FONTFAMILY_TO_WEB_FONTFAMILY(f) \ + static_cast<WebFontDescription::GenericFamily>(f + 1) + +// Assumes the given PP_FontDescription has been validated. +WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font) { + // Verify that the enums match so we can just static cast. + COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) == + static_cast<int>(PP_FONTWEIGHT_100), + FontWeight100); + COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) == + static_cast<int>(PP_FONTWEIGHT_900), + FontWeight900); + COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_DEFAULT), + StandardFamily); + COMPILE_ASSERT(WebFontDescription::GenericFamilySerif == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SERIF), + SerifFamily); + COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SANSSERIF), + SansSerifFamily); + COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace == + PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_MONOSPACE), + MonospaceFamily); + + WebFontDescription result; + scoped_refptr<StringVar> face_name(StringVar::FromPPVar(font.face)); + if (face_name) + result.family = UTF8ToUTF16(face_name->value()); + result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family); + result.size = static_cast<float>(font.size); + result.italic = font.italic; + result.smallCaps = font.small_caps; + result.weight = static_cast<WebFontDescription::Weight>(font.weight); + result.letterSpacing = static_cast<short>(font.letter_spacing); + result.wordSpacing = static_cast<short>(font.word_spacing); + return result; +} + +// Converts the given PP_TextRun to a WebTextRun, returning true on success. +// False means the input was invalid. +bool PPTextRunToWebTextRun(const PP_TextRun_Dev* run, WebTextRun* output) { + scoped_refptr<StringVar> text_string(StringVar::FromPPVar(run->text)); + if (!text_string) + return false; + *output = WebTextRun(UTF8ToUTF16(text_string->value()), + run->rtl, run->override_direction); + return true; +} + +PP_Resource Create(PP_Module module_id, + const PP_FontDescription_Dev* description) { PluginModule* module = PluginModule::FromPPModule(module_id); if (!module) - return NULL; + return 0; - int fd = webkit_glue::MatchFontWithFallback(description->face, - description->weight >= 700, - description->italic, - description->charset); - if (fd == -1) - return NULL; - - scoped_refptr<Font> font(new Font(module, fd)); + if (!IsPPFontDescriptionValid(*description)) + return 0; + scoped_refptr<Font> font(new Font(module, *description)); return font->GetReference(); -#else - // For trusted pepper plugins, this is only needed in Linux since font loading - // on Windows and Mac works through the renderer sandbox. - return false; -#endif } bool IsFont(PP_Resource resource) { - return !!Resource::GetAs<Font>(resource); + return !!Resource::GetAs<Font>(resource).get(); } -bool GetFontTable(PP_Resource font_id, - uint32_t table, - void* output, - uint32_t* output_length) { +bool Describe(PP_Resource font_id, + PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) { scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); if (!font.get()) return false; + return font->Describe(description, metrics); +} - return font->GetFontTable(table, output, output_length); +bool DrawTextAt(PP_Resource font_id, + PP_Resource image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + bool image_data_is_opaque) { + scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); + if (!font.get()) + return false; + return font->DrawTextAt(image_data, text, position, color, clip, + image_data_is_opaque); } -const PPB_Font ppb_font = { - &MatchFontWithFallback, +int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { + scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); + if (!font.get()) + return -1; + return font->MeasureText(text); +} + +uint32_t CharacterOffsetForPixel(PP_Resource font_id, + const PP_TextRun_Dev* text, + int32_t pixel_position) { + scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); + if (!font.get()) + return false; + return font->CharacterOffsetForPixel(text, pixel_position); +} + +int32_t PixelOffsetForCharacter(PP_Resource font_id, + const PP_TextRun_Dev* text, + uint32_t char_offset) { + scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); + if (!font.get()) + return false; + return font->PixelOffsetForCharacter(text, char_offset); +} + +const PPB_Font_Dev ppb_font = { + &Create, &IsFont, - &GetFontTable, + &Describe, + &DrawTextAt, + &MeasureText, + &CharacterOffsetForPixel, + &PixelOffsetForCharacter }; } // namespace -Font::Font(PluginModule* module, int fd) - : Resource(module), - fd_(fd) { +Font::Font(PluginModule* module, const PP_FontDescription_Dev& desc) + : Resource(module) { + WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc); + font_.reset(WebFont::create(web_font_desc)); } Font::~Font() { -#if defined (OS_LINUX) - close(fd_); -#endif } // static -const PPB_Font* Font::GetInterface() { +const PPB_Font_Dev* Font::GetInterface() { return &ppb_font; } -bool Font::GetFontTable(uint32_t table, - void* output, - uint32_t* output_length) { -#if defined(OS_LINUX) - size_t temp_size = static_cast<size_t>(*output_length); - bool rv = webkit_glue::GetFontTable( - fd_, table, static_cast<uint8_t*>(output), &temp_size); - *output_length = static_cast<uint32_t>(temp_size); - return rv; -#else - return false; -#endif +bool Font::Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics) { + if (description->face.type != PP_VARTYPE_VOID) + return false; + + WebFontDescription web_desc = font_->fontDescription(); + + // While converting the other way in PPFontDescToWebFontDesc we validated + // that the enums can be casted. + description->face = StringVar::StringToPPVar(module(), + UTF16ToUTF8(web_desc.family)); + description->family = static_cast<PP_FontFamily_Dev>(web_desc.genericFamily); + description->size = static_cast<uint32_t>(web_desc.size); + description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight); + description->italic = web_desc.italic; + description->small_caps = web_desc.smallCaps; + + metrics->height = font_->height(); + metrics->ascent = font_->ascent(); + metrics->descent = font_->descent(); + metrics->line_spacing = font_->lineSpacing(); + metrics->x_height = static_cast<int32_t>(font_->xHeight()); + + return true; +} + +bool Font::DrawTextAt(PP_Resource image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + bool image_data_is_opaque) { + WebTextRun run; + if (!PPTextRunToWebTextRun(text, &run)) + return false; + + // Get and map the image data we're painting to. + scoped_refptr<ImageData> image_resource( + Resource::GetAs<ImageData>(image_data)); + if (!image_resource.get()) + return false; + ImageDataAutoMapper mapper(image_resource); + if (!mapper.is_valid()) + return false; + + // Convert position and clip. + WebFloatPoint web_position(static_cast<float>(position->x), + static_cast<float>(position->y)); + WebRect web_clip; + if (!clip) { + // Use entire canvas. + web_clip = WebRect(0, 0, image_resource->width(), image_resource->height()); + } else { + web_clip = WebRect(clip->point.x, clip->point.y, + clip->size.width, clip->size.height); + } + + font_->drawText(webkit_glue::ToWebCanvas(image_resource->mapped_canvas()), + run, web_position, color, web_clip, image_data_is_opaque); + return true; +} + +int32_t Font::MeasureText(const PP_TextRun_Dev* text) { + WebTextRun run; + if (!PPTextRunToWebTextRun(text, &run)) + return -1; + return font_->calculateWidth(run); +} + +uint32_t Font::CharacterOffsetForPixel(const PP_TextRun_Dev* text, + int32_t pixel_position) { + WebTextRun run; + if (!PPTextRunToWebTextRun(text, &run)) + return -1; + + return static_cast<uint32_t>(font_->offsetForPosition( + run, static_cast<float>(pixel_position))); +} + +int32_t Font::PixelOffsetForCharacter(const PP_TextRun_Dev* text, + uint32_t char_offset) { + WebTextRun run; + if (!PPTextRunToWebTextRun(text, &run)) + return -1; + if (char_offset >= run.text.length()) + return -1; + + WebFloatRect rect = font_->selectionRectForText( + run, WebFloatPoint(0.0f, 0.0f), font_->height(), 0, char_offset); + return static_cast<int>(rect.width); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_font.h b/webkit/glue/plugins/pepper_font.h index ad1abba..34fe521 100644 --- a/webkit/glue/plugins/pepper_font.h +++ b/webkit/glue/plugins/pepper_font.h @@ -5,9 +5,13 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_FONT_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_FONT_H_ +#include "base/scoped_ptr.h" +#include "third_party/ppapi/c/dev/ppb_font_dev.h" #include "webkit/glue/plugins/pepper_resource.h" -typedef struct _ppb_Font PPB_Font; +namespace WebKit { +class WebFont; +} namespace pepper { @@ -15,23 +19,33 @@ class PluginInstance; class Font : public Resource { public: - Font(PluginModule* module, int fd); + Font(PluginModule* module, const PP_FontDescription_Dev& desc); virtual ~Font(); // Returns a pointer to the interface implementing PPB_Font that is exposed to // the plugin. - static const PPB_Font* GetInterface(); + static const PPB_Font_Dev* GetInterface(); // Resource overrides. Font* AsFont() { return this; } // PPB_Font implementation. - bool GetFontTable(uint32_t table, - void* output, - uint32_t* output_length); + bool Describe(PP_FontDescription_Dev* description, + PP_FontMetrics_Dev* metrics); + bool DrawTextAt(PP_Resource image_data, + const PP_TextRun_Dev* text, + const PP_Point* position, + uint32_t color, + const PP_Rect* clip, + bool image_data_is_opaque); + int32_t MeasureText(const PP_TextRun_Dev* text); + uint32_t CharacterOffsetForPixel(const PP_TextRun_Dev* text, + int32_t pixel_position); + int32_t PixelOffsetForCharacter(const PP_TextRun_Dev* text, + uint32_t char_offset); private: - int fd_; + scoped_ptr<WebKit::WebFont> font_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_image_data.cc b/webkit/glue/plugins/pepper_image_data.cc index 8288fe2..aeb2c88 100644 --- a/webkit/glue/plugins/pepper_image_data.cc +++ b/webkit/glue/plugins/pepper_image_data.cc @@ -14,6 +14,7 @@ #include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/pp_resource.h" #include "third_party/ppapi/c/ppb_image_data.h" +#include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -31,11 +32,11 @@ PP_Resource Create(PP_Module module_id, bool init_to_zero) { PluginModule* module = PluginModule::FromPPModule(module_id); if (!module) - return NULL; + return 0; scoped_refptr<ImageData> data(new ImageData(module)); if (!data->Init(format, size->width, size->height, init_to_zero)) - return NULL; + return 0; return data->GetReference(); } @@ -68,6 +69,13 @@ void Unmap(PP_Resource resource) { image_data->Unmap(); } +uint64_t GetNativeMemoryHandle2(PP_Resource resource) { + scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource)); + if (image_data) + return image_data->GetNativeMemoryHandle(); + return 0; +} + const PPB_ImageData ppb_imagedata = { &GetNativeImageDataFormat, &Create, @@ -77,6 +85,10 @@ const PPB_ImageData ppb_imagedata = { &Unmap, }; +const PPB_ImageDataTrusted ppb_imagedata_trusted = { + &GetNativeMemoryHandle2, +}; + } // namespace ImageData::ImageData(PluginModule* module) @@ -93,6 +105,11 @@ const PPB_ImageData* ImageData::GetInterface() { return &ppb_imagedata; } +// static +const PPB_ImageDataTrusted* ImageData::GetTrustedInterface() { + return &ppb_imagedata_trusted; +} + bool ImageData::Init(PP_ImageDataFormat format, int width, int height, bool init_to_zero) { @@ -143,6 +160,10 @@ void ImageData::Unmap() { // in the future to save some memory. } +uint64 ImageData::GetNativeMemoryHandle() const { + return platform_image_->GetSharedMemoryHandle(); +} + const SkBitmap* ImageData::GetMappedBitmap() const { if (!mapped_canvas_.get()) return NULL; diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h index 7652b80..f2a110b 100644 --- a/webkit/glue/plugins/pepper_image_data.h +++ b/webkit/glue/plugins/pepper_image_data.h @@ -15,6 +15,7 @@ namespace skia { class PlatformCanvas; } +struct PPB_ImageDataTrusted; class SkBitmap; namespace pepper { @@ -37,12 +38,17 @@ class ImageData : public Resource { // invalid or not mapped. See ImageDataAutoMapper below. bool is_mapped() const { return !!mapped_canvas_.get(); } + PluginDelegate::PlatformImage2D* platform_image() const { + return platform_image_.get(); + } + // Returns a pointer to the interface implementing PPB_ImageData that is // exposed to the plugin. static const PPB_ImageData* GetInterface(); + static const PPB_ImageDataTrusted* GetTrustedInterface(); // Resource overrides. - ImageData* AsImageData() { return this; } + virtual ImageData* AsImageData() { return this; } // PPB_ImageData implementation. bool Init(PP_ImageDataFormat format, @@ -52,6 +58,9 @@ class ImageData : public Resource { void* Map(); void Unmap(); + // PPB_ImageDataTrusted implementation. + uint64 GetNativeMemoryHandle() const; + // The mapped bitmap and canvas will be NULL if the image is not mapped. skia::PlatformCanvas* mapped_canvas() const { return mapped_canvas_.get(); } const SkBitmap* GetMappedBitmap() const; diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index ffc9d52..1bb4bed 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -5,15 +5,57 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_ +#include <string> + +#include "base/callback.h" +#include "base/platform_file.h" +#include "base/ref_counted.h" +#include "base/shared_memory.h" +#include "base/sync_socket.h" +#include "base/task.h" +#include "third_party/ppapi/c/pp_completion_callback.h" +#include "third_party/ppapi/c/pp_errors.h" #include "third_party/ppapi/c/pp_stdint.h" +class AudioMessageFilter; + +namespace base { +class MessageLoopProxy; +class Time; +} + +namespace fileapi { +class FileSystemCallbackDispatcher; +} + +namespace gfx { +class Rect; +} + +namespace gpu { +class CommandBuffer; +} + namespace skia { class PlatformCanvas; } +namespace WebKit { +class WebFileChooserCompletion; +struct WebFileChooserParams; +} + +struct PP_VideoCompressedDataBuffer_Dev; +struct PP_VideoDecoderConfig_Dev; +struct PP_VideoUncompressedDataBuffer_Dev; + +class TransportDIB; + namespace pepper { +class FileIO; class PluginInstance; +class FullscreenContainer; // Virtual interface that the browser implements to implement features for // Pepper plugins. @@ -32,6 +74,62 @@ class PluginDelegate { // this image. This is used by NativeClient to send the image to the // out-of-process plugin. Returns 0 on failure. virtual intptr_t GetSharedMemoryHandle() const = 0; + + virtual TransportDIB* GetTransportDIB() const = 0; + }; + + class PlatformContext3D { + public: + virtual ~PlatformContext3D() {} + + // Initialize the context. + virtual bool Init(const gfx::Rect& position, const gfx::Rect& clip) = 0; + + // This call will return the address of the command buffer object that is + // constructed in Initialize() and is valid until this context is destroyed. + virtual gpu::CommandBuffer* GetCommandBuffer() = 0; + + // Sets the function to be called on repaint. + virtual void SetNotifyRepaintTask(Task* task) = 0; + }; + + class PlatformAudio { + public: + class Client { + protected: + virtual ~Client() {} + + public: + // Called when the stream is created. + virtual void StreamCreated(base::SharedMemoryHandle shared_memory_handle, + size_t shared_memory_size, + base::SyncSocket::Handle socket) = 0; + }; + + virtual ~PlatformAudio() {} + + // Starts the playback. Returns false on error or if called before the + // stream is created or after the stream is closed. + virtual bool StartPlayback() = 0; + + // Stops the playback. Returns false on error or if called before the stream + // is created or after the stream is closed. + virtual bool StopPlayback() = 0; + + // Closes the stream. Make sure to call this before the object is + // destructed. + virtual void ShutDown() = 0; + }; + + class PlatformVideoDecoder { + public: + virtual ~PlatformVideoDecoder() {} + + // Returns false on failure. + virtual bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) = 0; + virtual int32_t Flush(PP_CompletionCallback& callback) = 0; + virtual bool ReturnUncompressedDataBuffer( + PP_VideoUncompressedDataBuffer_Dev& buffer) = 0; }; // Indicates that the given instance has been created. @@ -45,13 +143,65 @@ class PluginDelegate { // The caller will own the pointer returned from this. virtual PlatformImage2D* CreateImage2D(int width, int height) = 0; + // The caller will own the pointer returned from this. + virtual PlatformContext3D* CreateContext3D() = 0; + + // The caller will own the pointer returned from this. + virtual PlatformVideoDecoder* CreateVideoDecoder( + const PP_VideoDecoderConfig_Dev& decoder_config) = 0; + + // The caller will own the pointer returned from this. + virtual PlatformAudio* CreateAudio(uint32_t sample_rate, + uint32_t sample_count, + PlatformAudio::Client* client) = 0; + // Notifies that the number of find results has changed. virtual void DidChangeNumberOfFindResults(int identifier, - int total, - bool final_result) = 0; + int total, + bool final_result) = 0; // Notifies that the index of the currently selected item has been updated. virtual void DidChangeSelectedFindResult(int identifier, int index) = 0; + + // Runs a file chooser. + virtual bool RunFileChooser( + const WebKit::WebFileChooserParams& params, + WebKit::WebFileChooserCompletion* chooser_completion) = 0; + + // Sends an async IPC to open a file. + typedef Callback2<base::PlatformFileError, base::PlatformFile + >::Type AsyncOpenFileCallback; + virtual bool AsyncOpenFile(const FilePath& path, + int flags, + AsyncOpenFileCallback* callback) = 0; + virtual bool MakeDirectory( + const FilePath& path, + bool recursive, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual bool Query(const FilePath& path, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual bool Touch(const FilePath& path, + const base::Time& last_access_time, + const base::Time& last_modified_time, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual bool Delete(const FilePath& path, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual bool Rename(const FilePath& file_path, + const FilePath& new_file_path, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + + // Returns a MessageLoopProxy instance associated with the message loop + // of the file thread in this renderer. + virtual scoped_refptr<base::MessageLoopProxy> + GetFileThreadMessageLoopProxy() = 0; + + // Create a fullscreen container for a plugin instance. This effectively + // switches the plugin to fullscreen. + virtual FullscreenContainer* CreateFullscreenContainer( + PluginInstance* instance) = 0; + + // Returns a string with the name of the default 8-bit char encoding. + virtual std::string GetDefaultEncoding() = 0; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index 6a7bf54..b4ccd89 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -22,17 +22,19 @@ #include "printing/units.h" #include "skia/ext/vector_platform_device.h" #include "skia/ext/platform_canvas.h" +#include "third_party/ppapi/c/dev/ppb_find_dev.h" +#include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h" +#include "third_party/ppapi/c/dev/ppp_find_dev.h" +#include "third_party/ppapi/c/dev/ppp_zoom_dev.h" +#include "third_party/ppapi/c/pp_input_event.h" #include "third_party/ppapi/c/pp_instance.h" -#include "third_party/ppapi/c/pp_event.h" #include "third_party/ppapi/c/pp_rect.h" #include "third_party/ppapi/c/pp_resource.h" #include "third_party/ppapi/c/pp_var.h" #include "third_party/ppapi/c/ppb_core.h" -#include "third_party/ppapi/c/ppb_find.h" #include "third_party/ppapi/c/ppb_instance.h" -#include "third_party/ppapi/c/ppp_find.h" #include "third_party/ppapi/c/ppp_instance.h" -#include "third_party/ppapi/c/ppp_zoom.h" +#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebElement.h" @@ -41,8 +43,9 @@ #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "webkit/glue/plugins/pepper_buffer.h" -#include "webkit/glue/plugins/pepper_device_context_2d.h" +#include "webkit/glue/plugins/pepper_graphics_2d.h" #include "webkit/glue/plugins/pepper_event_conversion.h" +#include "webkit/glue/plugins/pepper_fullscreen_container.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -50,6 +53,7 @@ #include "webkit/glue/plugins/pepper_url_loader.h" #include "webkit/glue/plugins/pepper_var.h" +using WebKit::WebBindings; using WebKit::WebCanvas; using WebKit::WebCursorInfo; using WebKit::WebFrame; @@ -146,11 +150,11 @@ PP_Var GetOwnerElementObject(PP_Instance instance_id) { return instance->GetOwnerElementObject(); } -bool BindGraphicsDeviceContext(PP_Instance instance_id, PP_Resource device_id) { +bool BindGraphics(PP_Instance instance_id, PP_Resource device_id) { PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); if (!instance) return false; - return instance->BindGraphicsDeviceContext(device_id); + return instance->BindGraphics(device_id); } bool IsFullFrame(PP_Instance instance_id) { @@ -160,31 +164,21 @@ bool IsFullFrame(PP_Instance instance_id) { return instance->full_frame(); } -bool SetCursor(PP_Instance instance_id, - PP_CursorType type, - PP_Resource custom_image_id, - const PP_Point* hot_spot) { +PP_Var ExecuteScript(PP_Instance instance_id, + PP_Var script, + PP_Var* exception) { PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); if (!instance) - return false; - - scoped_refptr<ImageData> custom_image( - Resource::GetAs<ImageData>(custom_image_id)); - if (custom_image.get()) { - // TODO: implement custom cursors. - NOTIMPLEMENTED(); - return false; - } - - return instance->SetCursor(type); + return PP_MakeVoid(); + return instance->ExecuteScript(script, exception); } const PPB_Instance ppb_instance = { &GetWindowObject, &GetOwnerElementObject, - &BindGraphicsDeviceContext, + &BindGraphics, &IsFullFrame, - &SetCursor, + &ExecuteScript, }; void NumberOfFindResultsChanged(PP_Instance instance_id, @@ -210,11 +204,30 @@ void SelectedFindResultChanged(PP_Instance instance_id, instance->find_identifier(), index); } -const PPB_Find ppb_find = { +const PPB_Find_Dev ppb_find = { &NumberOfFindResultsChanged, &SelectedFindResultChanged, }; +bool IsFullscreen(PP_Instance instance_id) { + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return false; + return instance->IsFullscreen(); +} + +bool SetFullscreen(PP_Instance instance_id, bool fullscreen) { + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return false; + return instance->SetFullscreen(fullscreen); +} + +const PPB_Fullscreen_Dev ppb_fullscreen = { + &IsFullscreen, + &SetFullscreen, +}; + } // namespace PluginInstance::PluginInstance(PluginDelegate* delegate, @@ -225,6 +238,8 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, instance_interface_(instance_interface), container_(NULL), full_frame_(false), + has_webkit_focus_(false), + has_content_area_focus_(false), find_identifier_(-1), plugin_find_interface_(NULL), plugin_zoom_interface_(NULL), @@ -232,7 +247,10 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, num_pages_(0), pdf_output_done_(false), #endif // defined (OS_LINUX) - plugin_print_interface_(NULL) { + plugin_print_interface_(NULL), + plugin_graphics_3d_interface_(NULL), + always_on_top_(false), + fullscreen_container_(NULL) { memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); DCHECK(delegate); module_->InstanceCreated(this); @@ -255,10 +273,15 @@ PluginInstance* PluginInstance::FromPPInstance(PP_Instance instance) { } // static -const PPB_Find* PluginInstance::GetFindInterface() { +const PPB_Find_Dev* PluginInstance::GetFindInterface() { return &ppb_find; } +// static +const PPB_Fullscreen_Dev* PluginInstance::GetFullscreenInterface() { + return &ppb_fullscreen; +} + PP_Instance PluginInstance::GetPPInstance() { return reinterpret_cast<intptr_t>(this); } @@ -266,17 +289,24 @@ PP_Instance PluginInstance::GetPPInstance() { void PluginInstance::Paint(WebCanvas* canvas, const gfx::Rect& plugin_rect, const gfx::Rect& paint_rect) { - if (device_context_2d_) - device_context_2d_->Paint(canvas, plugin_rect, paint_rect); + if (bound_graphics_2d_) + bound_graphics_2d_->Paint(canvas, plugin_rect, paint_rect); } void PluginInstance::InvalidateRect(const gfx::Rect& rect) { - if (!container_ || position_.IsEmpty()) - return; // Nothing to do. - if (rect.IsEmpty()) - container_->invalidate(); - else - container_->invalidateRect(rect); + if (fullscreen_container_) { + if (rect.IsEmpty()) + fullscreen_container_->Invalidate(); + else + fullscreen_container_->InvalidateRect(rect); + } else { + if (!container_ || position_.IsEmpty()) + return; // Nothing to do. + if (rect.IsEmpty()) + container_->invalidate(); + else + container_->invalidateRect(rect); + } } PP_Var PluginInstance::GetWindowObject() { @@ -287,29 +317,28 @@ PP_Var PluginInstance::GetWindowObject() { if (!frame) return PP_MakeVoid(); - return NPObjectToPPVar(frame->windowObject()); + return ObjectVar::NPObjectToPPVar(module(), frame->windowObject()); } PP_Var PluginInstance::GetOwnerElementObject() { if (!container_) return PP_MakeVoid(); - - return NPObjectToPPVar(container_->scriptableObjectForElement()); + return ObjectVar::NPObjectToPPVar(module(), + container_->scriptableObjectForElement()); } -bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) { +bool PluginInstance::BindGraphics(PP_Resource device_id) { if (!device_id) { // Special-case clearing the current device. - if (device_context_2d_) { - device_context_2d_->BindToInstance(NULL); - device_context_2d_ = NULL; + if (bound_graphics_2d_) { + bound_graphics_2d_->BindToInstance(NULL); + bound_graphics_2d_ = NULL; InvalidateRect(gfx::Rect()); } return true; } - scoped_refptr<DeviceContext2D> device_2d = - Resource::GetAs<DeviceContext2D>(device_id); + scoped_refptr<Graphics2D> device_2d = Resource::GetAs<Graphics2D>(device_id); if (device_2d) { if (!device_2d->BindToInstance(this)) @@ -317,11 +346,11 @@ bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) { // See http://crbug.com/49403: this can be further optimized by keeping the // old device around and painting from it. - if (device_context_2d_.get()) { + if (bound_graphics_2d_.get()) { // Start the new image with the content of the old image until the plugin // repaints. const SkBitmap* old_backing_bitmap = - device_context_2d_->image_data()->GetMappedBitmap(); + bound_graphics_2d_->image_data()->GetMappedBitmap(); SkRect old_size = SkRect::MakeWH( SkScalar(static_cast<float>(old_backing_bitmap->width())), SkScalar(static_cast<float>(old_backing_bitmap->height()))); @@ -334,21 +363,63 @@ bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) { canvas.drawARGB(255, 255, 255, 255); } - device_context_2d_ = device_2d; + bound_graphics_2d_ = device_2d; // BindToInstance will have invalidated the plugin if necessary. } return true; } -bool PluginInstance::SetCursor(PP_CursorType type) { +bool PluginInstance::SetCursor(PP_CursorType_Dev type) { cursor_.reset(new WebCursorInfo(static_cast<WebCursorInfo::Type>(type))); return true; } +PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) { + TryCatch try_catch(module(), exception); + if (try_catch.has_exception()) + return PP_MakeVoid(); + + // Convert the script into an inconvenient NPString object. + scoped_refptr<StringVar> script_string(StringVar::FromPPVar(script)); + if (!script_string) { + try_catch.SetException("Script param to ExecuteScript must be a string."); + return PP_MakeVoid(); + } + NPString np_script; + np_script.UTF8Characters = script_string->value().c_str(); + np_script.UTF8Length = script_string->value().length(); + + // Get the current frame to pass to the evaluate function. + WebFrame* frame = container_->element().document().frame(); + if (!frame) { + try_catch.SetException("No frame to execute script in."); + return PP_MakeVoid(); + } + + NPVariant result; + bool ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script, + &result); + if (!ok) { + // TODO(brettw) bug 54011: The TryCatch isn't working properly and + // doesn't actually catch this exception. + try_catch.SetException("Exception caught"); + WebBindings::releaseVariantValue(&result); + return PP_MakeVoid(); + } + + PP_Var ret = Var::NPVariantToPPVar(module_, &result); + WebBindings::releaseVariantValue(&result); + return ret; +} + void PluginInstance::Delete() { instance_interface_->Delete(GetPPInstance()); + if (fullscreen_container_) { + fullscreen_container_->Destroy(); + fullscreen_container_ = NULL; + } container_ = NULL; } @@ -382,11 +453,14 @@ bool PluginInstance::HandleDocumentLoad(URLLoader* loader) { bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, WebCursorInfo* cursor_info) { - scoped_ptr<PP_Event> pp_event(CreatePP_Event(event)); - if (!pp_event.get()) - return false; + std::vector<PP_InputEvent> pp_events; + CreatePPEvent(event, &pp_events); + + // Each input event may generate more than one PP_InputEvent. + bool rv = false; + for (size_t i = 0; i < pp_events.size(); i++) + rv |= instance_interface_->HandleInputEvent(GetPPInstance(), &pp_events[i]); - bool rv = instance_interface_->HandleEvent(GetPPInstance(), pp_event.get()); if (cursor_.get()) *cursor_info = *cursor_; return rv; @@ -415,19 +489,67 @@ void PluginInstance::ViewChanged(const gfx::Rect& position, instance_interface_->ViewChanged(GetPPInstance(), &pp_position, &pp_clip); } +void PluginInstance::SetWebKitFocus(bool has_focus) { + if (has_webkit_focus_ == has_focus) + return; + + bool old_plugin_focus = PluginHasFocus(); + has_webkit_focus_ = has_focus; + if (PluginHasFocus() != old_plugin_focus) + instance_interface_->FocusChanged(GetPPInstance(), PluginHasFocus()); +} + +void PluginInstance::SetContentAreaFocus(bool has_focus) { + if (has_content_area_focus_ == has_focus) + return; + + bool old_plugin_focus = PluginHasFocus(); + has_content_area_focus_ = has_focus; + if (PluginHasFocus() != old_plugin_focus) + instance_interface_->FocusChanged(GetPPInstance(), PluginHasFocus()); +} + void PluginInstance::ViewInitiatedPaint() { - if (device_context_2d_) - device_context_2d_->ViewInitiatedPaint(); + if (bound_graphics_2d_) + bound_graphics_2d_->ViewInitiatedPaint(); } void PluginInstance::ViewFlushedPaint() { - if (device_context_2d_) - device_context_2d_->ViewFlushedPaint(); + if (bound_graphics_2d_) + bound_graphics_2d_->ViewFlushedPaint(); +} + +bool PluginInstance::GetBitmapForOptimizedPluginPaint( + const gfx::Rect& paint_bounds, + TransportDIB** dib, + gfx::Rect* location, + gfx::Rect* clip) { + if (!always_on_top_) + return false; + if (!bound_graphics_2d_ || !bound_graphics_2d_->is_always_opaque()) + return false; + + // We specifically want to compare against the area covered by the backing + // store when seeing if we cover the given paint bounds, since the backing + // store could be smaller than the declared plugin area. + ImageData* image_data = bound_graphics_2d_->image_data(); + gfx::Rect plugin_backing_store_rect(position_.origin(), + gfx::Size(image_data->width(), + image_data->height())); + gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_); + if (!plugin_paint_rect.Contains(paint_bounds)) + return false; + + *dib = image_data->platform_image()->GetTransportDIB(); + *location = plugin_backing_store_rect; + *clip = clip_; + return true; } string16 PluginInstance::GetSelectedText(bool html) { PP_Var rv = instance_interface_->GetSelectedText(GetPPInstance(), html); - String* string = GetString(rv); + scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); + Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us. if (!string) return string16(); return UTF8ToUTF16(string->value()); @@ -466,8 +588,8 @@ void PluginInstance::StopFind() { bool PluginInstance::LoadFindInterface() { if (!plugin_find_interface_) { plugin_find_interface_ = - reinterpret_cast<const PPP_Find*>(module_->GetPluginInterface( - PPP_FIND_INTERFACE)); + reinterpret_cast<const PPP_Find_Dev*>(module_->GetPluginInterface( + PPP_FIND_DEV_INTERFACE)); } return !!plugin_find_interface_; @@ -476,24 +598,28 @@ bool PluginInstance::LoadFindInterface() { bool PluginInstance::LoadZoomInterface() { if (!plugin_zoom_interface_) { plugin_zoom_interface_ = - reinterpret_cast<const PPP_Zoom*>(module_->GetPluginInterface( - PPP_ZOOM_INTERFACE)); + reinterpret_cast<const PPP_Zoom_Dev*>(module_->GetPluginInterface( + PPP_ZOOM_DEV_INTERFACE)); } return !!plugin_zoom_interface_; } +bool PluginInstance::PluginHasFocus() const { + return has_webkit_focus_ && has_content_area_focus_; +} + bool PluginInstance::GetPreferredPrintOutputFormat( - PP_PrintOutputFormat* format) { + PP_PrintOutputFormat_Dev* format) { if (!plugin_print_interface_) { plugin_print_interface_ = - reinterpret_cast<const PPP_Printing*>(module_->GetPluginInterface( - PPP_PRINTING_INTERFACE)); + reinterpret_cast<const PPP_Printing_Dev*>(module_->GetPluginInterface( + PPP_PRINTING_DEV_INTERFACE)); } if (!plugin_print_interface_) return false; uint32_t format_count = 0; - PP_PrintOutputFormat* supported_formats = + PP_PrintOutputFormat_Dev* supported_formats = plugin_print_interface_->QuerySupportedFormats(GetPPInstance(), &format_count); if (!supported_formats) @@ -517,13 +643,13 @@ bool PluginInstance::GetPreferredPrintOutputFormat( } bool PluginInstance::SupportsPrintInterface() { - PP_PrintOutputFormat format; + PP_PrintOutputFormat_Dev format; return GetPreferredPrintOutputFormat(&format); } int PluginInstance::PrintBegin(const gfx::Rect& printable_area, int printer_dpi) { - PP_PrintOutputFormat format; + PP_PrintOutputFormat_Dev format; if (!GetPreferredPrintOutputFormat(&format)) { // PrintBegin should not have been called since SupportsPrintInterface // would have returned false; @@ -531,7 +657,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area, return 0; } - PP_PrintSettings print_settings; + PP_PrintSettings_Dev print_settings; RectToPPRect(printable_area, &print_settings.printable_area); print_settings.dpi = printer_dpi; print_settings.orientation = PP_PRINTORIENTATION_NORMAL; @@ -551,7 +677,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area, bool PluginInstance::PrintPage(int page_number, WebKit::WebCanvas* canvas) { DCHECK(plugin_print_interface_); - PP_PrintPageNumberRange page_range; + PP_PrintPageNumberRange_Dev page_range; #if defined(OS_LINUX) if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) { // On Linux we will try and output all pages as PDF in the first call to @@ -592,13 +718,48 @@ void PluginInstance::PrintEnd() { plugin_print_interface_->End(GetPPInstance()); memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); #if defined(OS_MACOSX) - last_printed_page_ = SkBitmap(); + last_printed_page_ = NULL; #elif defined(OS_LINUX) num_pages_ = 0; pdf_output_done_ = false; #endif // defined(OS_LINUX) } +void PluginInstance::Graphics3DContextLost() { + if (!plugin_graphics_3d_interface_) { + plugin_graphics_3d_interface_ = + reinterpret_cast<const PPP_Graphics3D_Dev*>(module_->GetPluginInterface( + PPP_GRAPHICS_3D_DEV_INTERFACE)); + } + if (plugin_graphics_3d_interface_) + plugin_graphics_3d_interface_->Graphics3DContextLost(GetPPInstance()); +} + +bool PluginInstance::IsFullscreen() { + return fullscreen_container_ != NULL; +} + +bool PluginInstance::SetFullscreen(bool fullscreen) { + bool is_fullscreen = (fullscreen_container_ != NULL); + if (fullscreen == is_fullscreen) + return true; + LOG(INFO) << "Setting fullscreen to " << (fullscreen ? "on" : "off"); + if (fullscreen) { + fullscreen_container_ = delegate_->CreateFullscreenContainer(this); + } else { + fullscreen_container_->Destroy(); + fullscreen_container_ = NULL; + // TODO(piman): currently the fullscreen container resizes the plugin to the + // fullscreen size so we need to reset the size here. Eventually it will + // transparently scale and this won't be necessary. + if (container_) { + container_->reportGeometry(); + container_->invalidate(); + } + } + return true; +} + bool PluginInstance::PrintPDFOutput(PP_Resource print_output, WebKit::WebCanvas* canvas) { scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(print_output)); @@ -730,7 +891,7 @@ bool PluginInstance::PrintRasterOutput(PP_Resource print_output, DrawSkBitmapToCanvas(*bitmap, canvas, dest_rect_gfx, current_print_settings_.printable_area.size.height); // See comments in the header file. - last_printed_page_ = *bitmap; + last_printed_page_ = image; #else // defined(OS_MACOSX) if (draw_to_canvas) canvas->drawBitmapRect(*bitmap, &src_rect, dest_rect); diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index 4528a99..4eb956f 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -13,21 +13,24 @@ #include "base/scoped_ptr.h" #include "base/string16.h" #include "gfx/rect.h" -#include "third_party/ppapi/c/pp_cursor_type.h" +#include "third_party/ppapi/c/dev/pp_cursor_type_dev.h" +#include "third_party/ppapi/c/dev/ppp_graphics_3d_dev.h" +#include "third_party/ppapi/c/dev/ppp_printing_dev.h" #include "third_party/ppapi/c/pp_instance.h" #include "third_party/ppapi/c/pp_resource.h" -#include "third_party/ppapi/c/ppp_printing.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h" -typedef struct _pp_Var PP_Var; -typedef struct _ppb_Instance PPB_Instance; -typedef struct _ppb_Find PPB_Find; -typedef struct _ppp_Find PPP_Find; -typedef struct _ppp_Instance PPP_Instance; -typedef struct _ppp_Zoom PPP_Zoom; +struct PP_Var; +struct PPB_Instance; +struct PPB_Find_Dev; +struct PPB_Fullscreen_Dev; +struct PPP_Find_Dev; +struct PPP_Instance; +struct PPP_Zoom_Dev; class SkBitmap; +class TransportDIB; namespace gfx { class Rect; @@ -41,10 +44,12 @@ class WebPluginContainer; namespace pepper { -class DeviceContext2D; +class Graphics2D; +class ImageData; class PluginDelegate; class PluginModule; class URLLoader; +class FullscreenContainer; class PluginInstance : public base::RefCounted<PluginInstance> { public: @@ -60,7 +65,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // Returns a pointer to the interface implementing PPB_Find that is // exposed to the plugin. - static const PPB_Find* GetFindInterface(); + static const PPB_Find_Dev* GetFindInterface(); + static const PPB_Fullscreen_Dev* GetFullscreenInterface(); PluginDelegate* delegate() const { return delegate_; } PluginModule* module() const { return module_.get(); } @@ -72,6 +78,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { int find_identifier() const { return find_identifier_; } + void set_always_on_top(bool on_top) { always_on_top_ = on_top; } + PP_Instance GetPPInstance(); // Paints the current backing store to the web page. @@ -88,9 +96,10 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // PPB_Instance implementation. PP_Var GetWindowObject(); PP_Var GetOwnerElementObject(); - bool BindGraphicsDeviceContext(PP_Resource device_id); + bool BindGraphics(PP_Resource device_id); bool full_frame() const { return full_frame_; } - bool SetCursor(PP_CursorType type); + bool SetCursor(PP_CursorType_Dev type); + PP_Var ExecuteScript(PP_Var script, PP_Var* exception); // PPP_Instance pass-through. void Delete(); @@ -104,12 +113,26 @@ class PluginInstance : public base::RefCounted<PluginInstance> { PP_Var GetInstanceObject(); void ViewChanged(const gfx::Rect& position, const gfx::Rect& clip); + // Notifications about focus changes, see has_webkit_focus_ below. + void SetWebKitFocus(bool has_focus); + void SetContentAreaFocus(bool has_focus); + // Notifications that the view has rendered the page and that it has been // flushed to the screen. These messages are used to send Flush callbacks to // the plugin for DeviceContext2D. void ViewInitiatedPaint(); void ViewFlushedPaint(); + // If this plugin can be painted merely by copying the backing store to the + // screen, and the plugin bounds encloses the given paint bounds, returns + // true. In this case, the location, clipping, and ID of the backing store + // will be filled into the given output parameters. + bool GetBitmapForOptimizedPluginPaint( + const gfx::Rect& paint_bounds, + TransportDIB** dib, + gfx::Rect* dib_bounds, + gfx::Rect* clip); + string16 GetSelectedText(bool html); void Zoom(float factor, bool text_only); bool StartFind(const string16& search_text, @@ -123,14 +146,24 @@ class PluginInstance : public base::RefCounted<PluginInstance> { bool PrintPage(int page_number, WebKit::WebCanvas* canvas); void PrintEnd(); + void Graphics3DContextLost(); + + // Implementation of PPB_Fullscreen_Dev. + bool IsFullscreen(); + bool SetFullscreen(bool fullscreen); + private: bool LoadFindInterface(); bool LoadZoomInterface(); + // Determines if we think the plugin has focus, both content area and webkit + // (see has_webkit_focus_ below). + bool PluginHasFocus() const; + // Queries the plugin for supported print formats and sets |format| to the // best format to use. Returns false if the plugin does not support any // print format that we can handle (we can handle raster and PDF). - bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat* format); + bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat_Dev* format); bool PrintPDFOutput(PP_Resource print_output, WebKit::WebCanvas* canvas); bool PrintRasterOutput(PP_Resource print_output, WebKit::WebCanvas* canvas); #if defined(OS_WIN) @@ -165,24 +198,31 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // be (0, 0, w, h) regardless of scroll position. gfx::Rect clip_; + // We track two types of focus, one from WebKit, which is the focus among + // all elements of the page, one one from the browser, which is whether the + // tab/window has focus. We tell the plugin it has focus only when both of + // these values are set to true. + bool has_webkit_focus_; + bool has_content_area_focus_; + // The current device context for painting in 2D. - scoped_refptr<DeviceContext2D> device_context_2d_; + scoped_refptr<Graphics2D> bound_graphics_2d_; // The id of the current find operation, or -1 if none is in process. int find_identifier_; // The plugin find and zoom interfaces. - const PPP_Find* plugin_find_interface_; - const PPP_Zoom* plugin_zoom_interface_; + const PPP_Find_Dev* plugin_find_interface_; + const PPP_Zoom_Dev* plugin_zoom_interface_; // This is only valid between a successful PrintBegin call and a PrintEnd // call. - PP_PrintSettings current_print_settings_; + PP_PrintSettings_Dev current_print_settings_; #if defined(OS_MACOSX) // On the Mac, when we draw the bitmap to the PDFContext, it seems necessary // to keep the pixels valid until CGContextEndPage is called. We use this // variable to hold on to the pixels. - SkBitmap last_printed_page_; + scoped_refptr<ImageData> last_printed_page_; #elif defined(OS_LINUX) // On Linux, we always send all pages from the renderer to the browser. // So, if the plugin supports printPagesAsPDF we print the entire output @@ -197,11 +237,21 @@ class PluginInstance : public base::RefCounted<PluginInstance> { #endif // defined(OS_LINUX) // The plugin print interface. - const PPP_Printing* plugin_print_interface_; + const PPP_Printing_Dev* plugin_print_interface_; + + // The plugin 3D interface. + const PPP_Graphics3D_Dev* plugin_graphics_3d_interface_; // Containes the cursor if it's set by the plugin. scoped_ptr<WebKit::WebCursorInfo> cursor_; + // Set to true if this plugin thinks it will always be on top. This allows us + // to use a more optimized painting path in some cases. + bool always_on_top_; + + // Plugin container for fullscreen mode. NULL if not in fullscreen mode. + FullscreenContainer* fullscreen_container_; + DISALLOW_COPY_AND_ASSIGN(PluginInstance); }; diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index 8ffd78b..251023f 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -12,46 +12,71 @@ #include "base/logging.h" #include "base/scoped_ptr.h" #include "base/time.h" -#include "third_party/ppapi/c/ppb_buffer.h" +#include "third_party/ppapi/c/dev/ppb_buffer_dev.h" +#include "third_party/ppapi/c/dev/ppb_char_set_dev.h" +#include "third_party/ppapi/c/dev/ppb_cursor_control_dev.h" +#include "third_party/ppapi/c/dev/ppb_directory_reader_dev.h" +#include "third_party/ppapi/c/dev/ppb_file_io_dev.h" +#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h" +#include "third_party/ppapi/c/dev/ppb_file_system_dev.h" +#include "third_party/ppapi/c/dev/ppb_find_dev.h" +#include "third_party/ppapi/c/dev/ppb_font_dev.h" +#include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h" +#include "third_party/ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "third_party/ppapi/c/dev/ppb_opengles_dev.h" +#include "third_party/ppapi/c/dev/ppb_scrollbar_dev.h" +#include "third_party/ppapi/c/dev/ppb_testing_dev.h" +#include "third_party/ppapi/c/dev/ppb_transport_dev.h" +#include "third_party/ppapi/c/dev/ppb_url_loader_dev.h" +#include "third_party/ppapi/c/dev/ppb_url_loader_trusted_dev.h" +#include "third_party/ppapi/c/dev/ppb_url_request_info_dev.h" +#include "third_party/ppapi/c/dev/ppb_url_response_info_dev.h" +#include "third_party/ppapi/c/dev/ppb_url_util_dev.h" +#include "third_party/ppapi/c/dev/ppb_video_decoder_dev.h" +#include "third_party/ppapi/c/dev/ppb_widget_dev.h" +#include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h" +#include "third_party/ppapi/c/pp_module.h" +#include "third_party/ppapi/c/pp_resource.h" +#include "third_party/ppapi/c/pp_var.h" #include "third_party/ppapi/c/ppb_core.h" -#include "third_party/ppapi/c/ppb_device_context_2d.h" -#include "third_party/ppapi/c/ppb_file_io.h" -#include "third_party/ppapi/c/ppb_file_io_trusted.h" -#include "third_party/ppapi/c/ppb_file_system.h" +#include "third_party/ppapi/c/ppb_graphics_2d.h" #include "third_party/ppapi/c/ppb_image_data.h" #include "third_party/ppapi/c/ppb_instance.h" -#include "third_party/ppapi/c/ppb_find.h" -#include "third_party/ppapi/c/ppb_font.h" -#include "third_party/ppapi/c/ppb_scrollbar.h" -#include "third_party/ppapi/c/ppb_testing.h" -#include "third_party/ppapi/c/ppb_url_loader.h" -#include "third_party/ppapi/c/ppb_url_request_info.h" -#include "third_party/ppapi/c/ppb_url_response_info.h" #include "third_party/ppapi/c/ppb_var.h" -#include "third_party/ppapi/c/ppb_widget.h" #include "third_party/ppapi/c/ppp.h" #include "third_party/ppapi/c/ppp_instance.h" -#include "third_party/ppapi/c/pp_module.h" -#include "third_party/ppapi/c/pp_resource.h" -#include "third_party/ppapi/c/pp_var.h" +#include "webkit/glue/plugins/pepper_audio.h" #include "webkit/glue/plugins/pepper_buffer.h" -#include "webkit/glue/plugins/pepper_device_context_2d.h" +#include "webkit/glue/plugins/pepper_char_set.h" +#include "webkit/glue/plugins/pepper_cursor_control.h" #include "webkit/glue/plugins/pepper_directory_reader.h" +#include "webkit/glue/plugins/pepper_file_chooser.h" #include "webkit/glue/plugins/pepper_file_io.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_file_system.h" #include "webkit/glue/plugins/pepper_font.h" +#include "webkit/glue/plugins/pepper_graphics_2d.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/pepper_plugin_object.h" #include "webkit/glue/plugins/pepper_private.h" +#include "webkit/glue/plugins/pepper_private2.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" #include "webkit/glue/plugins/pepper_scrollbar.h" +#include "webkit/glue/plugins/pepper_transport.h" #include "webkit/glue/plugins/pepper_url_loader.h" #include "webkit/glue/plugins/pepper_url_request_info.h" #include "webkit/glue/plugins/pepper_url_response_info.h" +#include "webkit/glue/plugins/pepper_url_util.h" #include "webkit/glue/plugins/pepper_var.h" +#include "webkit/glue/plugins/pepper_video_decoder.h" #include "webkit/glue/plugins/pepper_widget.h" #include "webkit/glue/plugins/ppb_private.h" +#include "webkit/glue/plugins/ppb_private2.h" + +#ifdef ENABLE_GPU +#include "webkit/glue/plugins/pepper_graphics_3d.h" +#endif // ENABLE_GPU namespace pepper { @@ -107,13 +132,18 @@ void CallOnMainThread(int delay_in_msec, delay_in_msec); } +bool IsMainThread() { + return GetMainThreadMessageLoop()->BelongsToCurrentThread(); +} + const PPB_Core core_interface = { &AddRefResource, &ReleaseResource, &MemAlloc, &MemFree, &GetTime, - &CallOnMainThread + &CallOnMainThread, + &IsMainThread }; // PPB_Testing ----------------------------------------------------------------- @@ -121,8 +151,8 @@ const PPB_Core core_interface = { bool ReadImageData(PP_Resource device_context_2d, PP_Resource image, const PP_Point* top_left) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(device_context_2d)); + scoped_refptr<Graphics2D> context( + Resource::GetAs<Graphics2D>(device_context_2d)); if (!context.get()) return false; return context->ReadImageData(image, top_left); @@ -136,13 +166,37 @@ void RunMessageLoop() { } void QuitMessageLoop() { - MessageLoop::current()->Quit(); + MessageLoop::current()->QuitNow(); +} + +uint32_t GetLiveObjectCount(PP_Module module_id) { + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return static_cast<uint32_t>(-1); + return ResourceTracker::Get()->GetLiveObjectsForModule(module); +} + +PP_Resource GetInaccessibleFileRef(PP_Module module_id) { + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return static_cast<uint32_t>(-1); + return FileRef::GetInaccessibleFileRef(module)->GetReference(); +} + +PP_Resource GetNonexistentFileRef(PP_Module module_id) { + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return static_cast<uint32_t>(-1); + return FileRef::GetNonexistentFileRef(module)->GetReference(); } -const PPB_Testing testing_interface = { +const PPB_Testing_Dev testing_interface = { &ReadImageData, &RunMessageLoop, &QuitMessageLoop, + &GetLiveObjectCount, + &GetInaccessibleFileRef, + &GetNonexistentFileRef }; // GetInterface ---------------------------------------------------------------- @@ -151,46 +205,78 @@ const void* GetInterface(const char* name) { if (strcmp(name, PPB_CORE_INTERFACE) == 0) return &core_interface; if (strcmp(name, PPB_VAR_INTERFACE) == 0) - return GetVarInterface(); + return Var::GetInterface(); if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0) return PluginInstance::GetInterface(); if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0) return ImageData::GetInterface(); - if (strcmp(name, PPB_DEVICECONTEXT2D_INTERFACE) == 0) - return DeviceContext2D::GetInterface(); - if (strcmp(name, PPB_URLLOADER_INTERFACE) == 0) + if (strcmp(name, PPB_IMAGEDATA_TRUSTED_INTERFACE) == 0) + return ImageData::GetTrustedInterface(); + if (strcmp(name, PPB_AUDIO_CONFIG_DEV_INTERFACE) == 0) + return AudioConfig::GetInterface(); + if (strcmp(name, PPB_AUDIO_DEV_INTERFACE) == 0) + return Audio::GetInterface(); + if (strcmp(name, PPB_AUDIO_TRUSTED_DEV_INTERFACE) == 0) + return Audio::GetTrustedInterface(); + if (strcmp(name, PPB_GRAPHICS_2D_INTERFACE) == 0) + return Graphics2D::GetInterface(); +#ifdef ENABLE_GPU + if (strcmp(name, PPB_GRAPHICS_3D_DEV_INTERFACE) == 0) + return Graphics3D::GetInterface(); + if (strcmp(name, PPB_OPENGLES_DEV_INTERFACE) == 0) + return Graphics3D::GetOpenGLESInterface(); +#endif // ENABLE_GPU + if (strcmp(name, PPB_TRANSPORT_DEV_INTERFACE) == 0) + return Transport::GetInterface(); + if (strcmp(name, PPB_URLLOADER_DEV_INTERFACE) == 0) return URLLoader::GetInterface(); - if (strcmp(name, PPB_URLREQUESTINFO_INTERFACE) == 0) + if (strcmp(name, PPB_URLLOADERTRUSTED_DEV_INTERFACE) == 0) + return URLLoader::GetTrustedInterface(); + if (strcmp(name, PPB_URLREQUESTINFO_DEV_INTERFACE) == 0) return URLRequestInfo::GetInterface(); - if (strcmp(name, PPB_URLRESPONSEINFO_INTERFACE) == 0) + if (strcmp(name, PPB_URLRESPONSEINFO_DEV_INTERFACE) == 0) return URLResponseInfo::GetInterface(); - if (strcmp(name, PPB_BUFFER_INTERFACE) == 0) + if (strcmp(name, PPB_BUFFER_DEV_INTERFACE) == 0) return Buffer::GetInterface(); - if (strcmp(name, PPB_FILEREF_INTERFACE) == 0) + if (strcmp(name, PPB_FILEREF_DEV_INTERFACE) == 0) return FileRef::GetInterface(); - if (strcmp(name, PPB_FILEIO_INTERFACE) == 0) + if (strcmp(name, PPB_FILEIO_DEV_INTERFACE) == 0) return FileIO::GetInterface(); - if (strcmp(name, PPB_FILEIOTRUSTED_INTERFACE) == 0) + if (strcmp(name, PPB_FILEIOTRUSTED_DEV_INTERFACE) == 0) return FileIO::GetTrustedInterface(); - if (strcmp(name, PPB_FILESYSTEM_INTERFACE) == 0) + if (strcmp(name, PPB_FILESYSTEM_DEV_INTERFACE) == 0) return FileSystem::GetInterface(); - if (strcmp(name, PPB_DIRECTORYREADER_INTERFACE) == 0) + if (strcmp(name, PPB_DIRECTORYREADER_DEV_INTERFACE) == 0) return DirectoryReader::GetInterface(); - if (strcmp(name, PPB_WIDGET_INTERFACE) == 0) + if (strcmp(name, PPB_WIDGET_DEV_INTERFACE) == 0) return Widget::GetInterface(); - if (strcmp(name, PPB_SCROLLBAR_INTERFACE) == 0) + if (strcmp(name, PPB_SCROLLBAR_DEV_INTERFACE) == 0) return Scrollbar::GetInterface(); - if (strcmp(name, PPB_FONT_INTERFACE) == 0) + if (strcmp(name, PPB_FONT_DEV_INTERFACE) == 0) return Font::GetInterface(); - if (strcmp(name, PPB_FIND_INTERFACE) == 0) + if (strcmp(name, PPB_FIND_DEV_INTERFACE) == 0) return PluginInstance::GetFindInterface(); + if (strcmp(name, PPB_FULLSCREEN_DEV_INTERFACE) == 0) + return PluginInstance::GetFullscreenInterface(); + if (strcmp(name, PPB_URLUTIL_DEV_INTERFACE) == 0) + return UrlUtil::GetInterface(); if (strcmp(name, PPB_PRIVATE_INTERFACE) == 0) return Private::GetInterface(); + if (strcmp(name, PPB_PRIVATE2_INTERFACE) == 0) + return Private2::GetInterface(); + if (strcmp(name, PPB_FILECHOOSER_DEV_INTERFACE) == 0) + return FileChooser::GetInterface(); + if (strcmp(name, PPB_VIDEODECODER_DEV_INTERFACE) == 0) + return VideoDecoder::GetInterface(); + if (strcmp(name, PPB_CHAR_SET_DEV_INTERFACE) == 0) + return CharSet::GetInterface(); + if (strcmp(name, PPB_CURSOR_CONTROL_DEV_INTERFACE) == 0) + return GetCursorControlInterface(); // Only support the testing interface when the command line switch is // specified. This allows us to prevent people from (ab)using this interface // in production code. - if (strcmp(name, PPB_TESTING_INTERFACE) == 0) { + if (strcmp(name, PPB_TESTING_DEV_INTERFACE) == 0) { if (CommandLine::ForCurrentProcess()->HasSwitch("enable-pepper-testing")) return &testing_interface; } @@ -207,6 +293,17 @@ PluginModule::PluginModule() } PluginModule::~PluginModule() { + // Free all the plugin objects. This will automatically clear the back- + // pointer from the NPObject so WebKit can't call into the plugin any more. + // + // Swap out the set so we can delete from it (the objects will try to + // unregister themselves inside the delete call). + PluginObjectSet plugin_object_copy; + live_plugin_objects_.swap(plugin_object_copy); + for (PluginObjectSet::iterator i = live_plugin_objects_.begin(); + i != live_plugin_objects_.end(); ++i) + delete *i; + // When the module is being deleted, there should be no more instances still // holding a reference to us. DCHECK(instances_.empty()); @@ -359,4 +456,44 @@ void PluginModule::InstanceDeleted(PluginInstance* instance) { instances_.erase(instance); } +void PluginModule::AddNPObjectVar(ObjectVar* object_var) { + DCHECK(np_object_to_object_var_.find(object_var->np_object()) == + np_object_to_object_var_.end()) << "ObjectVar already in map"; + np_object_to_object_var_[object_var->np_object()] = object_var; +} + +void PluginModule::RemoveNPObjectVar(ObjectVar* object_var) { + NPObjectToObjectVarMap::iterator found = + np_object_to_object_var_.find(object_var->np_object()); + if (found == np_object_to_object_var_.end()) { + NOTREACHED() << "ObjectVar not registered."; + return; + } + if (found->second != object_var) { + NOTREACHED() << "ObjectVar doesn't match."; + return; + } + np_object_to_object_var_.erase(found); +} + +ObjectVar* PluginModule::ObjectVarForNPObject(NPObject* np_object) const { + NPObjectToObjectVarMap::const_iterator found = + np_object_to_object_var_.find(np_object); + if (found == np_object_to_object_var_.end()) + return NULL; + return found->second; +} + +void PluginModule::AddPluginObject(PluginObject* plugin_object) { + DCHECK(live_plugin_objects_.find(plugin_object) == + live_plugin_objects_.end()); + live_plugin_objects_.insert(plugin_object); +} + +void PluginModule::RemovePluginObject(PluginObject* plugin_object) { + // Don't actually verify that the object is in the set since during module + // deletion we'll be in the process of freeing them. + live_plugin_objects_.erase(plugin_object); +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h index 6bfeccf..a560c56 100644 --- a/webkit/glue/plugins/pepper_plugin_module.h +++ b/webkit/glue/plugins/pepper_plugin_module.h @@ -5,23 +5,30 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_ +#include <map> #include <set> #include "base/basictypes.h" -#include "base/file_path.h" #include "base/native_library.h" #include "base/ref_counted.h" +#include "base/weak_ptr.h" #include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/ppb.h" -typedef struct _ppb_Core PPB_Core; +class FilePath; +typedef struct NPObject NPObject; +struct PPB_Core; +typedef void* NPIdentifier; namespace pepper { +class ObjectVar; class PluginDelegate; class PluginInstance; +class PluginObject; -class PluginModule : public base::RefCounted<PluginModule> { +class PluginModule : public base::RefCounted<PluginModule>, + public base::SupportsWeakPtr<PluginModule> { public: typedef const void* (*PPP_GetInterfaceFunc)(const char*); typedef int (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface); @@ -69,6 +76,22 @@ class PluginModule : public base::RefCounted<PluginModule> { void InstanceCreated(PluginInstance* instance); void InstanceDeleted(PluginInstance* instance); + // Tracks all live ObjectVar. This is so we can map between PluginModule + + // NPObject and get the ObjectVar corresponding to it. This Add/Remove + // function should be called by the ObjectVar when it is created and + // destroyed. + void AddNPObjectVar(ObjectVar* object_var); + void RemoveNPObjectVar(ObjectVar* object_var); + + // Looks up a previously registered ObjectVar for the given NPObject and + // module. Returns NULL if there is no ObjectVar corresponding to the given + // NPObject for the given module. See AddNPObjectVar above. + ObjectVar* ObjectVarForNPObject(NPObject* np_object) const; + + // Tracks all live PluginObjects. + void AddPluginObject(PluginObject* plugin_object); + void RemovePluginObject(PluginObject* plugin_object); + private: PluginModule(); @@ -94,6 +117,14 @@ class PluginModule : public base::RefCounted<PluginModule> { typedef std::set<PluginInstance*> PluginInstanceSet; PluginInstanceSet instances_; + // Tracks all live ObjectVars used by this module so we can map NPObjects to + // the corresponding object. These are non-owning references. + typedef std::map<NPObject*, ObjectVar*> NPObjectToObjectVarMap;; + NPObjectToObjectVarMap np_object_to_object_var_; + + typedef std::set<PluginObject*> PluginObjectSet; + PluginObjectSet live_plugin_objects_; + DISALLOW_COPY_AND_ASSIGN(PluginModule); }; diff --git a/webkit/glue/plugins/pepper_private.cc b/webkit/glue/plugins/pepper_private.cc index 8d5182f..e35006b 100644 --- a/webkit/glue/plugins/pepper_private.cc +++ b/webkit/glue/plugins/pepper_private.cc @@ -6,26 +6,167 @@ #include "webkit/glue/plugins/pepper_private.h" +#include "app/resource_bundle.h" #include "base/utf_string_conversions.h" +#include "grit/webkit_resources.h" #include "grit/webkit_strings.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "webkit/glue/webkit_glue.h" +#include "webkit/glue/plugins/pepper_image_data.h" +#include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_var.h" #include "webkit/glue/plugins/ppb_private.h" namespace pepper { +#if defined(OS_LINUX) +class PrivateFontFile : public Resource { + public: + PrivateFontFile(PluginModule* module, int fd) : Resource(module), fd_(fd) {} + virtual ~PrivateFontFile() {} + + // Resource overrides. + PrivateFontFile* AsPrivateFontFile() { return this; } + + bool GetFontTable(uint32_t table, + void* output, + uint32_t* output_length); + + private: + int fd_; +}; +#endif + namespace { -PP_Var GetLocalizedString(PP_ResourceString string_id) { +struct ResourceImageInfo { + PP_ResourceImage pp_id; + int res_id; +}; + +static const ResourceImageInfo kResourceImageMap[] = { + { PP_RESOURCEIMAGE_PDF_BUTTON_FTH, IDR_PDF_BUTTON_FTH }, + { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_HOVER, IDR_PDF_BUTTON_FTH_HOVER }, + { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_PRESSED, IDR_PDF_BUTTON_FTH_PRESSED }, + { PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW }, + { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER }, + { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED }, + { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN }, + { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER }, + { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED }, + { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT }, + { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER }, + { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED, + IDR_PDF_BUTTON_ZOOMOUT_PRESSED }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9 }, + { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND, + IDR_PDF_THUMBNAIL_NUM_BACKGROUND }, +}; + +PP_Var GetLocalizedString(PP_Module module_id, PP_ResourceString string_id) { + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return PP_MakeVoid(); + std::string rv; if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_NEED_PASSWORD)); - return StringToPPVar(rv); + return StringVar::StringToPPVar(module, rv); +} + +PP_Resource GetResourceImage(PP_Module module_id, PP_ResourceImage image_id) { + int res_id = 0; + for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) { + if (kResourceImageMap[i].pp_id == image_id) { + res_id = kResourceImageMap[i].res_id; + break; + } + } + if (res_id == 0) + return 0; + + SkBitmap* res_bitmap = + ResourceBundle::GetSharedInstance().GetBitmapNamed(res_id); + + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return 0; + scoped_refptr<pepper::ImageData> image_data(new pepper::ImageData(module)); + if (!image_data->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, + res_bitmap->width(), res_bitmap->height(), false)) { + return 0; + } + + ImageDataAutoMapper mapper(image_data); + if (!mapper.is_valid()) + return 0; + + skia::PlatformCanvas* canvas = image_data->mapped_canvas(); + SkBitmap& ret_bitmap = + const_cast<SkBitmap&>(canvas->getTopPlatformDevice().accessBitmap(true)); + if (!res_bitmap->copyTo(&ret_bitmap, SkBitmap::kARGB_8888_Config, NULL)) { + return 0; + } + + return image_data->GetReference(); +} + +PP_Resource GetFontFileWithFallback( + PP_Module module_id, + const PP_PrivateFontFileDescription* description) { +#if defined(OS_LINUX) + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return 0; + + int fd = webkit_glue::MatchFontWithFallback(description->face, + description->weight >= 700, + description->italic, + description->charset); + if (fd == -1) + return 0; + + scoped_refptr<PrivateFontFile> font(new PrivateFontFile(module, fd)); + + return font->GetReference(); +#else + // For trusted pepper plugins, this is only needed in Linux since font loading + // on Windows and Mac works through the renderer sandbox. + return 0; +#endif +} + +bool GetFontTableForPrivateFontFile(PP_Resource font_file, + uint32_t table, + void* output, + uint32_t* output_length) { +#if defined(OS_LINUX) + scoped_refptr<PrivateFontFile> font( + Resource::GetAs<PrivateFontFile>(font_file)); + if (!font.get()) + return false; + return font->GetFontTable(table, output, output_length); +#else + return false; +#endif } const PPB_Private ppb_private = { &GetLocalizedString, + &GetResourceImage, + &GetFontFileWithFallback, + &GetFontTableForPrivateFontFile, }; } // namespace @@ -35,4 +176,16 @@ const PPB_Private* Private::GetInterface() { return &ppb_private; } +#if defined(OS_LINUX) +bool PrivateFontFile::GetFontTable(uint32_t table, + void* output, + uint32_t* output_length) { + size_t temp_size = static_cast<size_t>(*output_length); + bool rv = webkit_glue::GetFontTable( + fd_, table, static_cast<uint8_t*>(output), &temp_size); + *output_length = static_cast<uint32_t>(temp_size); + return rv; +} +#endif + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_private.h b/webkit/glue/plugins/pepper_private.h index fda75a7..06016f0 100644 --- a/webkit/glue/plugins/pepper_private.h +++ b/webkit/glue/plugins/pepper_private.h @@ -7,7 +7,7 @@ #include "webkit/glue/plugins/pepper_resource.h" -typedef struct _ppb_Private PPB_Private; +struct PPB_Private; namespace pepper { diff --git a/webkit/glue/plugins/pepper_resource.cc b/webkit/glue/plugins/pepper_resource.cc index c568183..cf7a7fe 100644 --- a/webkit/glue/plugins/pepper_resource.cc +++ b/webkit/glue/plugins/pepper_resource.cc @@ -4,10 +4,18 @@ #include "webkit/glue/plugins/pepper_resource.h" +#include "base/logging.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { +Resource::Resource(PluginModule* module) + : resource_id_(0), module_(module) { +} + +Resource::~Resource() { +} + PP_Resource Resource::GetReference() { ResourceTracker *tracker = ResourceTracker::Get(); if (resource_id_) @@ -16,4 +24,10 @@ PP_Resource Resource::GetReference() { resource_id_ = tracker->AddResource(this); return resource_id_; } + +void Resource::StoppedTracking() { + DCHECK(resource_id_ != 0); + resource_id_ = 0; +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h index 417a06b..cab6f32 100644 --- a/webkit/glue/plugins/pepper_resource.h +++ b/webkit/glue/plugins/pepper_resource.h @@ -5,7 +5,6 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_ -#include "base/logging.h" #include "base/basictypes.h" #include "base/ref_counted.h" #include "third_party/ppapi/c/pp_resource.h" @@ -14,24 +13,33 @@ namespace pepper { class Buffer; -class DeviceContext2D; +class Audio; +class AudioConfig; class DirectoryReader; class FileChooser; class FileIO; class FileRef; class Font; +class Graphics2D; +class Graphics3D; class ImageData; +class ObjectVar; class PluginModule; +class PrivateFontFile; class Scrollbar; +class StringVar; +class Transport; class URLLoader; class URLRequestInfo; class URLResponseInfo; +class Var; +class VideoDecoder; class Widget; class Resource : public base::RefCountedThreadSafe<Resource> { public: - explicit Resource(PluginModule* module) : resource_id_(0), module_(module) {} - virtual ~Resource() {} + explicit Resource(PluginModule* module); + virtual ~Resource(); // Returns NULL if the resource is invalid or is a different type. template<typename T> @@ -72,18 +80,27 @@ class Resource : public base::RefCountedThreadSafe<Resource> { // Type-specific getters for individual resource types. These will return // NULL if the resource does not match the specified type. Used by the Cast() // function. + virtual Audio* AsAudio() { return NULL; } + virtual AudioConfig* AsAudioConfig() { return NULL; } virtual Buffer* AsBuffer() { return NULL; } - virtual DeviceContext2D* AsDeviceContext2D() { return NULL; } virtual DirectoryReader* AsDirectoryReader() { return NULL; } virtual FileChooser* AsFileChooser() { return NULL; } virtual FileIO* AsFileIO() { return NULL; } virtual FileRef* AsFileRef() { return NULL; } virtual Font* AsFont() { return NULL; } + virtual Graphics2D* AsGraphics2D() { return NULL; } + virtual Graphics3D* AsGraphics3D() { return NULL; } virtual ImageData* AsImageData() { return NULL; } + virtual ObjectVar* AsObjectVar() { return NULL; } + virtual PrivateFontFile* AsPrivateFontFile() { return NULL; } virtual Scrollbar* AsScrollbar() { return NULL; } + virtual StringVar* AsStringVar() { return NULL; } + virtual Transport* AsTransport() { return NULL; } virtual URLLoader* AsURLLoader() { return NULL; } virtual URLRequestInfo* AsURLRequestInfo() { return NULL; } virtual URLResponseInfo* AsURLResponseInfo() { return NULL; } + virtual Var* AsVar() { return NULL; } + virtual VideoDecoder* AsVideoDecoder() { return NULL; } virtual Widget* AsWidget() { return NULL; } private: @@ -101,10 +118,7 @@ class Resource : public base::RefCountedThreadSafe<Resource> { // Called by the resource tracker when the last plugin reference has been // dropped. friend class ResourceTracker; - void StoppedTracking() { - DCHECK(resource_id_ != 0); - resource_id_ = 0; - } + void StoppedTracking(); DISALLOW_COPY_AND_ASSIGN(Resource); }; @@ -115,18 +129,27 @@ class Resource : public base::RefCountedThreadSafe<Resource> { return As##Type(); \ } +DEFINE_RESOURCE_CAST(Audio) +DEFINE_RESOURCE_CAST(AudioConfig) DEFINE_RESOURCE_CAST(Buffer) -DEFINE_RESOURCE_CAST(DeviceContext2D) DEFINE_RESOURCE_CAST(DirectoryReader) DEFINE_RESOURCE_CAST(FileChooser) DEFINE_RESOURCE_CAST(FileIO) DEFINE_RESOURCE_CAST(FileRef) DEFINE_RESOURCE_CAST(Font) +DEFINE_RESOURCE_CAST(Graphics2D) +DEFINE_RESOURCE_CAST(Graphics3D) DEFINE_RESOURCE_CAST(ImageData) +DEFINE_RESOURCE_CAST(ObjectVar) +DEFINE_RESOURCE_CAST(PrivateFontFile) DEFINE_RESOURCE_CAST(Scrollbar) +DEFINE_RESOURCE_CAST(StringVar); +DEFINE_RESOURCE_CAST(Transport) DEFINE_RESOURCE_CAST(URLLoader) DEFINE_RESOURCE_CAST(URLRequestInfo) DEFINE_RESOURCE_CAST(URLResponseInfo) +DEFINE_RESOURCE_CAST(Var) +DEFINE_RESOURCE_CAST(VideoDecoder) DEFINE_RESOURCE_CAST(Widget) #undef DEFINE_RESOURCE_CAST diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc index 8aa94d2..9ee54f8 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.cc +++ b/webkit/glue/plugins/pepper_resource_tracker.cc @@ -21,6 +21,13 @@ scoped_refptr<Resource> ResourceTracker::GetResource(PP_Resource res) const { return result->second.first; } +ResourceTracker::ResourceTracker() + : last_id_(0) { +} + +ResourceTracker::~ResourceTracker() { +} + PP_Resource ResourceTracker::AddResource(Resource* resource) { // If the plugin manages to create 4B resources... if (last_id_ == std::numeric_limits<PP_Resource>::max()) { @@ -58,4 +65,18 @@ bool ResourceTracker::UnrefResource(PP_Resource res) { } } +uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const { + // Since this is for testing only, we'll just go through all of them and + // count. + // + // TODO(brettw) we will eventually need to implement more efficient + // module->resource lookup to free resources when a module is unloaded. In + // this case, this function can be implemented using that system. + uint32 count = 0; + for (ResourceMap::const_iterator i = live_resources_.begin(); + i != live_resources_.end(); ++i) + count++; + return count; +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h index d06c9ba..59f02d2 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.h +++ b/webkit/glue/plugins/pepper_resource_tracker.h @@ -5,17 +5,19 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ -#include <set> +#include <utility> -#include "base/atomic_sequence_num.h" #include "base/basictypes.h" #include "base/hash_tables.h" #include "base/ref_counted.h" #include "base/singleton.h" #include "third_party/ppapi/c/pp_resource.h" +typedef struct NPObject NPObject; + namespace pepper { +class PluginModule; class Resource; // This class maintains a global list of all live pepper resources. It allows @@ -41,13 +43,18 @@ class ResourceTracker { bool AddRefResource(PP_Resource res); bool UnrefResource(PP_Resource res); + // Returns the number of resources associated with this module. + // + // This is slow, use only for testing. + uint32 GetLiveObjectsForModule(PluginModule* module) const; + private: friend struct DefaultSingletonTraits<ResourceTracker>; friend class Resource; // Prohibit creation other then by the Singleton class. - ResourceTracker() : last_id_(0) {} - ~ResourceTracker() {} + ResourceTracker(); + ~ResourceTracker(); // Adds the given resource to the tracker and assigns it a resource ID and // refcount of 1. The assigned resource ID will be returned. Used only by the diff --git a/webkit/glue/plugins/pepper_scrollbar.cc b/webkit/glue/plugins/pepper_scrollbar.cc index 48db8d4..a8943d2 100644 --- a/webkit/glue/plugins/pepper_scrollbar.cc +++ b/webkit/glue/plugins/pepper_scrollbar.cc @@ -6,7 +6,8 @@ #include "base/logging.h" #include "base/message_loop.h" -#include "third_party/ppapi/c/ppp_scrollbar.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/ppapi/c/dev/ppp_scrollbar_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebScrollbar.h" @@ -17,6 +18,10 @@ #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/webkit_glue.h" +#if defined(OS_WIN) +#include "base/win_util.h" +#endif + using WebKit::WebInputEvent; using WebKit::WebRect; using WebKit::WebScrollbar; @@ -28,7 +33,7 @@ namespace { PP_Resource Create(PP_Instance instance_id, bool vertical) { PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); if (!instance) - return NULL; + return 0; scoped_refptr<Scrollbar> scrollbar(new Scrollbar(instance, vertical)); return scrollbar->GetReference(); @@ -69,15 +74,13 @@ void SetTickMarks(PP_Resource resource, scrollbar->SetTickMarks(tick_marks, count); } -void ScrollBy(PP_Resource resource, - PP_ScrollBy unit, - int32_t multiplier) { +void ScrollBy(PP_Resource resource, PP_ScrollBy_Dev unit, int32_t multiplier) { scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); if (scrollbar) scrollbar->ScrollBy(unit, multiplier); } -const PPB_Scrollbar ppb_scrollbar = { +const PPB_Scrollbar_Dev ppb_scrollbar = { &Create, &IsScrollbar, &GetThickness, @@ -101,7 +104,7 @@ Scrollbar::~Scrollbar() { } // static -const PPB_Scrollbar* Scrollbar::GetInterface() { +const PPB_Scrollbar_Dev* Scrollbar::GetInterface() { return &ppb_scrollbar; } @@ -129,7 +132,7 @@ void Scrollbar::SetTickMarks(const PP_Rect* tick_marks, uint32_t count) { Invalidate(&rect); } -void Scrollbar::ScrollBy(PP_ScrollBy unit, int32_t multiplier) { +void Scrollbar::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) { WebScrollbar::ScrollDirection direction = multiplier >= 0 ? WebScrollbar::ScrollForward : WebScrollbar::ScrollBackward; float fmultiplier = 1.0; @@ -159,10 +162,18 @@ bool Scrollbar::Paint(const PP_Rect* rect, ImageData* image) { if (!canvas) return false; scrollbar_->paint(webkit_glue::ToWebCanvas(canvas), gfx_rect); + +#if defined(OS_WIN) + if (win_util::GetWinVersion() == win_util::WINVERSION_XP) { + canvas->getTopPlatformDevice().makeOpaque( + gfx_rect.x(), gfx_rect.y(), gfx_rect.width(), gfx_rect.height()); + } +#endif + return true; } -bool Scrollbar::HandleEvent(const PP_Event* event) { +bool Scrollbar::HandleEvent(const PP_InputEvent* event) { scoped_ptr<WebInputEvent> web_input_event(CreateWebInputEvent(*event)); if (!web_input_event.get()) return false; @@ -178,8 +189,9 @@ void Scrollbar::SetLocationInternal(const PP_Rect* location) { } void Scrollbar::valueChanged(WebKit::WebScrollbar* scrollbar) { - const PPP_Scrollbar* ppp_scrollbar = static_cast<const PPP_Scrollbar*>( - module()->GetPluginInterface(PPP_SCROLLBAR_INTERFACE)); + const PPP_Scrollbar_Dev* ppp_scrollbar = + static_cast<const PPP_Scrollbar_Dev*>( + module()->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE)); if (!ppp_scrollbar) return; ScopedResourceId resource(this); diff --git a/webkit/glue/plugins/pepper_scrollbar.h b/webkit/glue/plugins/pepper_scrollbar.h index bf25136..e8ac480 100644 --- a/webkit/glue/plugins/pepper_scrollbar.h +++ b/webkit/glue/plugins/pepper_scrollbar.h @@ -8,13 +8,11 @@ #include <vector> #include "gfx/rect.h" -#include "third_party/ppapi/c/ppb_scrollbar.h" +#include "third_party/ppapi/c/dev/ppb_scrollbar_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebScrollbarClient.h" #include "webkit/glue/plugins/pepper_widget.h" -typedef struct _ppb_Scrollbar PPB_Scrollbar; - namespace pepper { class PluginInstance; @@ -26,7 +24,7 @@ class Scrollbar : public Widget, public WebKit::WebScrollbarClient { // Returns a pointer to the interface implementing PPB_Scrollbar that is // exposed to the plugin. - static const PPB_Scrollbar* GetInterface(); + static const PPB_Scrollbar_Dev* GetInterface(); // Resource overrides. Scrollbar* AsScrollbar() { return this; } @@ -36,11 +34,11 @@ class Scrollbar : public Widget, public WebKit::WebScrollbarClient { void SetValue(uint32_t value); void SetDocumentSize(uint32_t size); void SetTickMarks(const PP_Rect* tick_marks, uint32_t count); - void ScrollBy(PP_ScrollBy unit, int32_t multiplier); + void ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier); // PPB_Widget implementation. virtual bool Paint(const PP_Rect* rect, ImageData* image); - virtual bool HandleEvent(const PP_Event* event); + virtual bool HandleEvent(const PP_InputEvent* event); virtual void SetLocationInternal(const PP_Rect* location); private: diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc index aa09686..4169c00 100644 --- a/webkit/glue/plugins/pepper_url_loader.cc +++ b/webkit/glue/plugins/pepper_url_loader.cc @@ -7,14 +7,17 @@ #include "base/logging.h" #include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/ppb_url_loader.h" +#include "third_party/ppapi/c/dev/ppb_url_loader_dev.h" +#include "third_party/ppapi/c/dev/ppb_url_loader_trusted_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebKit.h" #include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_url_request_info.h" #include "webkit/glue/plugins/pepper_url_response_info.h" @@ -121,6 +124,15 @@ int32_t ReadResponseBody(PP_Resource loader_id, return loader->ReadResponseBody(buffer, bytes_to_read, callback); } +int32_t FinishStreamingToFile(PP_Resource loader_id, + PP_CompletionCallback callback) { + scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); + if (!loader) + return PP_ERROR_BADRESOURCE; + + return loader->FinishStreamingToFile(callback); +} + void Close(PP_Resource loader_id) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); if (!loader) @@ -129,7 +141,7 @@ void Close(PP_Resource loader_id) { loader->Close(); } -const PPB_URLLoader ppb_urlloader = { +const PPB_URLLoader_Dev ppb_urlloader = { &Create, &IsURLLoader, &Open, @@ -138,9 +150,22 @@ const PPB_URLLoader ppb_urlloader = { &GetDownloadProgress, &GetResponseInfo, &ReadResponseBody, + &FinishStreamingToFile, &Close }; +void GrantUniversalAccess(PP_Resource loader_id) { + scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); + if (!loader) + return; + + loader->GrantUniversalAccess(); +} + +const PPB_URLLoaderTrusted_Dev ppb_urlloadertrusted = { + &GrantUniversalAccess +}; + } // namespace URLLoader::URLLoader(PluginInstance* instance) @@ -148,22 +173,28 @@ URLLoader::URLLoader(PluginInstance* instance) instance_(instance), pending_callback_(), bytes_sent_(0), - total_bytes_to_be_sent_(0), + total_bytes_to_be_sent_(-1), bytes_received_(0), - total_bytes_to_be_received_(0), + total_bytes_to_be_received_(-1), user_buffer_(NULL), user_buffer_size_(0), - done_(false) { + done_status_(PP_ERROR_WOULDBLOCK), + has_universal_access_(false) { } URLLoader::~URLLoader() { } // static -const PPB_URLLoader* URLLoader::GetInterface() { +const PPB_URLLoader_Dev* URLLoader::GetInterface() { return &ppb_urlloader; } +// static +const PPB_URLLoaderTrusted_Dev* URLLoader::GetTrustedInterface() { + return &ppb_urlloadertrusted; +} + int32_t URLLoader::Open(URLRequestInfo* request, PP_CompletionCallback callback) { if (loader_.get()) @@ -177,6 +208,12 @@ int32_t URLLoader::Open(URLRequestInfo* request, if (!frame) return PP_ERROR_FAILED; WebURLRequest web_request(request->ToWebURLRequest(frame)); + + // Check if we are allowed to access this URL. + if (!has_universal_access_ && + !frame->securityOrigin().canRequest(web_request.url())) + return PP_ERROR_NOACCESS; + frame->dispatchWillSendRequest(web_request); loader_.reset(WebKit::webKitClient()->createURLLoader()); @@ -199,6 +236,8 @@ int32_t URLLoader::FollowRedirect(PP_CompletionCallback callback) { int32_t URLLoader::ReadResponseBody(char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { + if (!response_info_ || response_info_->body()) + return PP_ERROR_FAILED; if (bytes_to_read <= 0 || !buffer) return PP_ERROR_BADARGUMENT; if (pending_callback_.func) @@ -214,20 +253,40 @@ int32_t URLLoader::ReadResponseBody(char* buffer, int32_t bytes_to_read, if (!buffer_.empty()) return FillUserBuffer(); - if (done_) { + // We may have already reached EOF. + if (done_status_ != PP_ERROR_WOULDBLOCK) { user_buffer_ = NULL; user_buffer_size_ = 0; - return 0; + return done_status_; } pending_callback_ = callback; return PP_ERROR_WOULDBLOCK; } +int32_t URLLoader::FinishStreamingToFile(PP_CompletionCallback callback) { + if (!response_info_ || !response_info_->body()) + return PP_ERROR_FAILED; + if (pending_callback_.func) + return PP_ERROR_INPROGRESS; + + // We may have already reached EOF. + if (done_status_ != PP_ERROR_WOULDBLOCK) + return done_status_; + + // Wait for didFinishLoading / didFail. + pending_callback_ = callback; + return PP_ERROR_WOULDBLOCK; +} + void URLLoader::Close() { NOTIMPLEMENTED(); // TODO(darin): Implement me. } +void URLLoader::GrantUniversalAccess() { + has_universal_access_ = true; +} + void URLLoader::willSendRequest(WebURLLoader* loader, WebURLRequest& new_request, const WebURLResponse& redirect_response) { @@ -248,12 +307,22 @@ void URLLoader::didReceiveResponse(WebURLLoader* loader, if (response_info->Initialize(response)) response_info_ = response_info; + // Sets -1 if the content length is unknown. + total_bytes_to_be_received_ = response.expectedContentLength(); + RunCallback(PP_OK); } +void URLLoader::didDownloadData(WebURLLoader* loader, + int data_length) { + bytes_received_ += data_length; +} + void URLLoader::didReceiveData(WebURLLoader* loader, const char* data, int data_length) { + bytes_received_ += data_length; + buffer_.insert(buffer_.end(), data, data + data_length); if (user_buffer_) { RunCallback(FillUserBuffer()); @@ -262,15 +331,15 @@ void URLLoader::didReceiveData(WebURLLoader* loader, } } -void URLLoader::didFinishLoading(WebURLLoader* loader) { - done_ = true; - RunCallback(PP_OK); +void URLLoader::didFinishLoading(WebURLLoader* loader, double finish_time) { + done_status_ = PP_OK; + RunCallback(done_status_); } void URLLoader::didFail(WebURLLoader* loader, const WebURLError& error) { - done_ = true; // TODO(darin): Provide more detailed error information. - RunCallback(PP_ERROR_FAILED); + done_status_ = PP_ERROR_FAILED; + RunCallback(done_status_); } void URLLoader::RunCallback(int32_t result) { diff --git a/webkit/glue/plugins/pepper_url_loader.h b/webkit/glue/plugins/pepper_url_loader.h index 088f220..4919de7 100644 --- a/webkit/glue/plugins/pepper_url_loader.h +++ b/webkit/glue/plugins/pepper_url_loader.h @@ -13,7 +13,8 @@ #include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h" #include "webkit/glue/plugins/pepper_resource.h" -typedef struct _ppb_URLLoader PPB_URLLoader; +struct PPB_URLLoader_Dev; +struct PPB_URLLoaderTrusted_Dev; namespace pepper { @@ -28,7 +29,11 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { // Returns a pointer to the interface implementing PPB_URLLoader that is // exposed to the plugin. - static const PPB_URLLoader* GetInterface(); + static const PPB_URLLoader_Dev* GetInterface(); + + // Returns a pointer to the interface implementing PPB_URLLoaderTrusted that + // is exposed to the plugin. + static const PPB_URLLoaderTrusted_Dev* GetTrustedInterface(); // Resource overrides. URLLoader* AsURLLoader() { return this; } @@ -38,8 +43,12 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { int32_t FollowRedirect(PP_CompletionCallback callback); int32_t ReadResponseBody(char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback); + int32_t FinishStreamingToFile(PP_CompletionCallback callback); void Close(); + // PPB_URLLoaderTrusted implementation. + void GrantUniversalAccess(); + // WebKit::WebURLLoaderClient implementation. virtual void willSendRequest(WebKit::WebURLLoader* loader, WebKit::WebURLRequest& new_request, @@ -49,10 +58,13 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { unsigned long long total_bytes_to_be_sent); virtual void didReceiveResponse(WebKit::WebURLLoader* loader, const WebKit::WebURLResponse& response); + virtual void didDownloadData(WebKit::WebURLLoader* loader, + int data_length); virtual void didReceiveData(WebKit::WebURLLoader* loader, const char* data, int data_length); - virtual void didFinishLoading(WebKit::WebURLLoader* loader); + virtual void didFinishLoading(WebKit::WebURLLoader* loader, + double finish_time); virtual void didFail(WebKit::WebURLLoader* loader, const WebKit::WebURLError& error); @@ -81,7 +93,8 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { int64_t total_bytes_to_be_received_; char* user_buffer_; size_t user_buffer_size_; - bool done_; + int32_t done_status_; + bool has_universal_access_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc index d230f20..4edbe83 100644 --- a/webkit/glue/plugins/pepper_url_request_info.cc +++ b/webkit/glue/plugins/pepper_url_request_info.cc @@ -22,7 +22,6 @@ #include "webkit/glue/webkit_glue.h" using WebKit::WebData; -using WebKit::WebFileInfo; using WebKit::WebHTTPBody; using WebKit::WebString; using WebKit::WebFrame; @@ -62,7 +61,7 @@ bool IsURLRequestInfo(PP_Resource resource) { } bool SetProperty(PP_Resource request_id, - PP_URLRequestProperty property, + PP_URLRequestProperty_Dev property, PP_Var var) { scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); @@ -72,8 +71,11 @@ bool SetProperty(PP_Resource request_id, if (var.type == PP_VARTYPE_BOOL) return request->SetBooleanProperty(property, var.value.as_bool); - if (var.type == PP_VARTYPE_STRING) - return request->SetStringProperty(property, GetString(var)->value()); + if (var.type == PP_VARTYPE_STRING) { + scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); + if (string) + return request->SetStringProperty(property, string->value()); + } return false; } @@ -84,7 +86,7 @@ bool AppendDataToBody(PP_Resource request_id, PP_Var var) { if (!request) return false; - String* data = GetString(var); + scoped_refptr<StringVar> data(StringVar::FromPPVar(var)); if (!data) return false; @@ -111,7 +113,7 @@ bool AppendFileToBody(PP_Resource request_id, expected_last_modified_time); } -const PPB_URLRequestInfo ppb_urlrequestinfo = { +const PPB_URLRequestInfo_Dev ppb_urlrequestinfo = { &Create, &IsURLRequestInfo, &SetProperty, @@ -122,24 +124,31 @@ const PPB_URLRequestInfo ppb_urlrequestinfo = { } // namespace URLRequestInfo::URLRequestInfo(PluginModule* module) - : Resource(module) { + : Resource(module), + stream_to_file_(false) { } URLRequestInfo::~URLRequestInfo() { } // static -const PPB_URLRequestInfo* URLRequestInfo::GetInterface() { +const PPB_URLRequestInfo_Dev* URLRequestInfo::GetInterface() { return &ppb_urlrequestinfo; } -bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty property, +bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty_Dev property, bool value) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return false; + switch (property) { + case PP_URLREQUESTPROPERTY_STREAMTOFILE: + stream_to_file_ = value; + return true; + default: + NOTIMPLEMENTED(); // TODO(darin): Implement me! + return false; + } } -bool URLRequestInfo::SetStringProperty(PP_URLRequestProperty property, +bool URLRequestInfo::SetStringProperty(PP_URLRequestProperty_Dev property, const std::string& value) { // TODO(darin): Validate input. Perhaps at a different layer? switch (property) { @@ -167,6 +176,14 @@ bool URLRequestInfo::AppendFileToBody(FileRef* file_ref, int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time) { + // Ignore a call to append nothing. + if (number_of_bytes == 0) + return true; + + // Check for bad values. (-1 means read until end of file.) + if (start_offset < 0 || number_of_bytes < -1) + return false; + body_.push_back(BodyItem(file_ref, start_offset, number_of_bytes, @@ -178,6 +195,7 @@ WebURLRequest URLRequestInfo::ToWebURLRequest(WebFrame* frame) const { WebURLRequest web_request; web_request.initialize(); web_request.setURL(frame->document().completeURL(WebString::fromUTF8(url_))); + web_request.setDownloadToFile(stream_to_file_); if (!method_.empty()) web_request.setHTTPMethod(WebString::fromUTF8(method_)); @@ -198,13 +216,11 @@ WebURLRequest URLRequestInfo::ToWebURLRequest(WebFrame* frame) const { http_body.initialize(); for (size_t i = 0; i < body_.size(); ++i) { if (body_[i].file_ref) { - WebFileInfo file_info; - file_info.modificationTime = body_[i].expected_last_modified_time; http_body.appendFileRange( webkit_glue::FilePathToWebString(body_[i].file_ref->system_path()), body_[i].start_offset, body_[i].number_of_bytes, - file_info); + body_[i].expected_last_modified_time); } else { DCHECK(!body_[i].data.empty()); http_body.appendData(WebData(body_[i].data)); diff --git a/webkit/glue/plugins/pepper_url_request_info.h b/webkit/glue/plugins/pepper_url_request_info.h index ef1452c..7220531 100644 --- a/webkit/glue/plugins/pepper_url_request_info.h +++ b/webkit/glue/plugins/pepper_url_request_info.h @@ -9,7 +9,7 @@ #include <vector> #include "base/ref_counted.h" -#include "third_party/ppapi/c/ppb_url_request_info.h" +#include "third_party/ppapi/c/dev/ppb_url_request_info_dev.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_resource.h" @@ -27,14 +27,14 @@ class URLRequestInfo : public Resource { // Returns a pointer to the interface implementing PPB_URLRequestInfo that is // exposed to the plugin. - static const PPB_URLRequestInfo* GetInterface(); + static const PPB_URLRequestInfo_Dev* GetInterface(); // Resource overrides. URLRequestInfo* AsURLRequestInfo() { return this; } // PPB_URLRequestInfo implementation. - bool SetBooleanProperty(PP_URLRequestProperty property, bool value); - bool SetStringProperty(PP_URLRequestProperty property, + bool SetBooleanProperty(PP_URLRequestProperty_Dev property, bool value); + bool SetStringProperty(PP_URLRequestProperty_Dev property, const std::string& value); bool AppendDataToBody(const std::string& data); bool AppendFileToBody(FileRef* file_ref, @@ -76,6 +76,7 @@ class URLRequestInfo : public Resource { std::string method_; std::string headers_; Body body_; + bool stream_to_file_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_response_info.cc b/webkit/glue/plugins/pepper_url_response_info.cc index bff92aa..79042ba 100644 --- a/webkit/glue/plugins/pepper_url_response_info.cc +++ b/webkit/glue/plugins/pepper_url_response_info.cc @@ -12,6 +12,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_var.h" +#include "webkit/glue/webkit_glue.h" using WebKit::WebHTTPHeaderVisitor; using WebKit::WebString; @@ -42,7 +43,7 @@ bool IsURLResponseInfo(PP_Resource resource) { } PP_Var GetProperty(PP_Resource response_id, - PP_URLResponseProperty property) { + PP_URLResponseProperty_Dev property) { scoped_refptr<URLResponseInfo> response( Resource::GetAs<URLResponseInfo>(response_id)); if (!response) @@ -65,7 +66,7 @@ PP_Resource GetBody(PP_Resource response_id) { return body->GetReference(); } -const PPB_URLResponseInfo ppb_urlresponseinfo = { +const PPB_URLResponseInfo_Dev ppb_urlresponseinfo = { &IsURLResponseInfo, &GetProperty, &GetBody @@ -82,18 +83,18 @@ URLResponseInfo::~URLResponseInfo() { } // static -const PPB_URLResponseInfo* URLResponseInfo::GetInterface() { +const PPB_URLResponseInfo_Dev* URLResponseInfo::GetInterface() { return &ppb_urlresponseinfo; } -PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty property) { +PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty_Dev property) { switch (property) { case PP_URLRESPONSEPROPERTY_URL: - return StringToPPVar(url_); + return StringVar::StringToPPVar(module(), url_); case PP_URLRESPONSEPROPERTY_STATUSCODE: return PP_MakeInt32(status_code_); case PP_URLRESPONSEPROPERTY_HEADERS: - return StringToPPVar(headers_); + return StringVar::StringToPPVar(module(), headers_); default: NOTIMPLEMENTED(); // TODO(darin): Implement me! return PP_MakeVoid(); @@ -107,6 +108,10 @@ bool URLResponseInfo::Initialize(const WebURLResponse& response) { HeaderFlattener flattener; response.visitHTTPHeaderFields(&flattener); headers_ = flattener.buffer(); + + WebString file_path = response.downloadFilePath(); + if (!file_path.isEmpty()) + body_ = new FileRef(module(), webkit_glue::WebStringToFilePath(file_path)); return true; } diff --git a/webkit/glue/plugins/pepper_url_response_info.h b/webkit/glue/plugins/pepper_url_response_info.h index 8874919..d8e1321 100644 --- a/webkit/glue/plugins/pepper_url_response_info.h +++ b/webkit/glue/plugins/pepper_url_response_info.h @@ -7,7 +7,7 @@ #include <string> -#include "third_party/ppapi/c/ppb_url_response_info.h" +#include "third_party/ppapi/c/dev/ppb_url_response_info_dev.h" #include "webkit/glue/plugins/pepper_resource.h" namespace WebKit { @@ -23,13 +23,13 @@ class URLResponseInfo : public Resource { // Returns a pointer to the interface implementing PPB_URLResponseInfo that // is exposed to the plugin. - static const PPB_URLResponseInfo* GetInterface(); + static const PPB_URLResponseInfo_Dev* GetInterface(); // Resource overrides. URLResponseInfo* AsURLResponseInfo() { return this; } // PPB_URLResponseInfo implementation. - PP_Var GetProperty(PP_URLResponseProperty property); + PP_Var GetProperty(PP_URLResponseProperty_Dev property); bool Initialize(const WebKit::WebURLResponse& response); diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc index 414df7b..b4ba014 100644 --- a/webkit/glue/plugins/pepper_var.cc +++ b/webkit/glue/plugins/pepper_var.cc @@ -9,9 +9,9 @@ #include "base/string_util.h" #include "third_party/ppapi/c/pp_var.h" #include "third_party/ppapi/c/ppb_var.h" -#include "third_party/ppapi/c/ppp_class.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" -#include "webkit/glue/plugins/pepper_string.h" +#include "webkit/glue/plugins/pepper_plugin_module.h" +#include "webkit/glue/plugins/pepper_plugin_object.h" #include "v8/include/v8.h" using WebKit::WebBindings; @@ -20,43 +20,9 @@ namespace pepper { namespace { -void Release(PP_Var var); -PP_Var VarFromUtf8(const char* data, uint32_t len); - -// --------------------------------------------------------------------------- -// Exceptions - -class TryCatch { - public: - TryCatch(PP_Var* exception) : exception_(exception) { - WebBindings::pushExceptionHandler(&TryCatch::Catch, this); - } - - ~TryCatch() { - WebBindings::popExceptionHandler(); - } - - bool HasException() const { - return exception_ && exception_->type != PP_VARTYPE_VOID; - } - - void SetException(const char* message) { - DCHECK(!HasException()); - if (exception_) - *exception_ = VarFromUtf8(message, strlen(message)); - } - - private: - static void Catch(void* self, const NPUTF8* message) { - static_cast<TryCatch*>(self)->SetException(message); - } - - // May be null if the consumer isn't interesting in catching exceptions. - PP_Var* exception_; -}; - const char kInvalidObjectException[] = "Error: Invalid object"; const char kInvalidPropertyException[] = "Error: Invalid property"; +const char kInvalidValueException[] = "Error: Invalid value"; const char kUnableToGetPropertyException[] = "Error: Unable to get property"; const char kUnableToSetPropertyException[] = "Error: Unable to set property"; const char kUnableToRemovePropertyException[] = @@ -69,531 +35,182 @@ const char kUnableToConstructException[] = "Error: Unable to construct"; // --------------------------------------------------------------------------- // Utilities -String* GetStringUnchecked(PP_Var var) { - return reinterpret_cast<String*>(var.value.as_id); -} - -NPObject* GetNPObjectUnchecked(PP_Var var) { - return reinterpret_cast<NPObject*>(var.value.as_id); -} - -// Returns a PP_Var that corresponds to the given NPVariant. The contents of -// the NPVariant will be copied unless the NPVariant corresponds to an object. -PP_Var NPVariantToPPVar(const NPVariant* variant) { - switch (variant->type) { - case NPVariantType_Void: - return PP_MakeVoid(); - case NPVariantType_Null: - return PP_MakeNull(); - case NPVariantType_Bool: - return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant)); - case NPVariantType_Int32: - return PP_MakeInt32(NPVARIANT_TO_INT32(*variant)); - case NPVariantType_Double: - return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant)); - case NPVariantType_String: - return VarFromUtf8(NPVARIANT_TO_STRING(*variant).UTF8Characters, - NPVARIANT_TO_STRING(*variant).UTF8Length); - case NPVariantType_Object: - return NPObjectToPPVar(NPVARIANT_TO_OBJECT(*variant)); - } - NOTREACHED(); - return PP_MakeVoid(); -} - -// Returns a NPVariant that corresponds to the given PP_Var. The contents of -// the PP_Var will be copied unless the PP_Var corresponds to an object. -NPVariant PPVarToNPVariant(PP_Var var) { - NPVariant ret; +// Converts the given PP_Var to an NPVariant, returning true on success. +// False means that the given variant is invalid. In this case, the result +// NPVariant will be set to a void one. +// +// The contents of the PP_Var will NOT be copied, so you need to ensure that +// the PP_Var remains valid while the resultant NPVariant is in use. +bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) { switch (var.type) { case PP_VARTYPE_VOID: - VOID_TO_NPVARIANT(ret); + VOID_TO_NPVARIANT(*result); break; case PP_VARTYPE_NULL: - NULL_TO_NPVARIANT(ret); + NULL_TO_NPVARIANT(*result); break; case PP_VARTYPE_BOOL: - BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret); + BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result); break; case PP_VARTYPE_INT32: - INT32_TO_NPVARIANT(var.value.as_int, ret); + INT32_TO_NPVARIANT(var.value.as_int, *result); break; case PP_VARTYPE_DOUBLE: - DOUBLE_TO_NPVARIANT(var.value.as_double, ret); + DOUBLE_TO_NPVARIANT(var.value.as_double, *result); break; case PP_VARTYPE_STRING: { - const std::string& value = GetStringUnchecked(var)->value(); - STRINGN_TO_NPVARIANT(base::strdup(value.c_str()), value.size(), ret); + scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); + if (!string) { + VOID_TO_NPVARIANT(*result); + return false; + } + const std::string& value = string->value(); + STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result); break; } case PP_VARTYPE_OBJECT: { - NPObject* object = GetNPObjectUnchecked(var); - OBJECT_TO_NPVARIANT(WebBindings::retainObject(object), ret); + scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var)); + if (!object) { + VOID_TO_NPVARIANT(*result); + return false; + } + OBJECT_TO_NPVARIANT(object->np_object(), *result); break; } - } - return ret; -} - -// Returns a NPVariant that corresponds to the given PP_Var. The contents of -// the PP_Var will NOT be copied, so you need to ensure that the PP_Var remains -// valid while the resultant NPVariant is in use. -NPVariant PPVarToNPVariantNoCopy(PP_Var var) { - NPVariant ret; - switch (var.type) { - case PP_VARTYPE_VOID: - VOID_TO_NPVARIANT(ret); - break; - case PP_VARTYPE_NULL: - NULL_TO_NPVARIANT(ret); - break; - case PP_VARTYPE_BOOL: - BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret); - break; - case PP_VARTYPE_INT32: - INT32_TO_NPVARIANT(var.value.as_int, ret); - break; - case PP_VARTYPE_DOUBLE: - DOUBLE_TO_NPVARIANT(var.value.as_double, ret); - break; - case PP_VARTYPE_STRING: { - const std::string& value = GetStringUnchecked(var)->value(); - STRINGN_TO_NPVARIANT(value.c_str(), value.size(), ret); - break; - } - case PP_VARTYPE_OBJECT: { - OBJECT_TO_NPVARIANT(GetNPObjectUnchecked(var), ret); - break; - } - } - return ret; -} - -// Returns a NPIdentifier that corresponds to the given PP_Var. The contents -// of the PP_Var will be copied. Returns NULL if the given PP_Var is not a a -// string or integer type. -NPIdentifier PPVarToNPIdentifier(PP_Var var) { - switch (var.type) { - case PP_VARTYPE_STRING: - return WebBindings::getStringIdentifier( - GetStringUnchecked(var)->value().c_str()); - case PP_VARTYPE_INT32: - return WebBindings::getIntIdentifier(var.value.as_int); default: - return NULL; + VOID_TO_NPVARIANT(*result); + return false; } + return true; } -PP_Var NPIdentifierToPPVar(NPIdentifier id) { - const NPUTF8* string_value = NULL; - int32_t int_value = 0; - bool is_string = false; - WebBindings::extractIdentifierData(id, string_value, int_value, is_string); - if (is_string) - return VarFromUtf8(string_value, strlen(string_value)); - - return PP_MakeInt32(int_value); -} - -PP_Var NPIdentifierToPPVarString(NPIdentifier id) { - PP_Var var = NPIdentifierToPPVar(id); - if (var.type == PP_VARTYPE_STRING) - return var; - DCHECK(var.type == PP_VARTYPE_INT32); - const std::string& str = IntToString(var.value.as_int); - return VarFromUtf8(str.data(), str.size()); -} - -void ThrowException(NPObject* object, PP_Var exception) { - String* str = GetString(exception); - if (str) - WebBindings::setException(object, str->value().c_str()); -} - -// --------------------------------------------------------------------------- -// NPObject implementation in terms of PPP_Class - -struct WrapperObject : NPObject { - const PPP_Class* ppp_class; - void* ppp_class_data; -}; - -static WrapperObject* ToWrapper(NPObject* object) { - return static_cast<WrapperObject*>(object); -} - -NPObject* WrapperClass_Allocate(NPP npp, NPClass* unused) { - return new WrapperObject; -} - -void WrapperClass_Deallocate(NPObject* object) { - WrapperObject* wrapper = ToWrapper(object); - wrapper->ppp_class->Deallocate(wrapper->ppp_class_data); - delete object; -} - -void WrapperClass_Invalidate(NPObject* object) { - // TODO(darin): Do I need to do something here? -} - -bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { - WrapperObject* wrapper = ToWrapper(object); - - PP_Var method_name_var = NPIdentifierToPPVarString(method_name); - PP_Var exception = PP_MakeVoid(); - bool rv = wrapper->ppp_class->HasMethod(wrapper->ppp_class_data, - method_name_var, - &exception); - Release(method_name_var); - - if (exception.type != PP_VARTYPE_VOID) { - ThrowException(object, exception); - Release(exception); - return false; - } - return rv; -} - -bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, - const NPVariant* argv, uint32_t argc, - NPVariant* result) { - WrapperObject* wrapper = ToWrapper(object); - - scoped_array<PP_Var> args; - if (argc) { - args.reset(new PP_Var[argc]); - for (uint32_t i = 0; i < argc; ++i) - args[i] = NPVariantToPPVar(&argv[i]); - } - PP_Var method_name_var = NPIdentifierToPPVarString(method_name); - PP_Var exception = PP_MakeVoid(); - PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data, - method_name_var, argc, - args.get(), &exception); - Release(method_name_var); - for (uint32_t i = 0; i < argc; ++i) - Release(args[i]); - - bool rv; - if (exception.type == PP_VARTYPE_VOID) { - rv = true; - *result = PPVarToNPVariant(result_var); - } else { - rv = false; - ThrowException(object, exception); - Release(exception); - } - Release(result_var); - return rv; -} - -bool WrapperClass_InvokeDefault(NPObject* object, const NPVariant* argv, - uint32_t argc, NPVariant* result) { - WrapperObject* wrapper = ToWrapper(object); - - scoped_array<PP_Var> args; - if (argc) { - args.reset(new PP_Var[argc]); - for (uint32_t i = 0; i < argc; ++i) - args[i] = NPVariantToPPVar(&argv[i]); - } - PP_Var exception = PP_MakeVoid(); - PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data, - PP_MakeVoid(), argc, args.get(), - &exception); - for (uint32_t i = 0; i < argc; ++i) - Release(args[i]); - - bool rv; - if (exception.type == PP_VARTYPE_VOID) { - rv = true; - *result = PPVarToNPVariant(result_var); - } else { - rv = false; - ThrowException(object, exception); - Release(exception); - } - Release(result_var); - return rv; -} - -bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) { - WrapperObject* wrapper = ToWrapper(object); - - PP_Var property_name_var = NPIdentifierToPPVar(property_name); - PP_Var exception = PP_MakeVoid(); - bool rv = wrapper->ppp_class->HasProperty(wrapper->ppp_class_data, - property_name_var, - &exception); - Release(property_name_var); - - if (exception.type != PP_VARTYPE_VOID) { - ThrowException(object, exception); - Release(exception); - return false; - } - return rv; -} - -bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name, - NPVariant* result) { - WrapperObject* wrapper = ToWrapper(object); - - PP_Var property_name_var = NPIdentifierToPPVar(property_name); - PP_Var exception = PP_MakeVoid(); - PP_Var result_var = wrapper->ppp_class->GetProperty(wrapper->ppp_class_data, - property_name_var, - &exception); - Release(property_name_var); - - bool rv; - if (exception.type == PP_VARTYPE_VOID) { - rv = true; - *result = PPVarToNPVariant(result_var); - } else { - rv = false; - ThrowException(object, exception); - Release(exception); - } - Release(result_var); - return rv; -} - -bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name, - const NPVariant* value) { - WrapperObject* wrapper = ToWrapper(object); +// ObjectAccessorTryCatch ------------------------------------------------------ - PP_Var property_name_var = NPIdentifierToPPVar(property_name); - PP_Var value_var = NPVariantToPPVar(value); - PP_Var exception = PP_MakeVoid(); - wrapper->ppp_class->SetProperty(wrapper->ppp_class_data, property_name_var, - value_var, &exception); - Release(value_var); - Release(property_name_var); - - if (exception.type != PP_VARTYPE_VOID) { - ThrowException(object, exception); - Release(exception); - return false; +// Automatically sets up a TryCatch for accessing the object identified by the +// given PP_Var. The module from the object will be used for the exception +// strings generated by the TryCatch. +// +// This will automatically retrieve the ObjectVar from the object and throw +// an exception if it's invalid. At the end of construction, if there is no +// exception, you know that there is no previously set exception, that the +// object passed in is valid and ready to use (via the object() getter), and +// that the TryCatch's module() getter is also set up properly and ready to +// use. +class ObjectAccessorTryCatch : public TryCatch { + public: + ObjectAccessorTryCatch(PP_Var object, PP_Var* exception) + : TryCatch(NULL, exception), + object_(ObjectVar::FromPPVar(object)) { + if (!object_) { + // No object or an invalid object was given. This means we have no module + // to associated with the exception text, so use the magic invalid object + // exception. + SetInvalidObjectException(); + } else { + // When the object is valid, we have a valid module to associate + set_module(object_->module()); + } } - return true; -} -bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) { - WrapperObject* wrapper = ToWrapper(object); + ObjectVar* object() { return object_.get(); } - PP_Var property_name_var = NPIdentifierToPPVar(property_name); - PP_Var exception = PP_MakeVoid(); - wrapper->ppp_class->RemoveProperty(wrapper->ppp_class_data, property_name_var, - &exception); - Release(property_name_var); + protected: + scoped_refptr<ObjectVar> object_; - if (exception.type != PP_VARTYPE_VOID) { - ThrowException(object, exception); - Release(exception); - return false; - } - return true; -} + DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch); +}; -bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, - uint32_t* count) { - WrapperObject* wrapper = ToWrapper(object); - - uint32_t property_count = 0; - PP_Var* properties = NULL; - PP_Var exception = PP_MakeVoid(); - wrapper->ppp_class->GetAllPropertyNames(wrapper->ppp_class_data, - &property_count, - &properties, - &exception); - - bool rv; - if (exception.type == PP_VARTYPE_VOID) { - rv = true; - if (property_count == 0) { - *values = NULL; - *count = 0; - } else { - *values = static_cast<NPIdentifier*>( - malloc(sizeof(NPIdentifier) * property_count)); - *count = property_count; - for (uint32_t i = 0; i < property_count; ++i) - (*values)[i] = PPVarToNPIdentifier(properties[i]); +// ObjectAccessiorWithIdentifierTryCatch --------------------------------------- + +// Automatically sets up a TryCatch for accessing the identifier on the given +// object. This just extends ObjectAccessorTryCatch to additionally convert +// the given identifier to an NPIdentifier and validate it, throwing an +// exception if it's invalid. +// +// At the end of construction, if there is no exception, you know that there is +// no previously set exception, that the object passed in is valid and ready to +// use (via the object() getter), that the identifier is valid and ready to +// use (via the identifier() getter), and that the TryCatch's module() getter +// is also set up properly and ready to use. +class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch { + public: + ObjectAccessorWithIdentifierTryCatch(PP_Var object, + PP_Var identifier, + PP_Var* exception) + : ObjectAccessorTryCatch(object, exception), + identifier_(0) { + if (!has_exception()) { + identifier_ = Var::PPVarToNPIdentifier(identifier); + if (!identifier_) + SetException(kInvalidPropertyException); } - } else { - rv = false; - ThrowException(object, exception); - Release(exception); } - for (uint32_t i = 0; i < property_count; ++i) - Release(properties[i]); - free(properties); - return rv; -} + NPIdentifier identifier() const { return identifier_; } -bool WrapperClass_Construct(NPObject* object, const NPVariant* argv, - uint32_t argc, NPVariant* result) { - WrapperObject* wrapper = ToWrapper(object); - - scoped_array<PP_Var> args; - if (argc) { - args.reset(new PP_Var[argc]); - for (uint32_t i = 0; i < argc; ++i) - args[i] = NPVariantToPPVar(&argv[i]); - } + private: + NPIdentifier identifier_; - PP_Var exception = PP_MakeVoid(); - PP_Var result_var = wrapper->ppp_class->Construct(wrapper->ppp_class_data, - argc, args.get(), - &exception); - for (uint32_t i = 0; i < argc; ++i) - Release(args[i]); - - bool rv; - if (exception.type == PP_VARTYPE_VOID) { - rv = true; - *result = PPVarToNPVariant(result_var); - } else { - rv = false; - ThrowException(object, exception); - Release(exception); - } - Release(result_var); - return rv; -} - -const NPClass wrapper_class = { - NP_CLASS_STRUCT_VERSION, - WrapperClass_Allocate, - WrapperClass_Deallocate, - WrapperClass_Invalidate, - WrapperClass_HasMethod, - WrapperClass_Invoke, - WrapperClass_InvokeDefault, - WrapperClass_HasProperty, - WrapperClass_GetProperty, - WrapperClass_SetProperty, - WrapperClass_RemoveProperty, - WrapperClass_Enumerate, - WrapperClass_Construct + DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch); }; -// --------------------------------------------------------------------------- -// PPB_Var methods - -void AddRef(PP_Var var) { - if (var.type == PP_VARTYPE_STRING) { - GetStringUnchecked(var)->AddRef(); - } else if (var.type == PP_VARTYPE_OBJECT) { - // TODO(darin): Add thread safety check - WebBindings::retainObject(GetNPObjectUnchecked(var)); - } -} - -void Release(PP_Var var) { - if (var.type == PP_VARTYPE_STRING) { - GetStringUnchecked(var)->Release(); - } else if (var.type == PP_VARTYPE_OBJECT) { - // TODO(darin): Add thread safety check - WebBindings::releaseObject(GetNPObjectUnchecked(var)); - } -} +// PPB_Var methods ------------------------------------------------------------- -PP_Var VarFromUtf8(const char* data, uint32_t len) { - String* str = new String(data, len); - str->AddRef(); // This is for the caller, we return w/ a refcount of 1. - PP_Var ret; - ret.type = PP_VARTYPE_STRING; - ret.value.as_id = reinterpret_cast<intptr_t>(str); - return ret; +PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) { + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return PP_MakeNull(); + return StringVar::StringToPPVar(module, data, len); } const char* VarToUtf8(PP_Var var, uint32_t* len) { - if (var.type != PP_VARTYPE_STRING) { + scoped_refptr<StringVar> str(StringVar::FromPPVar(var)); + if (!str) { *len = 0; return NULL; } - const std::string& str = GetStringUnchecked(var)->value(); - *len = static_cast<uint32_t>(str.size()); - if (str.empty()) + *len = static_cast<uint32_t>(str->value().size()); + if (str->value().empty()) return ""; // Don't return NULL on success. - return str.data(); + return str->value().data(); } bool HasProperty(PP_Var var, PP_Var name, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) + ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); + if (accessor.has_exception()) return false; - - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); - return false; - } - - NPIdentifier identifier = PPVarToNPIdentifier(name); - if (!identifier) { - try_catch.SetException(kInvalidPropertyException); - return false; - } - - return WebBindings::hasProperty(NULL, object, identifier); + return WebBindings::hasProperty(NULL, accessor.object()->np_object(), + accessor.identifier()); } bool HasMethod(PP_Var var, PP_Var name, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) - return false; - - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); + ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); + if (accessor.has_exception()) return false; - } - - NPIdentifier identifier = PPVarToNPIdentifier(name); - if (!identifier) { - try_catch.SetException(kInvalidPropertyException); - return false; - } - - return WebBindings::hasMethod(NULL, object, identifier); + return WebBindings::hasMethod(NULL, accessor.object()->np_object(), + accessor.identifier()); } PP_Var GetProperty(PP_Var var, PP_Var name, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) - return PP_MakeVoid(); - - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); - return PP_MakeVoid(); - } - - NPIdentifier identifier = PPVarToNPIdentifier(name); - if (!identifier) { - try_catch.SetException(kInvalidPropertyException); + ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); + if (accessor.has_exception()) return PP_MakeVoid(); - } NPVariant result; - if (!WebBindings::getProperty(NULL, object, identifier, &result)) { + if (!WebBindings::getProperty(NULL, accessor.object()->np_object(), + accessor.identifier(), &result)) { // An exception may have been raised. - if (!try_catch.HasException()) - try_catch.SetException(kUnableToGetPropertyException); + accessor.SetException(kUnableToGetPropertyException); return PP_MakeVoid(); } - PP_Var ret = NPVariantToPPVar(&result); + PP_Var ret = Var::NPVariantToPPVar(accessor.object()->module(), &result); WebBindings::releaseVariantValue(&result); return ret; } @@ -605,21 +222,15 @@ void GetAllPropertyNames(PP_Var var, *properties = NULL; *property_count = 0; - TryCatch try_catch(exception); - if (try_catch.HasException()) + ObjectAccessorTryCatch accessor(var, exception); + if (accessor.has_exception()) return; - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); - return; - } - NPIdentifier* identifiers = NULL; uint32_t count = 0; - if (!WebBindings::enumerate(NULL, object, &identifiers, &count)) { - if (!try_catch.HasException()) - try_catch.SetException(kUnableToGetAllPropertiesException); + if (!WebBindings::enumerate(NULL, accessor.object()->np_object(), + &identifiers, &count)) { + accessor.SetException(kUnableToGetAllPropertiesException); return; } @@ -628,8 +239,10 @@ void GetAllPropertyNames(PP_Var var, *property_count = count; *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count)); - for (uint32_t i = 0; i < count; ++i) - (*properties)[i] = NPIdentifierToPPVar(identifiers[i]); + for (uint32_t i = 0; i < count; ++i) { + (*properties)[i] = Var::NPIdentifierToPPVar(accessor.object()->module(), + identifiers[i]); + } free(identifiers); } @@ -637,52 +250,30 @@ void SetProperty(PP_Var var, PP_Var name, PP_Var value, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) + ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); + if (accessor.has_exception()) return; - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); + NPVariant variant; + if (!PPVarToNPVariantNoCopy(value, &variant)) { + accessor.SetException(kInvalidValueException); return; } - - NPIdentifier identifier = PPVarToNPIdentifier(name); - if (!identifier) { - try_catch.SetException(kInvalidPropertyException); - return; - } - - NPVariant variant = PPVarToNPVariantNoCopy(value); - if (!WebBindings::setProperty(NULL, object, identifier, &variant)) { - if (!try_catch.HasException()) - try_catch.SetException(kUnableToSetPropertyException); - } + if (!WebBindings::setProperty(NULL, accessor.object()->np_object(), + accessor.identifier(), &variant)) + accessor.SetException(kUnableToSetPropertyException); } void RemoveProperty(PP_Var var, PP_Var name, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) - return; - - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); - return; - } - - NPIdentifier identifier = PPVarToNPIdentifier(name); - if (!identifier) { - try_catch.SetException(kInvalidPropertyException); + ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); + if (accessor.has_exception()) return; - } - if (!WebBindings::removeProperty(NULL, object, identifier)) { - if (!try_catch.HasException()) - try_catch.SetException(kUnableToRemovePropertyException); - } + if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(), + accessor.identifier())) + accessor.SetException(kUnableToRemovePropertyException); } PP_Var Call(PP_Var var, @@ -690,56 +281,55 @@ PP_Var Call(PP_Var var, uint32_t argc, PP_Var* argv, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) + ObjectAccessorTryCatch accessor(var, exception); + if (accessor.has_exception()) return PP_MakeVoid(); - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); - return PP_MakeVoid(); - } - NPIdentifier identifier; if (method_name.type == PP_VARTYPE_VOID) { identifier = NULL; } else if (method_name.type == PP_VARTYPE_STRING) { // Specifically allow only string functions to be called. - identifier = PPVarToNPIdentifier(method_name); + identifier = Var::PPVarToNPIdentifier(method_name); if (!identifier) { - try_catch.SetException(kInvalidPropertyException); + accessor.SetException(kInvalidPropertyException); return PP_MakeVoid(); } } else { - try_catch.SetException(kInvalidPropertyException); + accessor.SetException(kInvalidPropertyException); return PP_MakeVoid(); } scoped_array<NPVariant> args; if (argc) { args.reset(new NPVariant[argc]); - for (uint32_t i = 0; i < argc; ++i) - args[i] = PPVarToNPVariantNoCopy(argv[i]); + for (uint32_t i = 0; i < argc; ++i) { + if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) { + // This argument was invalid, throw an exception & give up. + accessor.SetException(kInvalidValueException); + return PP_MakeVoid(); + } + } } bool ok; NPVariant result; if (identifier) { - ok = WebBindings::invoke(NULL, object, identifier, args.get(), argc, - &result); + ok = WebBindings::invoke(NULL, accessor.object()->np_object(), + identifier, args.get(), argc, &result); } else { - ok = WebBindings::invokeDefault(NULL, object, args.get(), argc, &result); + ok = WebBindings::invokeDefault(NULL, accessor.object()->np_object(), + args.get(), argc, &result); } if (!ok) { // An exception may have been raised. - if (!try_catch.HasException()) - try_catch.SetException(kUnableToCallMethodException); + accessor.SetException(kUnableToCallMethodException); return PP_MakeVoid(); } - PP_Var ret = NPVariantToPPVar(&result); + PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result); WebBindings::releaseVariantValue(&result); return ret; } @@ -748,67 +338,58 @@ PP_Var Construct(PP_Var var, uint32_t argc, PP_Var* argv, PP_Var* exception) { - TryCatch try_catch(exception); - if (try_catch.HasException()) + ObjectAccessorTryCatch accessor(var, exception); + if (accessor.has_exception()) return PP_MakeVoid(); - NPObject* object = GetNPObject(var); - if (!object) { - try_catch.SetException(kInvalidObjectException); - return PP_MakeVoid(); - } - scoped_array<NPVariant> args; if (argc) { args.reset(new NPVariant[argc]); - for (uint32_t i = 0; i < argc; ++i) - args[i] = PPVarToNPVariantNoCopy(argv[i]); + for (uint32_t i = 0; i < argc; ++i) { + if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) { + // This argument was invalid, throw an exception & give up. + accessor.SetException(kInvalidValueException); + return PP_MakeVoid(); + } + } } NPVariant result; - if (!WebBindings::construct(NULL, object, args.get(), argc, &result)) { + if (!WebBindings::construct(NULL, accessor.object()->np_object(), + args.get(), argc, &result)) { // An exception may have been raised. - if (!try_catch.HasException()) - try_catch.SetException(kUnableToConstructException); + accessor.SetException(kUnableToConstructException); return PP_MakeVoid(); } - PP_Var ret = NPVariantToPPVar(&result); + PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result); WebBindings::releaseVariantValue(&result); return ret; } -bool IsInstanceOf(PP_Var var, const PPP_Class* ppp_class, +bool IsInstanceOf(PP_Var var, + const PPP_Class* ppp_class, void** ppp_class_data) { - NPObject* object = GetNPObject(var); + scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var)); if (!object) - return false; - - if (object->_class != &wrapper_class) - return false; + return false; // Not an object at all. - WrapperObject* wrapper = ToWrapper(object); - if (wrapper->ppp_class != ppp_class) - return false; - - if (ppp_class_data) - *ppp_class_data = wrapper->ppp_class_data; - return true; + return PluginObject::IsInstanceOf(object->np_object(), + ppp_class, ppp_class_data); } -PP_Var CreateObject(const PPP_Class* ppp_class, void* ppp_class_data) { - NPObject* object = - WebBindings::createObject(NULL, const_cast<NPClass*>(&wrapper_class)); - static_cast<WrapperObject*>(object)->ppp_class = ppp_class; - static_cast<WrapperObject*>(object)->ppp_class_data = ppp_class_data; - PP_Var ret = NPObjectToPPVar(object); - WebBindings::releaseObject(object); // Release reference from createObject - return ret; +PP_Var CreateObject(PP_Module module_id, + const PPP_Class* ppp_class, + void* ppp_class_data) { + PluginModule* module = PluginModule::FromPPModule(module_id); + if (!module) + return PP_MakeNull(); + return PluginObject::Create(module, ppp_class, ppp_class_data); } const PPB_Var var_interface = { - &AddRef, - &Release, + &Var::PluginAddRefPPVar, + &Var::PluginReleasePPVar, &VarFromUtf8, &VarToUtf8, &HasProperty, @@ -825,33 +406,206 @@ const PPB_Var var_interface = { } // namespace -const PPB_Var* GetVarInterface() { +// Var ------------------------------------------------------------------------- + +Var::Var(PluginModule* module) : Resource(module) { +} + +Var::~Var() { +} + +// static +PP_Var Var::NPVariantToPPVar(PluginModule* module, const NPVariant* variant) { + switch (variant->type) { + case NPVariantType_Void: + return PP_MakeVoid(); + case NPVariantType_Null: + return PP_MakeNull(); + case NPVariantType_Bool: + return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant)); + case NPVariantType_Int32: + return PP_MakeInt32(NPVARIANT_TO_INT32(*variant)); + case NPVariantType_Double: + return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant)); + case NPVariantType_String: + return StringVar::StringToPPVar( + module, + NPVARIANT_TO_STRING(*variant).UTF8Characters, + NPVARIANT_TO_STRING(*variant).UTF8Length); + case NPVariantType_Object: + return ObjectVar::NPObjectToPPVar(module, NPVARIANT_TO_OBJECT(*variant)); + } + NOTREACHED(); + return PP_MakeVoid(); +} + +// static +NPIdentifier Var::PPVarToNPIdentifier(PP_Var var) { + switch (var.type) { + case PP_VARTYPE_STRING: { + scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); + if (!string) + return NULL; + return WebBindings::getStringIdentifier(string->value().c_str()); + } + case PP_VARTYPE_INT32: + return WebBindings::getIntIdentifier(var.value.as_int); + default: + return NULL; + } +} + +// static +PP_Var Var::NPIdentifierToPPVar(PluginModule* module, NPIdentifier id) { + const NPUTF8* string_value = NULL; + int32_t int_value = 0; + bool is_string = false; + WebBindings::extractIdentifierData(id, string_value, int_value, is_string); + if (is_string) + return StringVar::StringToPPVar(module, string_value); + + return PP_MakeInt32(int_value); +} + +// static +void Var::PluginAddRefPPVar(PP_Var var) { + if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) { + // TODO(brettw) consider checking that the ID is actually a var ID rather + // than some random other resource ID. + if (!ResourceTracker::Get()->AddRefResource(var.value.as_id)) + DLOG(WARNING) << "AddRefVar()ing a nonexistant string/object var."; + } +} + +// static +void Var::PluginReleasePPVar(PP_Var var) { + if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) { + // TODO(brettw) consider checking that the ID is actually a var ID rather + // than some random other resource ID. + if (!ResourceTracker::Get()->UnrefResource(var.value.as_id)) + DLOG(WARNING) << "ReleaseVar()ing a nonexistant string/object var."; + } +} + +// static +const PPB_Var* Var::GetInterface() { return &var_interface; } -PP_Var NPObjectToPPVar(NPObject* object) { +// StringVar ------------------------------------------------------------------- + +StringVar::StringVar(PluginModule* module, const char* str, uint32 len) + : Var(module), + value_(str, len) { +} + +StringVar::~StringVar() { +} + +// static +PP_Var StringVar::StringToPPVar(PluginModule* module, const std::string& var) { + return StringToPPVar(module, var.c_str(), var.size()); +} + +// static +PP_Var StringVar::StringToPPVar(PluginModule* module, + const char* data, uint32 len) { + scoped_refptr<StringVar> str(new StringVar(module, data, len)); + if (!str || !IsStringUTF8(str->value())) + return PP_MakeNull(); + PP_Var ret; - ret.type = PP_VARTYPE_OBJECT; - ret.value.as_id = reinterpret_cast<intptr_t>(object); - WebBindings::retainObject(object); + ret.type = PP_VARTYPE_STRING; + + // The caller takes ownership now. + ret.value.as_id = str->GetReference(); return ret; } -NPObject* GetNPObject(PP_Var var) { +// static +scoped_refptr<StringVar> StringVar::FromPPVar(PP_Var var) { + if (var.type != PP_VARTYPE_STRING) + return scoped_refptr<StringVar>(NULL); + return Resource::GetAs<StringVar>(var.value.as_id); +} + +// ObjectVar ------------------------------------------------------------- + +ObjectVar::ObjectVar(PluginModule* module, NPObject* np_object) + : Var(module), + np_object_(np_object) { + WebBindings::retainObject(np_object_); + module->AddNPObjectVar(this); +} + +ObjectVar::~ObjectVar() { + module()->RemoveNPObjectVar(this); + WebBindings::releaseObject(np_object_); +} + +// static +PP_Var ObjectVar::NPObjectToPPVar(PluginModule* module, NPObject* object) { + scoped_refptr<ObjectVar> object_var(module->ObjectVarForNPObject(object)); + if (!object_var) // No object for this module yet, make a new one. + object_var = new ObjectVar(module, object); + + if (!object_var) + return PP_MakeVoid(); + + // Convert to a PP_Var, GetReference will AddRef for us. + PP_Var result; + result.type = PP_VARTYPE_OBJECT; + result.value.as_id = object_var->GetReference(); + return result; +} + +// static +scoped_refptr<ObjectVar> ObjectVar::FromPPVar(PP_Var var) { if (var.type != PP_VARTYPE_OBJECT) - return NULL; - return GetNPObjectUnchecked(var); + return scoped_refptr<ObjectVar>(NULL); + return Resource::GetAs<ObjectVar>(var.value.as_id); } -PP_Var StringToPPVar(const std::string& str) { - DCHECK(IsStringUTF8(str)); - return VarFromUtf8(str.data(), str.size()); +// TryCatch -------------------------------------------------------------------- + +TryCatch::TryCatch(PluginModule* module, PP_Var* exception) + : module_(module), + has_exception_(exception && exception->type != PP_VARTYPE_VOID), + exception_(exception) { + WebBindings::pushExceptionHandler(&TryCatch::Catch, this); } -String* GetString(PP_Var var) { - if (var.type != PP_VARTYPE_STRING) - return NULL; - return GetStringUnchecked(var); +TryCatch::~TryCatch() { + WebBindings::popExceptionHandler(); +} + +void TryCatch::SetException(const char* message) { + if (!module_) { + // Don't have a module to make the string. + SetInvalidObjectException(); + return; + } + + if (!has_exception()) { + has_exception_ = true; + if (exception_) + *exception_ = StringVar::StringToPPVar(module_, message, strlen(message)); + } +} + +void TryCatch::SetInvalidObjectException() { + if (!has_exception()) { + has_exception_ = true; + // TODO(brettw) bug 54504: Have a global singleton string that can hold + // a generic error message. + if (exception_) + *exception_ = PP_MakeInt32(1); + } +} + +// static +void TryCatch::Catch(void* self, const char* message) { + static_cast<TryCatch*>(self)->SetException(message); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h index b8c31cc..b618029 100644 --- a/webkit/glue/plugins/pepper_var.h +++ b/webkit/glue/plugins/pepper_var.h @@ -7,39 +7,240 @@ #include <string> -typedef struct _pp_Var PP_Var; -typedef struct _ppb_Var PPB_Var; +#include "webkit/glue/plugins/pepper_resource.h" + +struct PP_Var; +struct PPB_Var; typedef struct NPObject NPObject; typedef struct _NPVariant NPVariant; typedef void* NPIdentifier; namespace pepper { -class String; +// Var ------------------------------------------------------------------------- + +// Represents a non-POD var. This is derived from a resource even though it +// isn't a resource from the plugin's perspective. This allows us to re-use +// the refcounting and the association with the module from the resource code. +class Var : public Resource { + public: + virtual ~Var(); + + // Resource overrides. + virtual Var* AsVar() { return this; } + + // Returns a PP_Var that corresponds to the given NPVariant. The contents of + // the NPVariant will be copied unless the NPVariant corresponds to an + // object. This will handle all Variant types including POD, strings, and + // objects. + // + // The returned PP_Var will have a refcount of 1, this passing ownership of + // the reference to the caller. This is suitable for returning to a plugin. + static PP_Var NPVariantToPPVar(PluginModule* module, + const NPVariant* variant); + + // Returns a NPIdentifier that corresponds to the given PP_Var. The contents + // of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a + // string or integer type. + static NPIdentifier PPVarToNPIdentifier(PP_Var var); + + // Returns a PP_Var corresponding to the given identifier. In the case of + // a string identifier, the string will be allocated associated with the + // given module. A returned string will have a reference count of 1. + static PP_Var NPIdentifierToPPVar(PluginModule* module, NPIdentifier id); + + // Provides access to the manual refcounting of a PP_Var from the plugin's + // perspective. This is different than the AddRef/Release on this scoped + // object. This uses the ResourceTracker, which keeps a separate "plugin + // refcount" that prevents the plugin from messing up our refcounting or + // freeing something out from under us. + // + // You should not generally need to use these functions. However, if you + // call a plugin function that returns a var, it will transfer a ref to us + // (the caller) which in the case of a string or object var will need to + // be released. + // + // Example, assuming we're expecting the plugin to return a string: + // PP_Var rv = some_ppp_interface->DoSomething(a, b, c); + // + // // Get the string value. This will take a reference to the object which + // // will prevent it from being deleted out from under us when we call + // // PluginReleasePPVar(). + // scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); + // + // // Release the reference the plugin gave us when returning the value. + // // This is legal to do for all types of vars. + // Var::PluginReleasePPVar(rv); + // + // // Use the string. + // if (!string) + // return false; // It didn't return a proper string. + // UseTheString(string->value()); + static void PluginAddRefPPVar(PP_Var var); + static void PluginReleasePPVar(PP_Var var); + + // Returns the PPB_Var interface for the plugin to use. + static const PPB_Var* GetInterface(); + + protected: + // This can only be constructed as a StringVar or an ObjectVar. + explicit Var(PluginModule* module); + + private: + DISALLOW_COPY_AND_ASSIGN(Var); +}; + +// StringVar ------------------------------------------------------------------- + +// Represents a string-based Var. +// +// Returning a given string as a PP_Var: +// return StringVar::StringToPPVar(module, my_string); +// +// Converting a PP_Var to a string: +// scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); +// if (!string) +// return false; // Not a string or an invalid var. +// DoSomethingWithTheString(string->value()); +class StringVar : public Var { + public: + StringVar(PluginModule* module, const char* str, uint32 len); + virtual ~StringVar(); + + const std::string& value() const { return value_; } + + // Resource overrides. + virtual StringVar* AsStringVar() { return this; } + + // Helper function to create a PP_Var of type string that contains a copy of + // the given string. The input data must be valid UTF-8 encoded text, if it + // is not valid UTF-8, a NULL var will be returned. + // + // The return value will have a reference count of 1. Internally, this will + // create a StringVar, associate it with a module, and return the reference + // to it in the var. + static PP_Var StringToPPVar(PluginModule* module, const std::string& str); + static PP_Var StringToPPVar(PluginModule* module, + const char* str, uint32 len); + + // Helper function that converts a PP_Var to a string. This will return NULL + // if the PP_Var is not of string type or the string is invalid. + static scoped_refptr<StringVar> FromPPVar(PP_Var var); + + private: + std::string value_; + + DISALLOW_COPY_AND_ASSIGN(StringVar); +}; + +// ObjectVar ------------------------------------------------------------------- + +// Represents a JavaScript object Var. By itself, this represents random +// NPObjects that a given plugin (identified by the resource's module) wants to +// reference. If two different modules reference the same NPObject (like the +// "window" object), then there will be different ObjectVar's (and hence PP_Var +// IDs) for each module. This allows us to track all references owned by a +// given module and free them when the plugin exits independently of other +// plugins that may be running at the same time. +// +// See StringVar for examples, except obviously using NPObjects instead of +// strings. +class ObjectVar : public Var { + public: + virtual ~ObjectVar(); + + // Resource overrides. + virtual ObjectVar* AsObjectVar() { return this; } + + // Returns the underlying NPObject corresponding to this ObjectVar. + // Guaranteed non-NULL. + NPObject* np_object() const { return np_object_; } + + // Helper function to create a PP_Var of type object that contains the given + // NPObject for use byt he given module. Calling this function multiple times + // given the same module + NPObject results in the same PP_Var, assuming that + // there is still a PP_Var with a reference open to it from the previous + // call. + // + // The module is necessary because we can have different modules pointing to + // the same NPObject, and we want to keep their refs separate. + // + // If no ObjectVar currently exists corresponding to the NPObject, one is + // created associated with the given module. + static PP_Var NPObjectToPPVar(PluginModule* module, NPObject* object); + + // Helper function that converts a PP_Var to an object. This will return NULL + // if the PP_Var is not of object type or the object is invalid. + static scoped_refptr<ObjectVar> FromPPVar(PP_Var var); + + protected: + // You should always use FromNPObject to create an ObjectVar. This function + // guarantees that we maintain the 1:1 mapping between NPObject and + // ObjectVar. + ObjectVar(PluginModule* module, NPObject* np_object); + + private: + // Guaranteed non-NULL, this is the underlying object used by WebKit. We + // hold a reference to this object. + NPObject* np_object_; + + DISALLOW_COPY_AND_ASSIGN(ObjectVar); +}; + +// TryCatch -------------------------------------------------------------------- + +// Instantiate this object on the stack to catch V8 exceptions and pass them +// to an optional out parameter supplied by the plugin. +class TryCatch { + public: + // The given exception may be NULL if the consumer isn't interested in + // catching exceptions. If non-NULL, the given var will be updated if any + // exception is thrown (so it must outlive the TryCatch object). + // + // The module associated with the exception is passed so we know which module + // to associate any exception string with. It may be NULL if you don't know + // the module at construction time, in which case you should set it later + // by calling set_module(). + // + // If an exception is thrown when the module is NULL, setting *any* exception + // will result in using the InvalidObjectException. + TryCatch(PluginModule* module, PP_Var* exception); + ~TryCatch(); + + // Get and set the module. This may be NULL (see the constructor). + PluginModule* module() { return module_; } + void set_module(PluginModule* module) { module_ = module; } + + // Returns true is an exception has been thrown. This can be true immediately + // after construction if the var passed to the constructor is non-void. + bool has_exception() const { return has_exception_; } + + // Sets the given exception. If no module has been set yet, the message will + // be ignored (since we have no module to associate the string with) and the + // SetInvalidObjectException() will be used instead. + // + // If an exception has been previously set, this function will do nothing + // (normally you want only the first exception). + void SetException(const char* message); -// There's no class implementing Var since it could represent a number of -// objects. Instead, we just expose a getter for the interface implemented in -// the .cc file here. -const PPB_Var* GetVarInterface(); + // Sets the exception to be a generic message contained in a magic string + // not associated with any module. + void SetInvalidObjectException(); -// Returns a PP_Var of type object that wraps the given NPObject. Calling this -// function multiple times given the same NPObject results in the same PP_Var. -PP_Var NPObjectToPPVar(NPObject* object); + private: + static void Catch(void* self, const char* message); -// Returns the NPObject corresponding to the PP_Var. This pointer has not been -// retained, so you should not call WebBindings::releaseObject unless you first -// call WebBindings::retainObject. Returns NULL if the PP_Var is not an object -// type. -NPObject* GetNPObject(PP_Var var); + PluginModule* module_; -// Returns a PP_Var of type string that contains a copy of the given string. -// The input data must be valid UTF-8 encoded text. -PP_Var StringToPPVar(const std::string& str); + // True if an exception has been thrown. Since the exception itself may be + // NULL if the plugin isn't interested in getting the exception, this will + // always indicate if SetException has been called, regardless of whether + // the exception itself has been stored. + bool has_exception_; -// Returns the String corresponding to the PP_Var. This pointer has not been -// AddRef'd, so you should not call Release! Returns NULL if the PP_Var is not -// a string type. -String* GetString(PP_Var var); + // May be null if the consumer isn't interesting in catching exceptions. + PP_Var* exception_; +}; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc index df8aae0..32903b0 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.cc +++ b/webkit/glue/plugins/pepper_webplugin_impl.cc @@ -4,7 +4,6 @@ #include "webkit/glue/plugins/pepper_webplugin_impl.h" -#include "base/file_path.h" #include "base/message_loop.h" #include "third_party/ppapi/c/pp_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h" @@ -74,11 +73,16 @@ void WebPluginImpl::destroy() { } NPObject* WebPluginImpl::scriptableObject() { - return GetNPObject(instance_->GetInstanceObject()); + scoped_refptr<ObjectVar> object( + ObjectVar::FromPPVar(instance_->GetInstanceObject())); + if (object) + return object->np_object(); + return NULL; } void WebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) { - instance_->Paint(canvas, plugin_rect_, rect); + if (!instance_->IsFullscreen()) + instance_->Paint(canvas, plugin_rect_, rect); } void WebPluginImpl::updateGeometry( @@ -87,10 +91,12 @@ void WebPluginImpl::updateGeometry( const WebVector<WebRect>& cut_outs_rects, bool is_visible) { plugin_rect_ = window_rect; - instance_->ViewChanged(plugin_rect_, clip_rect); + if (!instance_->IsFullscreen()) + instance_->ViewChanged(plugin_rect_, clip_rect); } void WebPluginImpl::updateFocus(bool focused) { + instance_->SetWebKitFocus(focused); } void WebPluginImpl::updateVisibility(bool visible) { @@ -102,6 +108,8 @@ bool WebPluginImpl::acceptsInputEvents() { bool WebPluginImpl::handleInputEvent(const WebKit::WebInputEvent& event, WebKit::WebCursorInfo& cursor_info) { + if (instance_->IsFullscreen()) + return false; return instance_->HandleInputEvent(event, &cursor_info); } @@ -123,7 +131,7 @@ void WebPluginImpl::didReceiveData(const char* data, int data_length) { void WebPluginImpl::didFinishLoading() { if (document_loader_) { - document_loader_->didFinishLoading(NULL); + document_loader_->didFinishLoading(NULL, 0); document_loader_ = NULL; } } diff --git a/webkit/glue/plugins/pepper_widget.cc b/webkit/glue/plugins/pepper_widget.cc index 74b0e40..1ba5280 100644 --- a/webkit/glue/plugins/pepper_widget.cc +++ b/webkit/glue/plugins/pepper_widget.cc @@ -5,10 +5,10 @@ #include "webkit/glue/plugins/pepper_widget.h" #include "base/logging.h" +#include "third_party/ppapi/c/dev/ppb_widget_dev.h" +#include "third_party/ppapi/c/dev/ppp_widget_dev.h" #include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/ppb_widget.h" -#include "third_party/ppapi/c/ppp_widget.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -27,10 +27,13 @@ bool Paint(PP_Resource resource, const PP_Rect* rect, PP_Resource image_id) { return false; scoped_refptr<ImageData> image(Resource::GetAs<ImageData>(image_id)); - return widget && widget->Paint(rect, image); + if (!image) + return false; + + return widget->Paint(rect, image); } -bool HandleEvent(PP_Resource resource, const PP_Event* event) { +bool HandleEvent(PP_Resource resource, const PP_InputEvent* event) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); return widget && widget->HandleEvent(event); } @@ -46,7 +49,7 @@ void SetLocation(PP_Resource resource, const PP_Rect* location) { widget->SetLocation(location); } -const PPB_Widget ppb_widget = { +const PPB_Widget_Dev ppb_widget = { &IsWidget, &Paint, &HandleEvent, @@ -65,7 +68,7 @@ Widget::~Widget() { } // static -const PPB_Widget* Widget::GetInterface() { +const PPB_Widget_Dev* Widget::GetInterface() { return &ppb_widget; } @@ -80,8 +83,8 @@ void Widget::SetLocation(const PP_Rect* location) { } void Widget::Invalidate(const PP_Rect* dirty) { - const PPP_Widget* widget = static_cast<const PPP_Widget*>( - module()->GetPluginInterface(PPP_WIDGET_INTERFACE)); + const PPP_Widget_Dev* widget = static_cast<const PPP_Widget_Dev*>( + module()->GetPluginInterface(PPP_WIDGET_DEV_INTERFACE)); if (!widget) return; ScopedResourceId resource(this); diff --git a/webkit/glue/plugins/pepper_widget.h b/webkit/glue/plugins/pepper_widget.h index 048a718..47826e3 100644 --- a/webkit/glue/plugins/pepper_widget.h +++ b/webkit/glue/plugins/pepper_widget.h @@ -9,8 +9,8 @@ #include "third_party/ppapi/c/pp_rect.h" #include "webkit/glue/plugins/pepper_resource.h" -typedef struct _ppb_Widget PPB_Widget; -typedef struct _pp_Event PP_Event; +struct PPB_Widget_Dev; +struct PP_InputEvent; namespace pepper { @@ -24,14 +24,14 @@ class Widget : public Resource { // Returns a pointer to the interface implementing PPB_Widget that is // exposed to the plugin. - static const PPB_Widget* GetInterface(); + static const PPB_Widget_Dev* GetInterface(); // Resource overrides. Widget* AsWidget() { return this; } // PPB_Widget implementation. virtual bool Paint(const PP_Rect* rect, ImageData* image) = 0; - virtual bool HandleEvent(const PP_Event* event) = 0; + virtual bool HandleEvent(const PP_InputEvent* event) = 0; bool GetLocation(PP_Rect* location); void SetLocation(const PP_Rect* location); diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index fe1d7ef..a1a6d5f 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -13,6 +13,7 @@ #include "base/sys_info.h" #endif #include "base/sys_string_conversions.h" +#include "base/utf_string_conversions.h" #include "net/base/net_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" #include "webkit/glue/webkit_glue.h" @@ -449,7 +450,7 @@ static NPError PostURLNotify(NPP id, base::SysNativeMBToWide(file_path_ascii)); } - file_util::FileInfo post_file_info = {0}; + base::PlatformFileInfo post_file_info = {0}; if (!file_util::GetFileInfo(file_path, &post_file_info) || post_file_info.is_directory) return NPERR_FILE_NOT_FOUND; diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc index 8506623..f7b3bf7 100644 --- a/webkit/glue/plugins/plugin_instance.cc +++ b/webkit/glue/plugins/plugin_instance.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,7 @@ #include "base/file_util.h" #include "base/message_loop.h" -#include "base/string_util.h" +#include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/plugins/plugin_host.h" @@ -489,13 +489,13 @@ void PluginInstance::RequestRead(NPStream* stream, NPByteRange* range_list) { std::string range_info = "bytes="; while (range_list) { - range_info += IntToString(range_list->offset); - range_info += "-"; - range_info += IntToString(range_list->offset + range_list->length - 1); + range_info += base::IntToString(range_list->offset); + range_info.push_back('-'); + range_info += + base::IntToString(range_list->offset + range_list->length - 1); range_list = range_list->next; - if (range_list) { - range_info += ","; - } + if (range_list) + range_info.push_back(','); } if (plugin_data_stream_) { diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h index 36bf601..0dd3ee4 100644 --- a/webkit/glue/plugins/plugin_instance.h +++ b/webkit/glue/plugins/plugin_instance.h @@ -9,7 +9,6 @@ #define WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__ #include <map> -#include <set> #include <stack> #include <string> #include <vector> diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc index 877548e..9a0770e 100644 --- a/webkit/glue/plugins/plugin_lib.cc +++ b/webkit/glue/plugins/plugin_lib.cc @@ -98,8 +98,9 @@ NPPluginFuncs* PluginLib::functions() { } NPError PluginLib::NP_Initialize() { - LOG(INFO) << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value() << - "): initialized=" << initialized_; + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value() + << "): initialized=" << initialized_; if (initialized_) return NPERR_NO_ERROR; @@ -123,8 +124,9 @@ NPError PluginLib::NP_Initialize() { } #endif // OS_MACOSX #endif - LOG(INFO) << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value() << - "): result=" << rv; + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "PluginLib::NP_Initialize(" << web_plugin_info_.path.value() + << "): result=" << rv; initialized_ = (rv == NPERR_NO_ERROR); return rv; } @@ -165,7 +167,7 @@ bool PluginLib::Load() { if (!internal_) { library = base::LoadNativeLibrary(web_plugin_info_.path); if (library == 0) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Couldn't load plugin " << web_plugin_info_.path.value(); return rv; } @@ -215,12 +217,12 @@ bool PluginLib::Load() { if (!internal_) { if (rv) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Plugin " << web_plugin_info_.path.value() << " loaded successfully."; library_ = library; } else { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Plugin " << web_plugin_info_.path.value() << " failed to load, unloading."; base::UnloadNativeLibrary(library); @@ -277,14 +279,14 @@ void PluginLib::Unload() { FreePluginLibraryTask* free_library_task = new FreePluginLibraryTask(skip_unload_ ? NULL : library_, entry_points_.np_shutdown); - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Scheduling delayed unload for plugin " << web_plugin_info_.path.value(); MessageLoop::current()->PostTask(FROM_HERE, free_library_task); } else { Shutdown(); if (!skip_unload_) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Unloading plugin " << web_plugin_info_.path.value(); base::UnloadNativeLibrary(library_); } diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h index 647916e..ca46e41 100644 --- a/webkit/glue/plugins/plugin_lib.h +++ b/webkit/glue/plugins/plugin_lib.h @@ -9,13 +9,13 @@ #include <vector> #include "base/basictypes.h" -#include "base/file_path.h" #include "base/native_library.h" #include "base/ref_counted.h" #include "build/build_config.h" #include "webkit/glue/plugins/plugin_list.h" #include "webkit/glue/plugins/webplugin.h" +class FilePath; struct WebPluginInfo; namespace NPAPI { diff --git a/webkit/glue/plugins/plugin_lib_mac.mm b/webkit/glue/plugins/plugin_lib_mac.mm index 263b3b4..07da77c 100644 --- a/webkit/glue/plugins/plugin_lib_mac.mm +++ b/webkit/glue/plugins/plugin_lib_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,6 +9,7 @@ #include "base/native_library.h" #include "base/scoped_cftyperef.h" #include "base/scoped_ptr.h" +#include "base/string_split.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc index dbc64ed..fb813b6 100644 --- a/webkit/glue/plugins/plugin_lib_posix.cc +++ b/webkit/glue/plugins/plugin_lib_posix.cc @@ -17,6 +17,7 @@ #include "base/eintr_wrapper.h" #include "base/file_util.h" +#include "base/string_split.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" @@ -118,14 +119,14 @@ void UnwrapNSPluginWrapper(void **dl, FilePath* unwrapped_path) { if (!newdl) { // We couldn't load the unwrapped plugin for some reason, despite // being able to load the wrapped one. Just use the wrapped one. - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Could not use unwrapped nspluginwrapper plugin " << unwrapped_path->value() << ", using the wrapped one."; return; } // Unload the wrapped plugin, and use the wrapped plugin instead. - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Using unwrapped version " << unwrapped_path->value() << " of nspluginwrapper-wrapped plugin."; base::UnloadNativeLibrary(*dl); @@ -144,7 +145,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename, // Skip files that aren't appropriate for our architecture. if (!ELFMatchesCurrentArchitecture(filename)) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Skipping plugin " << filename.value() << " because it doesn't match the current architecture."; return false; @@ -152,7 +153,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename, void* dl = base::LoadNativeLibrary(filename); if (!dl) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "While reading plugin info, unable to load library " << filename.value() << ", skipping."; return false; @@ -193,12 +194,12 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename, if (description) info->desc = UTF8ToUTF16(description); - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Got info for plugin " << filename.value() << " Name = \"" << UTF16ToUTF8(info->name) << "\", Description = \"" << UTF16ToUTF8(info->desc) << "\"."; } else { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Plugin " << filename.value() << " has no GetValue() and probably won't work."; } diff --git a/webkit/glue/plugins/plugin_lib_unittest.cc b/webkit/glue/plugins/plugin_lib_unittest.cc index a52510b..5ac6bdc 100644 --- a/webkit/glue/plugins/plugin_lib_unittest.cc +++ b/webkit/glue/plugins/plugin_lib_unittest.cc @@ -5,6 +5,7 @@ #include "webkit/glue/plugins/plugin_lib.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/webkit/glue/plugins/plugin_lib_win.cc b/webkit/glue/plugins/plugin_lib_win.cc index 00f6243..382c2c8 100644 --- a/webkit/glue/plugins/plugin_lib_win.cc +++ b/webkit/glue/plugins/plugin_lib_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,12 +6,13 @@ #include "base/file_version_info.h" #include "base/file_version_info_win.h" +#include "base/logging.h" #include "base/path_service.h" #include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_list.h" -namespace NPAPI -{ +namespace NPAPI { + bool PluginLib::ReadWebPluginInfo(const FilePath &filename, WebPluginInfo* info) { // On windows, the way we get the mime types for the library is @@ -21,8 +22,12 @@ bool PluginLib::ReadWebPluginInfo(const FilePath &filename, // video/quicktime|audio/aiff|image/jpeg scoped_ptr<FileVersionInfo> version_info( FileVersionInfo::CreateFileVersionInfo(filename.value())); - if (!version_info.get()) + if (!version_info.get()) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Could not get version info for plugin " + << filename.value(); return false; + } FileVersionInfoWin* version_info_win = static_cast<FileVersionInfoWin*>(version_info.get()); diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc index a3412d7..b2a7634 100644 --- a/webkit/glue/plugins/plugin_list.cc +++ b/webkit/glue/plugins/plugin_list.cc @@ -9,9 +9,9 @@ #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/logging.h" +#include "base/string_split.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "base/time.h" #include "googleurl/src/gurl.h" #include "net/base/mime_util.h" #include "webkit/glue/plugins/plugin_constants_win.h" @@ -45,8 +45,11 @@ void PluginList::RefreshPlugins() { } void PluginList::AddExtraPluginPath(const FilePath& plugin_path) { + // Chrome OS only loads plugins from /opt/google/chrome/plugins. +#if !defined(OS_CHROMEOS) AutoLock lock(lock_); extra_plugin_paths_.push_back(plugin_path); +#endif } void PluginList::RemoveExtraPluginPath(const FilePath& plugin_path) { @@ -59,8 +62,11 @@ void PluginList::RemoveExtraPluginPath(const FilePath& plugin_path) { } void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) { + // Chrome OS only loads plugins from /opt/google/chrome/plugins. +#if !defined(OS_CHROMEOS) AutoLock lock(lock_); extra_plugin_dirs_.push_back(plugin_dir); +#endif } void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) { @@ -108,8 +114,11 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, info->mime_types.clear(); - if (mime_types.empty()) + if (mime_types.empty()) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Plugin " << pvi.product_name << " has no MIME types, skipping"; return false; + } info->name = WideToUTF16(pvi.product_name); info->desc = WideToUTF16(pvi.file_description); @@ -168,8 +177,6 @@ void PluginList::LoadPlugins(bool refresh) { internal_plugins = internal_plugins_; } - base::TimeTicks start_time = base::TimeTicks::Now(); - std::vector<WebPluginInfo> new_plugins; std::set<FilePath> visited_plugins; @@ -209,10 +216,6 @@ void PluginList::LoadPlugins(bool refresh) { if (webkit_glue::IsDefaultPluginEnabled()) LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins); - base::TimeTicks end_time = base::TimeTicks::Now(); - base::TimeDelta elapsed = end_time - start_time; - DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms."; - // Only update the data now since loading plugins can take a while. AutoLock lock(lock_); @@ -230,6 +233,9 @@ void PluginList::LoadPlugins(bool refresh) { void PluginList::LoadPlugin(const FilePath& path, std::vector<WebPluginInfo>* plugins) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Loading plugin " << path.value(); + WebPluginInfo plugin_info; const PluginEntryPoints* entry_points; diff --git a/webkit/glue/plugins/plugin_list_mac.mm b/webkit/glue/plugins/plugin_list_mac.mm index 16bde9d..ee6c6ad 100644 --- a/webkit/glue/plugins/plugin_list_mac.mm +++ b/webkit/glue/plugins/plugin_list_mac.mm @@ -92,6 +92,14 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, if (IsBlacklistedPlugin(info)) return false; + // Flip4Mac has a reproducible hang during a synchronous call from the render + // with certain content types (as well as a common crash). Disable by default + // to minimize those issues, but don't blacklist it so that users can choose + // to enable it. + if (StartsWith(info.name, ASCIIToUTF16("Flip4Mac Windows Media Plugin"), + false)) + DisablePlugin(info.path); + // Hierarchy check // (we're loading plugins hierarchically from Library folders, so plugins we // encounter earlier must override plugins we encounter later) diff --git a/webkit/glue/plugins/plugin_list_posix.cc b/webkit/glue/plugins/plugin_list_posix.cc index 1fbd76f..b23909b 100644 --- a/webkit/glue/plugins/plugin_list_posix.cc +++ b/webkit/glue/plugins/plugin_list_posix.cc @@ -7,6 +7,7 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/sha1.h" +#include "base/string_split.h" #include "base/string_util.h" #include "build/build_config.h" @@ -121,6 +122,8 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { PathService::Get(base::DIR_EXE, &dir); plugin_dirs->push_back(dir.Append("plugins")); + // Chrome OS only loads plugins from /opt/google/chrome/plugins. +#if !defined(OS_CHROMEOS) // Mozilla code to reference: // http://mxr.mozilla.org/firefox/ident?i=NS_APP_PLUGINS_DIR_LIST // and tens of accompanying files (mxr is very helpful). @@ -156,7 +159,8 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { plugin_dirs->push_back(FilePath("/usr/lib64/mozilla/plugins")); plugin_dirs->push_back(FilePath("/usr/lib64/firefox/plugins")); plugin_dirs->push_back(FilePath("/usr/lib64/xulrunner-addons/plugins")); -#endif +#endif // defined(ARCH_CPU_64_BITS) +#endif // !defined(OS_CHROMEOS) } void PluginList::LoadPluginsFromDir(const FilePath& dir_path, @@ -183,18 +187,18 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path, // symlinks. FilePath orig_path = path; file_util::AbsolutePath(&path); - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Resolved " << orig_path.value() << " -> " << path.value(); if (visited_plugins->find(path) != visited_plugins->end()) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Skipping duplicate instance of " << path.value(); continue; } visited_plugins->insert(path); if (IsBlacklistedPlugin(path)) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Skipping blacklisted plugin " << path.value(); continue; } @@ -209,14 +213,15 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path, // Go back to the old path. path = orig_path; } else { - LOG(ERROR) << "Flash misbehaves when used from a directory containing " - << kNetscapeInPath << ", so skipping " << orig_path.value(); + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Flash misbehaves when used from a directory containing " + << kNetscapeInPath << ", so skipping " << orig_path.value(); continue; } } // Get mtime. - file_util::FileInfo info; + base::PlatformFileInfo info; if (!file_util::GetFileInfo(path, &info)) continue; @@ -232,14 +237,13 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path, } } - bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, std::vector<WebPluginInfo>* plugins) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Considering " << info.path.value() << " (" << info.name << ")"; if (IsUndesirablePlugin(info)) { - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << info.path.value() << " is undesirable."; // See if we have a better version of this plugin. @@ -248,7 +252,7 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, !IsUndesirablePlugin(plugins->at(i))) { // Skip the current undesirable one so we can use the better one // we just found. - LOG_IF(INFO, PluginList::DebugPluginLoading()) + LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Skipping " << info.path.value() << ", preferring " << plugins->at(i).path.value(); return false; diff --git a/webkit/glue/plugins/plugin_list_win.cc b/webkit/glue/plugins/plugin_list_win.cc index 1c91916..b5ded9e 100644 --- a/webkit/glue/plugins/plugin_list_win.cc +++ b/webkit/glue/plugins/plugin_list_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -14,6 +14,8 @@ #include "base/path_service.h" #include "base/registry.h" #include "base/scoped_ptr.h" +#include "base/string_number_conversions.h" +#include "base/string_split.h" #include "base/string_util.h" #include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_lib.h" @@ -65,7 +67,7 @@ bool GetInstalledPath(const TCHAR* app, FilePath* out) { reg_path.append(L"\\"); reg_path.append(app); - RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str()); + RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ); std::wstring path; if (key.ReadValue(kRegistryPath, &path)) { *out = FilePath(path); @@ -86,7 +88,7 @@ void GetPluginsInRegistryDirectory( std::wstring reg_path = registry_folder; reg_path.append(L"\\"); reg_path.append(iter.Name()); - RegKey key(root_key, reg_path.c_str()); + RegKey key(root_key, reg_path.c_str(), KEY_READ); std::wstring path; if (key.ReadValue(kRegistryPath, &path)) @@ -313,8 +315,10 @@ bool IsNewerVersion(const std::wstring& a, const std::wstring& b) { if (a_ver.size() != b_ver.size()) return false; for (size_t i = 0; i < a_ver.size(); i++) { - int cur_a = StringToInt(a_ver[i]); - int cur_b = StringToInt(b_ver[i]); + int cur_a, cur_b; + base::StringToInt(a_ver[i], &cur_a); + base::StringToInt(b_ver[i], &cur_b); + if (cur_a > cur_b) return false; if (cur_a < cur_b) @@ -370,9 +374,9 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, SplitString(info.version, '.', &ver); int major, minor, update; if (ver.size() == 4 && - StringToInt(ver[0], &major) && - StringToInt(ver[1], &minor) && - StringToInt(ver[2], &update)) { + base::StringToInt(ver[0], &major) && + base::StringToInt(ver[1], &minor) && + base::StringToInt(ver[2], &update)) { if (major == 6 && minor == 0 && update < 120) return false; // Java SE6 Update 11 or older. } diff --git a/webkit/glue/plugins/plugin_stream.h b/webkit/glue/plugins/plugin_stream.h index f15ea66..c17faaf 100644 --- a/webkit/glue/plugins/plugin_stream.h +++ b/webkit/glue/plugins/plugin_stream.h @@ -2,13 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__ -#define WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__ +#ifndef WEBKIT_GLUE_PLUGINS_PLUGIN_STREAM_H_ +#define WEBKIT_GLUE_PLUGINS_PLUGIN_STREAM_H_ + +#include "build/build_config.h" #include <string> #include <vector> +#if defined(OS_POSIX) #include "base/file_path.h" +#endif #include "base/ref_counted.h" #include "third_party/npapi/bindings/npapi.h" @@ -110,7 +114,8 @@ class PluginStream : public base::RefCounted<PluginStream> { // Send the data to the plugin, returning how many bytes it accepted, or -1 // if an error occurred. - int TryWriteToPlugin(const char *buf, const int length, const int data_offset); + int TryWriteToPlugin(const char *buf, const int length, + const int data_offset); // The callback which calls TryWriteToPlugin. void OnDelayDelivery(); @@ -141,6 +146,6 @@ class PluginStream : public base::RefCounted<PluginStream> { DISALLOW_COPY_AND_ASSIGN(PluginStream); }; -} // namespace NPAPI +} // namespace NPAPI -#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__ +#endif // WEBKIT_GLUE_PLUGINS_PLUGIN_STREAM_H_ diff --git a/webkit/glue/plugins/ppb_private.h b/webkit/glue/plugins/ppb_private.h index a0956f0..218f73a 100644 --- a/webkit/glue/plugins/ppb_private.h +++ b/webkit/glue/plugins/ppb_private.h @@ -5,17 +5,103 @@ #ifndef WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ #define WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ +#include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/pp_var.h" #define PPB_PRIVATE_INTERFACE "PPB_Private;1" -typedef enum _pp_ResourceString { +typedef enum { PP_RESOURCESTRING_PDFGETPASSWORD = 0, } PP_ResourceString; -typedef struct _ppb_Private { +typedef enum { + PP_RESOURCEIMAGE_PDF_BUTTON_FTH = 0, + PP_RESOURCEIMAGE_PDF_BUTTON_FTH_HOVER = 1, + PP_RESOURCEIMAGE_PDF_BUTTON_FTH_PRESSED = 2, + PP_RESOURCEIMAGE_PDF_BUTTON_FTW = 3, + PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER = 4, + PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED = 5, + PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN = 6, + PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER = 7, + PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED = 8, + PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT = 9, + PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER = 10, + PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED = 11, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0 = 12, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1 = 13, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2 = 14, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3 = 15, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4 = 16, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5 = 17, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6 = 18, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7 = 19, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8 = 20, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9 = 21, + PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND = 22, +} PP_ResourceImage; + +typedef enum { + PP_PRIVATEFONTPITCH_DEFAULT = 0, + PP_PRIVATEFONTPITCH_FIXED = 1 +} PP_PrivateFontPitch; + +typedef enum { + PP_PRIVATEFONTFAMILY_DEFAULT = 0, + PP_PRIVATEFONTFAMILY_ROMAN = 1, + PP_PRIVATEFONTFAMILY_SCRIPT = 2 +} PP_PrivateFontFamily; + +typedef enum { + PP_PRIVATEFONTCHARSET_ANSI = 0, + PP_PRIVATEFONTCHARSET_DEFAULT = 1, + PP_PRIVATEFONTCHARSET_SYMBOL = 2, + PP_PRIVATEFONTCHARSET_MAC = 77, + PP_PRIVATEFONTCHARSET_SHIFTJIS = 128, + PP_PRIVATEFONTCHARSET_HANGUL = 129, + PP_PRIVATEFONTCHARSET_JOHAB = 130, + PP_PRIVATEFONTCHARSET_GB2312 =134, + PP_PRIVATEFONTCHARSET_CHINESEBIG5 = 136, + PP_PRIVATEFONTCHARSET_GREEK = 161, + PP_PRIVATEFONTCHARSET_TURKISH = 162, + PP_PRIVATEFONTCHARSET_VIETNAMESE = 163, + PP_PRIVATEFONTCHARSET_HEBREW = 177, + PP_PRIVATEFONTCHARSET_ARABIC = 178, + PP_PRIVATEFONTCHARSET_BALTIC = 186, + PP_PRIVATEFONTCHARSET_RUSSIAN = 204, + PP_PRIVATEFONTCHARSET_THAI = 222, + PP_PRIVATEFONTCHARSET_EASTEUROPE = 238, + PP_PRIVATEFONTCHARSET_OEM = 255 +} PP_PrivateFontCharset; + +struct PP_PrivateFontFileDescription { + const char* face; + uint32_t weight; + bool italic; + PP_PrivateFontPitch pitch; + PP_PrivateFontFamily family; + PP_PrivateFontCharset charset; +}; + +struct PPB_Private { // Returns a localized string. - PP_Var (*GetLocalizedString)(PP_ResourceString string_id); -} PPB_Private; + PP_Var (*GetLocalizedString)(PP_Module module, PP_ResourceString string_id); + + // Returns a resource image. + PP_Resource (*GetResourceImage)(PP_Module module, + PP_ResourceImage image_id); + + // Returns a resource identifying a font file corresponding to the given font + // request after applying the browser-specific fallback. Linux only. + PP_Resource (*GetFontFileWithFallback)( + PP_Module module, + const PP_PrivateFontFileDescription* description); + + // Given a resource previously returned by GetFontFileWithFallback, returns + // a pointer to the requested font table. Linux only. + bool (*GetFontTableForPrivateFontFile)(PP_Resource font_file, + uint32_t table, + void* output, + uint32_t* output_length); +}; #endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ diff --git a/webkit/glue/plugins/test/npapi_test.cc b/webkit/glue/plugins/test/npapi_test.cc index d7c4fa7..895a842 100644 --- a/webkit/glue/plugins/test/npapi_test.cc +++ b/webkit/glue/plugins/test/npapi_test.cc @@ -66,13 +66,55 @@ EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* pFuncs) { return NPAPIClient::PluginClient::GetEntryPoints(pFuncs); } -EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* pFuncs) { - return NPAPIClient::PluginClient::Initialize(pFuncs); -} - EXPORT NPError API_CALL NP_Shutdown() { return NPAPIClient::PluginClient::Shutdown(); } + +#if defined(OS_WIN) || defined(OS_MACOSX) +EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnFuncs) { + return NPAPIClient::PluginClient::Initialize(npnFuncs); +} +#elif defined(OS_POSIX) +EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnFuncs, + NPPluginFuncs* nppFuncs) { + NPError error = NPAPIClient::PluginClient::Initialize(npnFuncs); + if (error == NPERR_NO_ERROR) { + error = NP_GetEntryPoints(nppFuncs); + } + return error; +} + +EXPORT NPError API_CALL NP_GetValue(NPP instance, NPPVariable variable, + void* value) { + NPError err = NPERR_NO_ERROR; + + switch (variable) { + case NPPVpluginNameString: + *(static_cast<const char**>(value)) = "NPAPI Test Plugin"; + break; + case NPPVpluginDescriptionString: + *(static_cast<const char**>(value)) = + "Simple NPAPI plug-in for Chromium unit tests"; + break; + case NPPVpluginNeedsXEmbed: + *(static_cast<NPBool*>(value)) = true; + break; + default: + err = NPERR_GENERIC_ERROR; + break; + } + + return err; +} + +EXPORT const char* API_CALL NP_GetMIMEDescription(void) { + // The layout test LayoutTests/fast/js/navigator-mimeTypes-length.html + // asserts that the number of mimetypes handled by plugins should be + // greater than the number of plugins. We specify a mimetype here so + // this plugin has at least one. + return "application/vnd.npapi-test:npapitest:test npapi"; +} +#endif // OS_POSIX } // extern "C" namespace WebCore { diff --git a/webkit/glue/plugins/test/plugin_arguments_test.cc b/webkit/glue/plugins/test/plugin_arguments_test.cc index ee6d2c0..46ccf43 100644 --- a/webkit/glue/plugins/test/plugin_arguments_test.cc +++ b/webkit/glue/plugins/test/plugin_arguments_test.cc @@ -1,9 +1,10 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/basictypes.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "webkit/glue/plugins/test/plugin_arguments_test.h" @@ -45,7 +46,7 @@ NPError PluginArgumentsTest::New(uint16 mode, int16 argc, int size = atoi(size_string); for (int index = 1; index <= max_args; index++) { - std::string arg_name = StringPrintf("%s%d", "val", index); + std::string arg_name = base::StringPrintf("%s%d", "val", index); const char *val_string = GetArgValue(arg_name.c_str(), argc, argn, argv); ExpectAsciiStringNotEqual(val_string, (const char*)NULL); diff --git a/webkit/glue/plugins/test/plugin_geturl_test.cc b/webkit/glue/plugins/test/plugin_geturl_test.cc index f321b4b..aedf582 100644 --- a/webkit/glue/plugins/test/plugin_geturl_test.cc +++ b/webkit/glue/plugins/test/plugin_geturl_test.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,6 +8,8 @@ #include "base/basictypes.h" #include "base/file_util.h" +#include "base/string_number_conversions.h" +#include "base/utf_string_conversions.h" // url for "self". The %22%22 is to make a statement for javascript to // evaluate and return. @@ -357,7 +359,7 @@ void PluginGetURLTest::URLNotify(const char* url, NPReason reason, void* data) { case BOGUS_URL_STREAM_ID: if (reason != NPRES_NETWORK_ERR) { std::string err = "BOGUS_URL received unexpected URLNotify status: "; - err.append(IntToString(reason)); + err.append(base::IntToString(reason)); SetError(err); } tests_in_progress_--; diff --git a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc index b62a764..10b3239 100644 --- a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc +++ b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc @@ -17,7 +17,8 @@ NPObjectDeletePluginInNPN_Evaluate* NPObjectLifetimeTest::NPObjectLifetimeTest(NPP id, NPNetscapeFuncs *host_functions) : PluginTest(id, host_functions), - other_plugin_instance_object_(NULL) { + other_plugin_instance_object_(NULL), + timer_id_(0) { } NPError NPObjectLifetimeTest::SetWindow(NPWindow* pNPWindow) { @@ -30,8 +31,8 @@ NPError NPObjectLifetimeTest::SetWindow(NPWindow* pNPWindow) { // We attempt to retreive the NPObject for the plugin instance identified // by the NPObjectLifetimeTestInstance2 class as it may not have been // instantiated yet. - SetTimer(window_handle, kNPObjectLifetimeTimer, kNPObjectLifetimeTimerElapse, - TimerProc); + timer_id_ = SetTimer(window_handle, kNPObjectLifetimeTimer, + kNPObjectLifetimeTimerElapse, TimerProc); } return NPERR_NO_ERROR; } @@ -40,10 +41,11 @@ void CALLBACK NPObjectLifetimeTest::TimerProc( HWND window, UINT message, UINT timer_id, unsigned long elapsed_milli_seconds) { - KillTimer(window, kNPObjectLifetimeTimer); NPObjectLifetimeTest* this_instance = reinterpret_cast<NPObjectLifetimeTest*> (::GetProp(window, L"Plugin_Instance")); + KillTimer(window, this_instance->timer_id_); + this_instance->timer_id_ = 0; this_instance->other_plugin_instance_object_ = NPObjectLifetimeTestInstance2::plugin_instance_object_; @@ -107,7 +109,7 @@ NPObjectDeletePluginInNPN_Evaluate::NPObjectDeletePluginInNPN_Evaluate( NPP id, NPNetscapeFuncs *host_functions) : PluginTest(id, host_functions), plugin_instance_object_(NULL), - npn_evaluate_timer_proc_set_(false) { + timer_id_(0) { g_npn_evaluate_test_instance_ = this; } @@ -128,12 +130,10 @@ NPError NPObjectDeletePluginInNPN_Evaluate::SetWindow(NPWindow* np_window) { // while it is being used in webkit as this leads to crashes and is a // more accurate representation of the renderer crash as described in // http://b/issue?id=1134683. - if (!npn_evaluate_timer_proc_set_) { - npn_evaluate_timer_proc_set_ = true; - SetTimer(window_handle, kNPObjectLifetimeTimer, kNPObjectLifetimeTimerElapse, - TimerProc); + if (!timer_id_) { + timer_id_ = SetTimer(window_handle, kNPObjectLifetimeTimer, + kNPObjectLifetimeTimerElapse, TimerProc); } - return NPERR_NO_ERROR; } @@ -141,7 +141,8 @@ void CALLBACK NPObjectDeletePluginInNPN_Evaluate::TimerProc( HWND window, UINT message, UINT timer_id, unsigned long elapsed_milli_seconds) { - KillTimer(window, kNPObjectLifetimeTimer); + KillTimer(window, g_npn_evaluate_test_instance_->timer_id_); + g_npn_evaluate_test_instance_->timer_id_ = 0; NPObject *window_obj = NULL; g_npn_evaluate_test_instance_->HostFunctions()->getvalue( g_npn_evaluate_test_instance_->id(), NPNVWindowNPObject, diff --git a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h index 4303d99..60d0314 100644 --- a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h +++ b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.h @@ -30,6 +30,7 @@ class NPObjectLifetimeTest : public PluginTest { #if defined(OS_WIN) static void CALLBACK TimerProc(HWND window, UINT message, UINT timer_id, unsigned long elapsed_milli_seconds); + UINT_PTR timer_id_; #endif DISALLOW_IMPLICIT_CONSTRUCTORS(NPObjectLifetimeTest); }; @@ -67,10 +68,10 @@ class NPObjectDeletePluginInNPN_Evaluate : public PluginTest { #if defined(OS_WIN) static void CALLBACK TimerProc(HWND window, UINT message, UINT timer_id, unsigned long elapsed_milli_seconds); + UINT_PTR timer_id_; #endif private: - bool npn_evaluate_timer_proc_set_; static NPObjectDeletePluginInNPN_Evaluate* g_npn_evaluate_test_instance_; DISALLOW_IMPLICIT_CONSTRUCTORS(NPObjectDeletePluginInNPN_Evaluate); diff --git a/webkit/glue/plugins/test/plugin_schedule_timer_test.h b/webkit/glue/plugins/test/plugin_schedule_timer_test.h index 9ca947f..e3e6505 100644 --- a/webkit/glue/plugins/test/plugin_schedule_timer_test.h +++ b/webkit/glue/plugins/test/plugin_schedule_timer_test.h @@ -1,12 +1,10 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_SCHEDULE_TIMER_TEST_H #define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_SCHEDULE_TIMER_TEST_H -#include <vector> - #include "base/at_exit.h" #include "base/time.h" #include "webkit/glue/plugins/test/plugin_test.h" diff --git a/webkit/glue/plugins/test/plugin_test.h b/webkit/glue/plugins/test/plugin_test.h index f06307e..eed6e3f 100644 --- a/webkit/glue/plugins/test/plugin_test.h +++ b/webkit/glue/plugins/test/plugin_test.h @@ -1,12 +1,13 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H__ -#define WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H__ +#ifndef WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H_ +#define WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H_ #include <string> +#include "base/string_number_conversions.h" #include "base/string_util.h" #include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/nphostapi.h" @@ -82,9 +83,9 @@ class PluginTest { if (val1 != val2) { std::string err; err = "Expected Equal for '"; - err.append(IntToString(val1)); + err.append(base::IntToString(val1)); err.append("' and '"); - err.append(IntToString(val2)); + err.append(base::IntToString(val2)); err.append("'"); SetError(err); } @@ -128,4 +129,4 @@ class PluginTest { } // namespace NPAPIClient -#endif // WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H__ +#endif // WEBKIT_PORT_PLUGINS_TEST_PLUGIN_TEST_H_ diff --git a/webkit/glue/plugins/test/plugin_test_factory.cc b/webkit/glue/plugins/test/plugin_test_factory.cc index e2b42b3..62a3977 100644 --- a/webkit/glue/plugins/test/plugin_test_factory.cc +++ b/webkit/glue/plugins/test/plugin_test_factory.cc @@ -66,7 +66,8 @@ PluginTest* CreatePluginTest(const std::string& test_name, new_test = new NPObjectLifetimeTestInstance2(instance, host_functions); } else if (test_name == "new_fails") { new_test = new NewFailsTest(instance, host_functions); - } else if (test_name == "npobject_delete_plugin_in_evaluate") { + } else if (test_name == "npobject_delete_plugin_in_evaluate" || + test_name == "npobject_delete_create_plugin_in_evaluate") { new_test = new NPObjectDeletePluginInNPN_Evaluate(instance, host_functions); #endif } else if (test_name == "plugin_javascript_open_popup_with_plugin") { @@ -86,7 +87,8 @@ PluginTest* CreatePluginTest(const std::string& test_name, } else if (test_name == "hidden_plugin" || test_name == "create_instance_in_paint" || test_name == "alert_in_window_message" || - test_name == "ensure_scripting_works_in_destroy") { + test_name == "ensure_scripting_works_in_destroy" || + test_name == "invoke_js_function_on_create") { new_test = new WindowedPluginTest(instance, host_functions); #endif } diff --git a/webkit/glue/plugins/test/plugin_thread_async_call_test.cc b/webkit/glue/plugins/test/plugin_thread_async_call_test.cc index 2e9f9e9..c01a49e 100644 --- a/webkit/glue/plugins/test/plugin_thread_async_call_test.cc +++ b/webkit/glue/plugins/test/plugin_thread_async_call_test.cc @@ -4,6 +4,7 @@ #include "webkit/glue/plugins/test/plugin_thread_async_call_test.h" +#include "base/at_exit.h" #include "base/message_loop.h" #include "base/thread.h" #include "webkit/glue/plugins/test/plugin_client.h" diff --git a/webkit/glue/plugins/test/plugin_thread_async_call_test.h b/webkit/glue/plugins/test/plugin_thread_async_call_test.h index 020e5e1..78e4e8d 100644 --- a/webkit/glue/plugins/test/plugin_thread_async_call_test.h +++ b/webkit/glue/plugins/test/plugin_thread_async_call_test.h @@ -1,16 +1,17 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H -#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H +#ifndef WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H_ +#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H_ -#include <vector> - -#include "base/at_exit.h" #include "base/scoped_ptr.h" #include "webkit/glue/plugins/test/plugin_test.h" +namespace base { +class AtExitManager; +} + namespace NPAPIClient { // This class tests scheduling and unscheduling of async callbacks using @@ -35,4 +36,4 @@ class PluginThreadAsyncCallTest : public PluginTest { } // namespace NPAPIClient -#endif // WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H +#endif // WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H_ diff --git a/webkit/glue/plugins/test/plugin_windowed_test.cc b/webkit/glue/plugins/test/plugin_windowed_test.cc index 5ae8e30..461fc20 100644 --- a/webkit/glue/plugins/test/plugin_windowed_test.cc +++ b/webkit/glue/plugins/test/plugin_windowed_test.cc @@ -36,7 +36,8 @@ NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) { } if ((test_name() == "create_instance_in_paint" && test_id() == "1") || - test_name() == "alert_in_window_message") { + test_name() == "alert_in_window_message" || + test_name() == "invoke_js_function_on_create") { static ATOM window_class = 0; if (!window_class) { WNDCLASSEX wcex; @@ -130,6 +131,11 @@ LRESULT CALLBACK WindowedPluginTest::WindowProc( // and verify that we don't hang the browser. CallJSFunction(this_ptr, "CallAlert"); CallJSFunction(this_ptr, "CallAlert"); + } else if (this_ptr->test_name() == + "invoke_js_function_on_create" && + message == WM_PAINT) { + this_ptr->done_ = true; + CallJSFunction(this_ptr, "PluginCreated"); } } diff --git a/webkit/glue/plugins/test/plugin_windowless_test.cc b/webkit/glue/plugins/test/plugin_windowless_test.cc index c47c1d7..aa6a9d7 100644 --- a/webkit/glue/plugins/test/plugin_windowless_test.cc +++ b/webkit/glue/plugins/test/plugin_windowless_test.cc @@ -1,8 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #define STRSAFE_NO_DEPRECATE +#include "base/string_number_conversions.h" #include "base/string_util.h" #include "webkit/glue/plugins/test/plugin_windowless_test.h" #include "webkit/glue/plugins/test/plugin_client.h" @@ -151,9 +152,9 @@ void WindowlessPluginTest::MultipleInstanceSyncCalls(NPNetscapeFuncs* browser) { #if defined(OS_MACOSX) std::string StringForPoint(int x, int y) { std::string point_string("("); - point_string.append(IntToString(x)); + point_string.append(base::IntToString(x)); point_string.append(", "); - point_string.append(IntToString(y)); + point_string.append(base::IntToString(y)); point_string.append(")"); return point_string; } diff --git a/webkit/glue/plugins/webplugin.cc b/webkit/glue/plugins/webplugin.cc index 6443318..18f722b 100644 --- a/webkit/glue/plugins/webplugin.cc +++ b/webkit/glue/plugins/webplugin.cc @@ -12,6 +12,9 @@ WebPluginGeometry::WebPluginGeometry() visible(false) { } +WebPluginGeometry::~WebPluginGeometry() { +} + bool WebPluginGeometry::Equals(const WebPluginGeometry& rhs) const { return window == rhs.window && window_rect == rhs.window_rect && diff --git a/webkit/glue/plugins/webplugin.h b/webkit/glue/plugins/webplugin.h index 1813842..19c6cb0 100644 --- a/webkit/glue/plugins/webplugin.h +++ b/webkit/glue/plugins/webplugin.h @@ -33,6 +33,7 @@ class WebPluginResourceClient; // Describes the new location for a plugin window. struct WebPluginGeometry { WebPluginGeometry(); + ~WebPluginGeometry(); bool Equals(const WebPluginGeometry& rhs) const; diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc index b73b5ae..5374546 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl.cc @@ -156,6 +156,42 @@ void WebPluginDelegateImpl::UpdateGeometry( } } +void WebPluginDelegateImpl::SetFocus(bool focused) { + DCHECK(windowless_); + // This is called when internal WebKit focus (the focused element on the page) + // changes, but plugins need to know about OS-level focus, so we have an extra + // layer of focus tracking. + // + // On Windows, historically browsers did not set focus events to windowless + // plugins when the toplevel window focus changes. Sending such focus events + // breaks full screen mode in Flash because it will come out of full screen + // mode when it loses focus, and its full screen window causes the browser to + // lose focus. + has_webkit_focus_ = focused; +#ifndef OS_WIN + if (containing_view_has_focus_) + SetPluginHasFocus(focused); +#else + SetPluginHasFocus(focused); +#endif +} + +void WebPluginDelegateImpl::SetPluginHasFocus(bool focused) { + if (focused == plugin_has_focus_) + return; + if (PlatformSetPluginHasFocus(focused)) + plugin_has_focus_ = focused; +} + +void WebPluginDelegateImpl::SetContentAreaHasFocus(bool has_focus) { + containing_view_has_focus_ = has_focus; + if (!windowless_) + return; +#ifndef OS_WIN // See SetFocus above. + SetPluginHasFocus(containing_view_has_focus_ && has_webkit_focus_); +#endif +} + NPObject* WebPluginDelegateImpl::GetPluginScriptableObject() { return instance_->GetPluginScriptableObject(); } diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index ebf5d3e..650d398 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_ -#define WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_ +#ifndef WEBKIT_GLUE_PLUGINS_WEBPLUGIN_DELEGATE_IMPL_H_ +#define WEBKIT_GLUE_PLUGINS_WEBPLUGIN_DELEGATE_IMPL_H_ #include "build/build_config.h" #include <string> #include <list> -#include <set> -#include "base/file_path.h" #include "base/ref_counted.h" #include "base/task.h" #include "base/time.h" @@ -27,9 +25,13 @@ #endif #if defined(USE_X11) +#include "app/x11_util.h" + typedef struct _GdkDrawable GdkPixmap; #endif +class FilePath; + namespace NPAPI { class PluginInstance; } @@ -135,6 +137,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Returns a combination of PluginQuirks. int GetQuirks() const { return quirks_; } + // Informs the plugin that the view it is in has gained or lost focus. + void SetContentAreaHasFocus(bool has_focus); + #if defined(OS_MACOSX) // Informs the plugin that the geometry has changed, as with UpdateGeometry, // but also includes the new buffer context for that new geometry. @@ -148,16 +153,14 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { static WebPluginDelegateImpl* GetActiveDelegate(); // Informs the plugin that the window it is in has gained or lost focus. void SetWindowHasFocus(bool has_focus); - // Informs the plugin that the view it is in has gained or lost first - // responder status. - void SetContentAreaHasFocus(bool has_focus); // Returns whether or not the window the plugin is in has focus. bool GetWindowHasFocus() const { return containing_window_has_focus_; } // Informs the plugin that its tab or window has been hidden or shown. void SetContainerVisibility(bool is_visible); // Informs the plugin that its containing window's frame has changed. // Frames are in screen coordinates. - void WindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame); + void WindowFrameChanged(const gfx::Rect& window_frame, + const gfx::Rect& view_frame); // Informs the delegate that the plugin set a Carbon ThemeCursor. void SetThemeCursor(ThemeCursor cursor); // Informs the delegate that the plugin set a Carbon Cursor. @@ -181,6 +184,12 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { void set_windowed_handle(gfx::PluginWindowHandle handle); #endif +#if defined(USE_X11) + void SetWindowlessShmPixmap(XID shm_pixmap) { + windowless_shm_pixmap_ = shm_pixmap; + } +#endif + private: friend class DeleteTask<WebPluginDelegateImpl>; friend class webkit_glue::WebPluginDelegate; @@ -246,6 +255,14 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // See NPAPI NPP_SetWindow for more information. void WindowlessSetWindow(); + // Informs the plugin that it has gained or lost keyboard focus (on the Mac, + // this just means window first responder status). + void SetPluginHasFocus(bool focused); + + // Handles the platform specific details of setting plugin focus. Returns + // false if the platform cancelled the focus tranfer. + bool PlatformSetPluginHasFocus(bool focused); + //----------------------------------------- // used for windowed and windowless plugins @@ -289,9 +306,12 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // layout of this process with the one of the browser process. HKL keyboard_layout_; int parent_thread_id_; -#endif // OS_WIN +#endif // defined(OS_WIN) #if defined(USE_X11) + // The SHM pixmap for a windowless plugin. + XID windowless_shm_pixmap_; + // The pixmap we're drawing into, for a windowless plugin. GdkPixmap* pixmap_; double first_event_time_; @@ -366,10 +386,6 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Updates everything that depends on the plugin's absolute screen location. void PluginScreenLocationChanged(); - // Informs the plugin that it has gained or lost keyboard focus (i.e., window - // first responder status). - void SetPluginHasFocus(bool has_focus); - // Returns the apparent zoom ratio for the given event, as inferred from our // current knowledge about about where on screen the plugin is. // This is a temporary workaround for <http://crbug.com/9996>; once that is @@ -424,14 +440,6 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // relative to an upper-left (0,0). gfx::Point content_area_origin_; - // True if the plugin thinks it has keyboard focus - bool plugin_has_focus_; - // True if the plugin element has focus within the page, regardless of whether - // its containing view is currently the first responder for the window. - bool has_webkit_focus_; - // True if the containing view is the window's first responder. - bool containing_view_has_focus_; - bool containing_window_has_focus_; bool initial_window_focus_; bool container_is_visible_; @@ -484,7 +492,18 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // call received by the plugin. bool first_set_window_call_; + // True if the plugin thinks it has keyboard focus + bool plugin_has_focus_; + // True if the plugin element has focus within the web content, regardless of + // whether its containing view currently has focus. + bool has_webkit_focus_; + // True if the containing view currently has focus. + // Initially set to true so that plugin focus still works in environments + // where SetContentAreaHasFocus is never called. See + // https://bugs.webkit.org/show_bug.cgi?id=46013 for details. + bool containing_view_has_focus_; + DISALLOW_COPY_AND_ASSIGN(WebPluginDelegateImpl); }; -#endif // WEBKIT_GLUE_PLUGIN_WEBPLUGIN_DELEGATE_IMPL_H_ +#endif // WEBKIT_GLUE_PLUGINS_WEBPLUGIN_DELEGATE_IMPL_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc index 18b1504..3d112fa 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc @@ -44,6 +44,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( windowless_(false), plugin_(NULL), instance_(instance), + windowless_shm_pixmap_(None), pixmap_(NULL), first_event_time_(-1.0), plug_(NULL), @@ -51,7 +52,10 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( parent_(containing_view), quirks_(0), handle_event_depth_(0), - first_set_window_call_(true) { + first_set_window_call_(true), + plugin_has_focus_(false), + has_webkit_focus_(false), + containing_view_has_focus_(true) { memset(&window_, 0, sizeof(window_)); if (instance_->mime_type() == "application/x-shockwave-flash") { // Flash is tied to Firefox's whacky behavior with windowless plugins. See @@ -399,47 +403,99 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context, pixmap_draw_rect.right(), pixmap_draw_rect.bottom()); - EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height()); - - // Copy the current image into the pixmap, so the plugin can draw over - // this background. - cairo_t* cairo = gdk_cairo_create(pixmap_); - BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin()); - cairo_destroy(cairo); - // Construct the paint message, targeting the pixmap. NPEvent np_event = {0}; XGraphicsExposeEvent &event = np_event.xgraphicsexpose; event.type = GraphicsExpose; - event.display = GDK_DISPLAY(); - event.drawable = GDK_PIXMAP_XID(pixmap_); event.x = pixmap_draw_rect.x(); event.y = pixmap_draw_rect.y(); event.width = pixmap_draw_rect.width(); event.height = pixmap_draw_rect.height(); + event.display = GDK_DISPLAY(); - // Tell the plugin to paint into the pixmap. - static StatsRate plugin_paint("Plugin.Paint"); - StatsScope<StatsRate> scope(plugin_paint); - NPError err = instance()->NPP_HandleEvent(&np_event); - DCHECK_EQ(err, NPERR_NO_ERROR); + if (windowless_shm_pixmap_ != None) { + Pixmap pixmap = None; + GC xgc = NULL; + Display* display = event.display; + gfx::Rect plugin_draw_rect = draw_rect; + + // Make plugin_draw_rect relative to the plugin window. + plugin_draw_rect.Offset(-window_rect_.x(), -window_rect_.y()); + + // In case the drawing area does not start with the plugin window origin, + // we can not let the plugin directly draw over the shared memory pixmap. + if (plugin_draw_rect.x() != pixmap_draw_rect.x() || + plugin_draw_rect.y() != pixmap_draw_rect.y()) { + pixmap = XCreatePixmap(display, windowless_shm_pixmap_, + std::max(1, pixmap_rect.width()), + std::max(1, pixmap_rect.height()), + DefaultDepth(display, 0)); + xgc = XCreateGC(display, windowless_shm_pixmap_, 0, NULL); + // Copy the current image into the pixmap, so the plugin can draw over it. + XCopyArea(display, windowless_shm_pixmap_, pixmap, xgc, + plugin_draw_rect.x(), plugin_draw_rect.y(), + pixmap_draw_rect.width(), pixmap_draw_rect.height(), + pixmap_draw_rect.x(), pixmap_draw_rect.y()); + + event.drawable = pixmap; + } else { + event.drawable = windowless_shm_pixmap_; + } + + // Tell the plugin to paint into the pixmap. + static StatsRate plugin_paint("Plugin.Paint"); + StatsScope<StatsRate> scope(plugin_paint); + NPError err = instance()->NPP_HandleEvent(&np_event); + DCHECK_EQ(err, NPERR_NO_ERROR); - cairo_save(context); - // Now copy the rendered image pixmap back into the drawing buffer. - gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y); - cairo_rectangle(context, draw_rect.x(), draw_rect.y(), - draw_rect.width(), draw_rect.height()); - cairo_clip(context); - cairo_paint(context); + if (pixmap != None) { + // Copy the rendered image pixmap back into the shm pixmap + // and thus the drawing buffer. + XCopyArea(display, pixmap, windowless_shm_pixmap_, xgc, + pixmap_draw_rect.x(), pixmap_draw_rect.y(), + pixmap_draw_rect.width(), pixmap_draw_rect.height(), + plugin_draw_rect.x(), plugin_draw_rect.y()); + XSync(display, FALSE); + if (xgc) + XFreeGC(display, xgc); + XFreePixmap(display, pixmap); + } else { + XSync(display, FALSE); + } + } else { + EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height()); + + // Copy the current image into the pixmap, so the plugin can draw over + // this background. + cairo_t* cairo = gdk_cairo_create(pixmap_); + BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin()); + cairo_destroy(cairo); + + event.drawable = GDK_PIXMAP_XID(pixmap_); + + // Tell the plugin to paint into the pixmap. + static StatsRate plugin_paint("Plugin.Paint"); + StatsScope<StatsRate> scope(plugin_paint); + NPError err = instance()->NPP_HandleEvent(&np_event); + DCHECK_EQ(err, NPERR_NO_ERROR); + + cairo_save(context); + // Now copy the rendered image pixmap back into the drawing buffer. + gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y); + cairo_rectangle(context, draw_rect.x(), draw_rect.y(), + draw_rect.width(), draw_rect.height()); + cairo_clip(context); + cairo_paint(context); #ifdef DEBUG_RECTANGLES - // Draw some debugging rectangles. - // Pixmap rect = blue. - DrawDebugRectangle(context, pixmap_rect, 0, 0, 1); - // Drawing rect = red. - DrawDebugRectangle(context, draw_rect, 1, 0, 0); + // Draw some debugging rectangles. + // Pixmap rect = blue. + DrawDebugRectangle(context, pixmap_rect, 0, 0, 1); + // Drawing rect = red. + DrawDebugRectangle(context, draw_rect, 1, 0, 0); #endif - cairo_restore(context); + cairo_restore(context); + } } void WebPluginDelegateImpl::WindowlessSetWindow() { @@ -485,7 +541,7 @@ void WebPluginDelegateImpl::WindowlessSetWindow() { } } -void WebPluginDelegateImpl::SetFocus(bool focused) { +bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { DCHECK(instance()->windowless()); NPEvent np_event = {0}; @@ -496,6 +552,7 @@ void WebPluginDelegateImpl::SetFocus(bool focused) { event.mode = -1; event.detail = NotifyDetailNone; instance()->NPP_HandleEvent(&np_event); + return true; } // Converts a WebInputEvent::Modifiers bitfield into a diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index efa6bdd..614f1d2 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -12,11 +12,11 @@ #include <set> #include "base/file_util.h" -#include "base/lazy_instance.h" #include "base/message_loop.h" #include "base/scoped_ptr.h" #include "base/stats_counters.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/plugins/plugin_lib.h" @@ -258,16 +258,16 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( layer_(nil), surface_(NULL), renderer_(nil), - plugin_has_focus_(false), - has_webkit_focus_(false), - containing_view_has_focus_(false), containing_window_has_focus_(false), initial_window_focus_(false), container_is_visible_(false), have_called_set_window_(false), external_drag_tracker_(new ExternalDragTracker()), handle_event_depth_(0), - first_set_window_call_(true) { + first_set_window_call_(true), + plugin_has_focus_(false), + has_webkit_focus_(false), + containing_view_has_focus_(true) { memset(&window_, 0, sizeof(window_)); #ifndef NP_NO_CARBON memset(&np_cg_context_, 0, sizeof(np_cg_context_)); @@ -385,12 +385,6 @@ bool WebPluginDelegateImpl::PlatformInitialize() { break; } - // TODO(stuartmorgan): We need real plugin container visibility information - // when the plugin is initialized; for now, assume it's visible. - // None of the calls SetContainerVisibility would make are useful at this - // point, so we just set the initial state directly. - container_is_visible_ = true; - // Let the WebPlugin know that we are windowless (unless this is a // Core Animation plugin, in which case BindFakePluginWindowHandle will take // care of setting up the appropriate window handle). @@ -472,15 +466,6 @@ void WebPluginDelegateImpl::Print(CGContextRef context) { NOTIMPLEMENTED(); } -void WebPluginDelegateImpl::SetFocus(bool focused) { - // This is called when internal WebKit focus (the focused element on the page) - // changes, but plugins need to know about actual first responder status, so - // we have an extra layer of focus tracking. - has_webkit_focus_ = focused; - if (containing_view_has_focus_) - SetPluginHasFocus(focused); -} - bool WebPluginDelegateImpl::PlatformHandleInputEvent( const WebInputEvent& event, WebCursorInfo* cursor_info) { DCHECK(cursor_info != NULL); @@ -497,12 +482,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( if (WebInputEvent::isMouseEventType(event.type) || event.type == WebInputEvent::MouseWheel) { - // Ideally we would compute the content origin from the web event using the - // code below as a safety net for missed content area location changes. - // Because of <http://crbug.com/9996>, however, only globalX/Y are right if - // the page has been zoomed, so for now the coordinates we get aren't - // trustworthy enough to use for corrections. -#if PLUGIN_SCALING_FIXED // Check our plugin location before we send the event to the plugin, just // in case we somehow missed a plugin frame change. const WebMouseEvent* mouse_event = @@ -517,7 +496,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( << content_origin; SetContentAreaOrigin(content_origin); } -#endif current_windowless_cursor_.GetCursorInfo(cursor_info); } @@ -593,25 +571,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( } } -#ifndef PLUGIN_SCALING_FIXED - // Because of <http://crbug.com/9996>, the non-global coordinates we get for - // zoomed pages are wrong. As a temporary hack around that bug, override the - // coordinates we are given with ones computed based on our knowledge of where - // the plugin is on screen. We only need to do this for Cocoa, since Carbon - // only uses the global coordinates. - if (instance()->event_model() == NPEventModelCocoa && - (WebInputEvent::isMouseEventType(event.type) || - event.type == WebInputEvent::MouseWheel)) { - const WebMouseEvent* mouse_event = - static_cast<const WebMouseEvent*>(&event); - NPCocoaEvent* cocoa_event = static_cast<NPCocoaEvent*>(plugin_event); - cocoa_event->data.mouse.pluginX = - mouse_event->globalX - content_area_origin_.x() - window_rect_.x(); - cocoa_event->data.mouse.pluginY = - mouse_event->globalY - content_area_origin_.y() - window_rect_.y(); - } -#endif - // Send the plugin the event. scoped_ptr<NPAPI::ScopedCurrentPluginEvent> event_scope(NULL); if (instance()->event_model() == NPEventModelCocoa) { @@ -855,13 +814,9 @@ void WebPluginDelegateImpl::SetWindowHasFocus(bool has_focus) { } } -void WebPluginDelegateImpl::SetPluginHasFocus(bool has_focus) { +bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { if (!have_called_set_window_) - return; - - if (has_focus == plugin_has_focus_) - return; - plugin_has_focus_ = has_focus; + return false; ScopedActiveDelegate active_delegate(this); @@ -869,7 +824,7 @@ void WebPluginDelegateImpl::SetPluginHasFocus(bool has_focus) { #ifndef NP_NO_CARBON case NPEventModelCarbon: { NPEvent focus_event = { 0 }; - if (plugin_has_focus_) + if (focused) focus_event.what = NPEventType_GetFocusEvent; else focus_event.what = NPEventType_LoseFocusEvent; @@ -882,16 +837,12 @@ void WebPluginDelegateImpl::SetPluginHasFocus(bool has_focus) { NPCocoaEvent focus_event; memset(&focus_event, 0, sizeof(focus_event)); focus_event.type = NPCocoaEventFocusChanged; - focus_event.data.focus.hasFocus = plugin_has_focus_; + focus_event.data.focus.hasFocus = focused; instance()->NPP_HandleEvent(&focus_event); break; } } -} - -void WebPluginDelegateImpl::SetContentAreaHasFocus(bool has_focus) { - containing_view_has_focus_ = has_focus; - SetPluginHasFocus(containing_view_has_focus_ && has_webkit_focus_); + return true; } void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) { @@ -925,8 +876,8 @@ void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) { instance()->webplugin()->InvalidateRect(gfx::Rect()); } -void WebPluginDelegateImpl::WindowFrameChanged(gfx::Rect window_frame, - gfx::Rect view_frame) { +void WebPluginDelegateImpl::WindowFrameChanged(const gfx::Rect& window_frame, + const gfx::Rect& view_frame) { instance()->set_window_frame(window_frame); SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y())); } diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc index 09184ab..9cdc7db 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,7 +15,10 @@ #include "base/registry.h" #include "base/scoped_ptr.h" #include "base/stats_counters.h" +#include "base/string_number_conversions.h" +#include "base/string_split.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "base/win_util.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" @@ -264,7 +267,10 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( user_gesture_msg_factory_(this), handle_event_depth_(0), mouse_hook_(NULL), - first_set_window_call_(true) { + first_set_window_call_(true), + plugin_has_focus_(false), + has_webkit_focus_(false), + containing_view_has_focus_(true) { memset(&window_, 0, sizeof(window_)); const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info(); @@ -285,7 +291,8 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( std::vector<std::wstring> version; SplitString(plugin_info.version, L'.', &version); if (version.size() > 0) { - int major = static_cast<int>(StringToInt64(version[0])); + int major; + base::StringToInt(version[0], &major); if (major >= 9) { quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD; @@ -410,7 +417,8 @@ bool WebPluginDelegateImpl::PlatformInitialize() { if ((quirks_ & PLUGIN_QUIRK_PATCH_REGENUMKEYEXW) && win_util::GetWinVersion() == win_util::WINVERSION_XP && !RegKey().Open(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe") && + L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe", + KEY_READ) && !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) { g_iat_patch_reg_enum_key_ex_w.Pointer()->Patch( L"wmpdxm.dll", "advapi32.dll", "RegEnumKeyExW", @@ -1048,7 +1056,7 @@ void WebPluginDelegateImpl::WindowlessSetWindow() { DCHECK(err == NPERR_NO_ERROR); } -void WebPluginDelegateImpl::SetFocus(bool focused) { +bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { DCHECK(instance()->windowless()); NPEvent focus_event; @@ -1057,6 +1065,7 @@ void WebPluginDelegateImpl::SetFocus(bool focused) { focus_event.lParam = 0; instance()->NPP_HandleEvent(&focus_event); + return true; } static bool NPEventFromWebMouseEvent(const WebMouseEvent& event, @@ -1187,7 +1196,7 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( parent_thread_id_ = GetWindowThreadProcessId(parent_, NULL); HKL parent_layout = GetKeyboardLayout(parent_thread_id_); if (keyboard_layout_ != parent_layout) { - std::wstring layout_name(StringPrintf(L"%08x", parent_layout)); + std::wstring layout_name(base::StringPrintf(L"%08x", parent_layout)); LoadKeyboardLayout(layout_name.c_str(), KLF_ACTIVATE); keyboard_layout_ = parent_layout; } diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc index 1660ede..80bc197 100644 --- a/webkit/glue/plugins/webplugin_impl.cc +++ b/webkit/glue/plugins/webplugin_impl.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "gfx/rect.h" #include "googleurl/src/gurl.h" @@ -113,7 +114,7 @@ class MultiPartResponseClient : public WebURLLoaderClient { byte_range_lower_bound_ += data_size; } - virtual void didFinishLoading(WebURLLoader*) {} + virtual void didFinishLoading(WebURLLoader*, double finishTime) {} virtual void didFail(WebURLLoader*, const WebURLError&) {} void Clear() { @@ -160,7 +161,7 @@ std::string GetAllHeaders(const WebURLResponse& response) { return result; // TODO(darin): Shouldn't we also report HTTP version numbers? - result = StringPrintf("HTTP %d ", response.httpStatusCode()); + result = base::StringPrintf("HTTP %d ", response.httpStatusCode()); result.append(status.utf8()); result.append("\n"); @@ -340,6 +341,10 @@ bool WebPluginImpl::acceptsInputEvents() { bool WebPluginImpl::handleInputEvent( const WebInputEvent& event, WebCursorInfo& cursor_info) { + // Swallow context menu events in order to suppress the default context menu. + if (event.type == WebInputEvent::ContextMenu) + return true; + return delegate_->HandleInputEvent(event, &cursor_info); } @@ -913,7 +918,7 @@ void WebPluginImpl::didReceiveData(WebURLLoader* loader, } } -void WebPluginImpl::didFinishLoading(WebURLLoader* loader) { +void WebPluginImpl::didFinishLoading(WebURLLoader* loader, double finishTime) { ClientInfo* client_info = GetClientInfoFromLoader(loader); if (client_info && client_info->client) { MultiPartResponseHandlerMap::iterator index = diff --git a/webkit/glue/plugins/webplugin_impl.h b/webkit/glue/plugins/webplugin_impl.h index 9b75e6e..5fe96d2 100644 --- a/webkit/glue/plugins/webplugin_impl.h +++ b/webkit/glue/plugins/webplugin_impl.h @@ -204,7 +204,8 @@ class WebPluginImpl : public WebPlugin, const WebKit::WebURLResponse& response); virtual void didReceiveData(WebKit::WebURLLoader* loader, const char *buffer, int length); - virtual void didFinishLoading(WebKit::WebURLLoader* loader); + virtual void didFinishLoading(WebKit::WebURLLoader* loader, + double finishTime); virtual void didFail(WebKit::WebURLLoader* loader, const WebKit::WebURLError& error); diff --git a/webkit/glue/plugins/webview_plugin.cc b/webkit/glue/plugins/webview_plugin.cc index 413ae10..231bd37 100644 --- a/webkit/glue/plugins/webview_plugin.cc +++ b/webkit/glue/plugins/webview_plugin.cc @@ -4,6 +4,7 @@ #include "webkit/glue/plugins/webview_plugin.h" +#include "base/histogram.h" #include "base/message_loop.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" @@ -12,6 +13,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" #if WEBKIT_USING_CG @@ -27,18 +29,21 @@ using WebKit::WebDragOperationsMask; using WebKit::WebFrame; using WebKit::WebImage; using WebKit::WebInputEvent; +using WebKit::WebPlugin; using WebKit::WebPluginContainer; using WebKit::WebPoint; using WebKit::WebRect; using WebKit::WebSize; using WebKit::WebURLError; using WebKit::WebURLRequest; +using WebKit::WebURLResponse; using WebKit::WebVector; using WebKit::WebView; WebViewPlugin::WebViewPlugin(WebViewPlugin::Delegate* delegate) : delegate_(delegate), - container_(NULL) { + container_(NULL), + finished_loading_(false) { web_view_ = WebView::create(this, NULL); web_view_->initializeMainFrame(this); } @@ -47,6 +52,26 @@ WebViewPlugin::~WebViewPlugin() { web_view_->close(); } +void WebViewPlugin::ReplayReceivedData(WebPlugin* plugin) { + if (!response_.isNull()) { + plugin->didReceiveResponse(response_); + size_t total_bytes = 0; + for (std::list<std::string>::iterator it = data_.begin(); + it != data_.end(); ++it) { + plugin->didReceiveData(it->c_str(), it->length()); + total_bytes += it->length(); + } + UMA_HISTOGRAM_MEMORY_KB("PluginDocument.Memory", (total_bytes / 1024)); + UMA_HISTOGRAM_COUNTS("PluginDocument.NumChunks", data_.size()); + } + if (finished_loading_) { + plugin->didFinishLoading(); + } + if (error_.get()) { + plugin->didFailLoading(*error_); + } +} + bool WebViewPlugin::initialize(WebPluginContainer* container) { container_ = container; return true; @@ -55,6 +80,7 @@ bool WebViewPlugin::initialize(WebPluginContainer* container) { void WebViewPlugin::destroy() { delegate_->WillDestroyPlugin(); delegate_ = NULL; + container_ = NULL; MessageLoop::current()->DeleteSoon(FROM_HERE, this); } @@ -104,6 +130,25 @@ bool WebViewPlugin::handleInputEvent(const WebInputEvent& event, return handled; } +void WebViewPlugin::didReceiveResponse(const WebURLResponse& response) { + DCHECK(response_.isNull()); + response_ = response; +} + +void WebViewPlugin::didReceiveData(const char* data, int data_length) { + data_.push_back(std::string(data, data_length)); +} + +void WebViewPlugin::didFinishLoading() { + DCHECK(!finished_loading_); + finished_loading_ = true; +} + +void WebViewPlugin::didFailLoading(const WebURLError& error) { + DCHECK(!error_.get()); + error_.reset(new WebURLError(error)); +} + void WebViewPlugin::startDragging(const WebDragData&, WebDragOperationsMask, const WebImage&, @@ -114,7 +159,7 @@ void WebViewPlugin::startDragging(const WebDragData&, void WebViewPlugin::didInvalidateRect(const WebRect& rect) { if (container_) - container_->invalidateRect(WebRect(rect)); + container_->invalidateRect(rect); } void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) { @@ -122,7 +167,8 @@ void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) { } void WebViewPlugin::didClearWindowObject(WebFrame* frame) { - delegate_->BindWebFrame(frame); + if (delegate_) + delegate_->BindWebFrame(frame); } bool WebViewPlugin::canHandleRequest(WebFrame* frame, diff --git a/webkit/glue/plugins/webview_plugin.h b/webkit/glue/plugins/webview_plugin.h index 2e41218..757a012 100644 --- a/webkit/glue/plugins/webview_plugin.h +++ b/webkit/glue/plugins/webview_plugin.h @@ -5,11 +5,14 @@ #ifndef WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_ #define WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_ +#include <list> + #include "base/scoped_ptr.h" #include "base/task.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" -#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h" // This class implements the WebPlugin interface by forwarding drawing and @@ -36,9 +39,14 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient, explicit WebViewPlugin(Delegate* delegate); - virtual WebKit::WebView* web_view() { return web_view_; } + WebKit::WebView* web_view() { return web_view_; } - virtual WebKit::WebPluginContainer* container() { return container_; } + WebKit::WebPluginContainer* container() { return container_; } + + // When loading a plug-in document (i.e. a full page plug-in not embedded in + // another page), we save all data that has been received, and replay it with + // this method on the actual plug-in. + void ReplayReceivedData(WebKit::WebPlugin* plugin); // WebPlugin methods: virtual bool initialize(WebKit::WebPluginContainer*); @@ -60,10 +68,10 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient, virtual bool handleInputEvent(const WebKit::WebInputEvent& event, WebKit::WebCursorInfo& cursor_info); - virtual void didReceiveResponse(const WebKit::WebURLResponse& response) { } - virtual void didReceiveData(const char* data, int data_length) { } - virtual void didFinishLoading() { } - virtual void didFailLoading(const WebKit::WebURLError& error) { } + virtual void didReceiveResponse(const WebKit::WebURLResponse& response); + virtual void didReceiveData(const char* data, int data_length); + virtual void didFinishLoading(); + virtual void didFailLoading(const WebKit::WebURLError& error); // Called in response to WebPluginContainer::loadFrameRequest virtual void didFinishLoadingFrameRequest( @@ -102,6 +110,11 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient, WebKit::WebPluginContainer* container_; WebKit::WebView* web_view_; gfx::Rect rect_; + + WebKit::WebURLResponse response_; + std::list<std::string> data_; + bool finished_loading_; + scoped_ptr<WebKit::WebURLError> error_; }; #endif // WEBKIT_GLUE_PLUGINS_WEBVIEW_PLUGIN_H_ diff --git a/webkit/glue/resource_fetcher.cc b/webkit/glue/resource_fetcher.cc index 186092b..9b00805 100644 --- a/webkit/glue/resource_fetcher.cc +++ b/webkit/glue/resource_fetcher.cc @@ -88,7 +88,8 @@ void ResourceFetcher::didReceiveCachedMetadata( metadata_.assign(data, data_length); } -void ResourceFetcher::didFinishLoading(WebURLLoader* loader) { +void ResourceFetcher::didFinishLoading( + WebURLLoader* loader, double finishTime) { DCHECK(!completed_); completed_ = true; @@ -119,6 +120,9 @@ ResourceFetcherWithTimeout::ResourceFetcherWithTimeout( &ResourceFetcherWithTimeout::TimeoutFired); } +ResourceFetcherWithTimeout::~ResourceFetcherWithTimeout() { +} + void ResourceFetcherWithTimeout::TimeoutFired() { if (!completed_) { loader_->cancel(); diff --git a/webkit/glue/resource_fetcher.h b/webkit/glue/resource_fetcher.h index 7910fc1..ff00939 100644 --- a/webkit/glue/resource_fetcher.h +++ b/webkit/glue/resource_fetcher.h @@ -65,7 +65,8 @@ class ResourceFetcher : public WebKit::WebURLLoaderClient { WebKit::WebURLLoader* loader, const char* data, int data_length); virtual void didReceiveData( WebKit::WebURLLoader* loader, const char* data, int data_length); - virtual void didFinishLoading(WebKit::WebURLLoader* loader); + virtual void didFinishLoading( + WebKit::WebURLLoader* loader, double finishTime); virtual void didFail( WebKit::WebURLLoader* loader, const WebKit::WebURLError& error); @@ -100,7 +101,7 @@ class ResourceFetcherWithTimeout : public ResourceFetcher { public: ResourceFetcherWithTimeout(const GURL& url, WebKit::WebFrame* frame, int timeout_secs, Callback* c); - virtual ~ResourceFetcherWithTimeout() {} + virtual ~ResourceFetcherWithTimeout(); private: // Callback for timer that limits how long we wait for the alternate error diff --git a/webkit/glue/resource_fetcher_unittest.cc b/webkit/glue/resource_fetcher_unittest.cc index 98cef0a..70c316b 100644 --- a/webkit/glue/resource_fetcher_unittest.cc +++ b/webkit/glue/resource_fetcher_unittest.cc @@ -5,6 +5,7 @@ #include "webkit/glue/resource_fetcher.h" #include "base/callback.h" +#include "base/message_loop.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" @@ -24,13 +25,8 @@ using webkit_glue::ResourceFetcherWithTimeout; namespace { class ResourceFetcherTests : public TestShellTest { - public: - void SetUp() { - TestShellTest::SetUp(); - } - void TearDown() { - TestShellTest::TearDown(); - } + protected: + UnittestTestServer test_server_; }; static const int kMaxWaitTimeMs = 5000; @@ -154,13 +150,11 @@ FetcherDelegate* FetcherDelegate::instance_ = NULL; // Test a fetch from the test server. TEST_F(ResourceFetcherTests, ResourceFetcherDownload) { - scoped_refptr<UnittestTestServer> server = - UnittestTestServer::CreateServer(); - ASSERT_TRUE(NULL != server.get()); + ASSERT_TRUE(test_server_.Start()); WebFrame* frame = test_shell_->webView()->mainFrame(); - GURL url = server->TestServerPage("files/test_shell/index.html"); + GURL url(test_server_.GetURL("files/test_shell/index.html")); scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate); scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher( url, frame, delegate->NewCallback())); @@ -173,7 +167,7 @@ TEST_F(ResourceFetcherTests, ResourceFetcherDownload) { EXPECT_TRUE(text.find("What is this page?") != std::string::npos); // Test 404 response. - url = server->TestServerPage("files/thisfiledoesntexist.html"); + url = test_server_.GetURL("files/thisfiledoesntexist.html"); delegate.reset(new FetcherDelegate); fetcher.reset(new ResourceFetcher(url, frame, delegate->NewCallback())); @@ -185,9 +179,7 @@ TEST_F(ResourceFetcherTests, ResourceFetcherDownload) { } TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) { - scoped_refptr<UnittestTestServer> server = - UnittestTestServer::CreateServer(); - ASSERT_TRUE(NULL != server.get()); + ASSERT_TRUE(test_server_.Start()); WebFrame* frame = test_shell_->webView()->mainFrame(); @@ -208,15 +200,13 @@ TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) { } TEST_F(ResourceFetcherTests, ResourceFetcherTimeout) { - scoped_refptr<UnittestTestServer> server = - UnittestTestServer::CreateServer(); - ASSERT_TRUE(NULL != server.get()); + ASSERT_TRUE(test_server_.Start()); WebFrame* frame = test_shell_->webView()->mainFrame(); // Grab a page that takes at least 1 sec to respond, but set the fetcher to // timeout in 0 sec. - GURL url = server->TestServerPage("slow?1"); + GURL url(test_server_.GetURL("slow?1")); scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate); scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcherWithTimeout( url, frame, 0, delegate->NewCallback())); diff --git a/webkit/glue/resource_loader_bridge.cc b/webkit/glue/resource_loader_bridge.cc index 8845256..ab19082 100644 --- a/webkit/glue/resource_loader_bridge.cc +++ b/webkit/glue/resource_loader_bridge.cc @@ -15,7 +15,8 @@ ResourceLoaderBridge::RequestInfo::RequestInfo() request_type(ResourceType::MAIN_FRAME), request_context(0), appcache_host_id(0), - routing_id(0) { + routing_id(0), + download_to_file(false) { } ResourceLoaderBridge::RequestInfo::~RequestInfo() { diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h index e66181f..eae1404 100644 --- a/webkit/glue/resource_loader_bridge.h +++ b/webkit/glue/resource_loader_bridge.h @@ -21,6 +21,7 @@ #if defined(OS_POSIX) #include "base/file_descriptor_posix.h" #endif +#include "base/file_path.h" #include "base/platform_file.h" #include "base/ref_counted.h" #include "base/time.h" @@ -32,8 +33,6 @@ namespace net { class HttpResponseHeaders; } -class FilePath; - namespace webkit_glue { class ResourceLoaderBridge { @@ -84,6 +83,10 @@ class ResourceLoaderBridge { // Used to associated the bridge with a frame's network context. int routing_id; + + // If true, then the response body will be downloaded to a file and the + // path to that file will be provided in ResponseInfo::download_file_path. + bool download_to_file; }; // Structure containing timing information for the request. It addresses @@ -114,12 +117,12 @@ class ResourceLoaderBridge { // The time that DNS lookup ended. For reused sockets this time is -1. int32 dns_end; - // The time that establishing connection started. For reused sockets - // this time is -1. Connect time includes dns time. + // The time that establishing connection started. Connect time includes + // DNS, blocking, TCP, TCP retries and SSL time. int32 connect_start; - // The time that establishing connection ended. For reused sockets this - // time is -1. Connect time includes dns time. + // The time that establishing connection ended. Connect time includes + // DNS, blocking, TCP, TCP retries and SSL time. int32 connect_end; // The time at which SSL handshake started. For non-HTTPS requests this @@ -191,6 +194,11 @@ class ResourceLoaderBridge { // Tools. LoadTimingInfo load_timing; + // The path to a file that will contain the response body. It may only + // contain a portion of the response body at the time that the ResponseInfo + // becomes available. + FilePath download_file_path; + // True if the response was delivered using SPDY. bool was_fetched_via_spdy; @@ -258,6 +266,12 @@ class ResourceLoaderBridge { virtual void OnReceivedResponse(const ResponseInfo& info, bool content_filtered) = 0; + // Called when a chunk of response data is downloaded. This method may be + // called multiple times or not at all if an error occurs. This method is + // only called if RequestInfo::download_to_file was set to true, and in + // that case, OnReceivedData will not be called. + virtual void OnDownloadedData(int len) = 0; + // Called when a chunk of response data is available. This method may // be called multiple times or not at all if an error occurs. virtual void OnReceivedData(const char* data, int len) = 0; @@ -269,7 +283,8 @@ class ResourceLoaderBridge { // Called when the response is complete. This method signals completion of // the resource load.ff virtual void OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info) = 0; + const std::string& security_info, + const base::Time& completion_time) = 0; // Returns the URL of the request, which allows us to display it in // debugging situations. @@ -304,6 +319,10 @@ class ResourceLoaderBridge { uint64 length, const base::Time& expected_modification_time) = 0; + // Call this method before calling Start() to append the contents of a blob + // to the request body. May only be used with HTTP(S) POST requests. + virtual void AppendBlobToUpload(const GURL& blob_url) = 0; + // Call this method before calling Start() to assign an upload identifier to // this request. This is used to enable caching of POST responses. A value // of 0 implies the unspecified identifier. diff --git a/webkit/glue/resource_type.h b/webkit/glue/resource_type.h index aa4a072..1de4fd2 100644 --- a/webkit/glue/resource_type.h +++ b/webkit/glue/resource_type.h @@ -22,6 +22,7 @@ class ResourceType { MEDIA, // a media resource. WORKER, // the main resource of a dedicated worker. SHARED_WORKER, // the main resource of a shared worker. + PREFETCH, // an explicitly requested prefetch LAST_TYPE // Place holder so we don't need to change ValidType // everytime. }; diff --git a/webkit/glue/resources/webkit_strings_am.xtb b/webkit/glue/resources/webkit_strings_am.xtb index acba326..1a71058 100644 --- a/webkit/glue/resources/webkit_strings_am.xtb +++ b/webkit/glue/resources/webkit_strings_am.xtb @@ -1,43 +1,30 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="am"> -<translation id="4420062214988137980">የPlugin ጭነት ተሰናክሏል</translation> <translation id="1235745349614807883">የቅርብ ጊዜ ፍለጋዎችን አስወግድ</translation> -<translation id="3825324228893189080">ተጨማሪ plugin ያስፈልጋል</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> plugin አልተጫነም</translation> <translation id="5048533449481078685">ዝርዝር አመልካች</translation> <translation id="4202807286478387388">ዝለል</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">እባክዎ <ph name="PLUGIN"/> plugin ለመጫን መፈለግዎን ያረጋግጡ። የሚያምኗቸውን plugins ብቻ መጫን ይኖርብዎታል።</translation> <translation id="7658239707568436148">ሰርዝ</translation> <translation id="795667975304826397">ምንም ፋይል አልተመረጠም</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> plugin ያስፈልጋል</translation> -<translation id="8662565117025751661">የሚወርድ plugin…</translation> <translation id="8141602879876242471">ይህ ሊፈለግ የሚችል መረጃ ጠቋሚ ነው። የፍለጋ ቁልፍ ቃላት አስገባ፦</translation> <translation id="6845533974506654842">ተጫን</translation> <translation id="8244226242650769279">የምስል ካርታ</translation> -<translation id="1383141426028388991">ከ<ph name="URL"/> plugin ለመጫን አልተቻለም</translation> <translation id="2548326553472216322">የቅርብ ጊዜ ፍለጋዎች የሉም</translation> <translation id="5944544982112848342">2048(ከፍተኛ ደረጃ)</translation> <translation id="3040011195152428237">አገናኝ</translation> -<translation id="8281246460978372009">plugin ከተጫነ በኋላ፣ ለማደስ እዚህ ይጫኑ</translation> <translation id="7364796246159120393">ፋይል ምረጥ</translation> <translation id="8964020114565522021">ፋይል ወደዚህ ጎትት</translation> <translation id="838869780401515933">አመልክት</translation> <translation id="2846343701378493991">1024(መካከለኛ ደረጃ)</translation> <translation id="5476505524087279545">አታመልክት</translation> -<translation id="679352192834563463">ይህን ይዘት ለማሳየት ምንም plugin የለም</translation> <translation id="3789841737615482174">ጫን</translation> <translation id="6663448176199120256">የቅርብ ጊዜ ፍለጋዎችን</translation> -<translation id="3600343118165084788">plugin ለማውረድ እዚህ ይጫኑ</translation> <translation id="6807599807928161586">የድር ክልል</translation> <translation id="5939518447894949180">ዳግም አስጀምር</translation> -<translation id="3771786644471114952">Plugin አግኝ</translation> <translation id="1842960171412779397">ምረጥ</translation> <translation id="6119846243427417423">አንቃ</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ፋይሎች</translation> -<translation id="3926627843712816530">እባክዎ ይህን plugin ለመጫን መፈለግዎን ያረጋግጡ። የሚያምኗቸውን plugins ብቻ መጫን ይኖርብዎታል።</translation> -<translation id="4838490908464673667">የሚፈለገው plugin አልተጫነም</translation> <translation id="8597182159515967513">ርእስ</translation> <translation id="2653659639078652383">አስገባ</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ar.xtb b/webkit/glue/resources/webkit_strings_ar.xtb index a558190..6f454f7 100644 --- a/webkit/glue/resources/webkit_strings_ar.xtb +++ b/webkit/glue/resources/webkit_strings_ar.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ar"> -<translation id="4420062214988137980">إخفاق محاولة تثبيت المكوّن الإضافي</translation> +<translation id="4519964825805946997">أخفق تثبيت المكون الإضافي من <ph name="URL"/></translation> <translation id="1235745349614807883">محو آخر عمليات البحث</translation> -<translation id="3825324228893189080">مطلوب مكوّن إضافيّ آخر.</translation> -<translation id="2965480764085142436">المكوّن الإضافي <ph name="PLUGIN"/> غير متوفّر</translation> <translation id="5048533449481078685">محدّد القائمة</translation> +<translation id="372362261556059955">المكوّن الإضافي المطلوب</translation> <translation id="4202807286478387388">الدخول</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">الرّجاء تأكيد طلب تثبيت المكوّن الإضافي <ph name="PLUGIN"/>. يجب تثبيت المكوّنات الإضافية الموثوق بها فقط.</translation> <translation id="7658239707568436148">إلغاء</translation> <translation id="795667975304826397">ّلم يتمّ اختيار أيّ ملفّ</translation> -<translation id="1275511093094545429">يلزم المكوّن الإضافيّ <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">تحميل المكوّن الإضافي...</translation> +<translation id="1416462845279468967">أخفق تثبيت المكون الإضافي</translation> <translation id="8141602879876242471">يمكن البحث في هذا الفهرس بإدخال كلمات مفتاحية:</translation> +<translation id="5650795167354946011">بعد تثبيت المكون الإضافي، انقر هنا للتحديث</translation> <translation id="6845533974506654842">اضغط</translation> <translation id="8244226242650769279">مخطّط صورة</translation> -<translation id="1383141426028388991">فشل تثبيت المكون الإضافي من <ph name="URL"/></translation> <translation id="2548326553472216322">لا عمليات بحث حديثة</translation> <translation id="5944544982112848342">2048 (درجة عالية)</translation> <translation id="3040011195152428237">رابط</translation> -<translation id="8281246460978372009">بعد تثبيت المكوّن الإضافي، انقر هنا لتحديث النافذة</translation> +<translation id="2745343197843472802">الحصول على المكوّن الإضافي</translation> +<translation id="5776402066334188252">الرجاء التأكيد على أنك تريد تثبيت المكوّن الإضافي هذا. يجب تثبيت المكونات الإضافية التي تثق فيها فقط.</translation> +<translation id="4003986561708175844">لم يتم تثبيت المكون الإضافي المطلوب</translation> +<translation id="3018094406922859308">جارٍ تنزيل المكوّن الإضافي...</translation> <translation id="7364796246159120393">اختيار ملفّ</translation> <translation id="8964020114565522021">سحب الملفّ إلى هنا</translation> <translation id="838869780401515933">الاختيار</translation> <translation id="2846343701378493991">1024 (درجة متوسطة)</translation> <translation id="5476505524087279545">إزالة علامة الاختيار</translation> -<translation id="679352192834563463">لا يتوفر أي مكوّن إضافي لعرض هذا المحتوى</translation> <translation id="3789841737615482174">تثبيت</translation> +<translation id="5253117816378681419">الرجاء التأكيد على أنك تريد تثبيت المكوّن الإضافي <ph name="PLUGIN"/>. يجب تثبيت المكونات الإضافية التي تثق فيها فقط.</translation> <translation id="6663448176199120256">آخر عمليات البحث</translation> -<translation id="3600343118165084788">انقر هنا لتنزيل المكوّن الإضافي</translation> +<translation id="2597378329261239068">هذا المستند محمي بكلمة المرور. الرجاء إدخال كلمة مرور.</translation> <translation id="6807599807928161586">منطقة الويب</translation> <translation id="5939518447894949180">إعادة</translation> -<translation id="3771786644471114952">جلب المكوّن الإضافي</translation> <translation id="1842960171412779397">الاختيار</translation> +<translation id="7638452146404718955">انقر هنا لتنزيل المكون الإضافي</translation> <translation id="6119846243427417423">تنشيط</translation> <translation id="8444882422881193423">عدد الملفات: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">يرجى تأكيد طلب تثبيت المكوّن الإضافي. يجب تثبيت المكوّنات الإضافية الموثوق بها فقط.</translation> -<translation id="4838490908464673667">المكوّن الإضافيّ المطلوب غير متوفّر</translation> +<translation id="4470547978413275879">لم يتم تثبيت المكون الإضافي <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">لا يتوفر أي مكون إضافي لعرض هذا المحتوى</translation> <translation id="8597182159515967513">العنوان</translation> <translation id="2653659639078652383">إرسال</translation> +<translation id="8475551193147984329">المكوّن الإضافي المطلوب <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_bg.xtb b/webkit/glue/resources/webkit_strings_bg.xtb index 91d0b4b..4edbd69 100644 --- a/webkit/glue/resources/webkit_strings_bg.xtb +++ b/webkit/glue/resources/webkit_strings_bg.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="bg"> -<translation id="4420062214988137980">Инсталирането на приставката не бе успешно</translation> +<translation id="4519964825805946997">Инсталирането на приставката от <ph name="URL"/> не бе успешно</translation> <translation id="1235745349614807883">Изчистване на скорошните търсения</translation> -<translation id="3825324228893189080">Изисква се допълнителна приставка</translation> -<translation id="2965480764085142436">Приставката за <ph name="PLUGIN"/> не е инсталирана</translation> <translation id="5048533449481078685">списъчен показалец</translation> +<translation id="372362261556059955">Необходима е допълнителна приставка</translation> <translation id="4202807286478387388">преминаване</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Моля, потвърдете, че искате да инсталирате приставката за <ph name="PLUGIN"/>. Инсталирайте само тези приставки, които считате за надеждни.</translation> <translation id="7658239707568436148">Отказ</translation> <translation id="795667975304826397">Няма избран файл</translation> -<translation id="1275511093094545429">Необходима е приставка за <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Приставката се изтегля...</translation> +<translation id="1416462845279468967">Инсталирането на приставката не бе успешно</translation> <translation id="8141602879876242471">В този индекс може да се търси. Въведете ключови думи за търсене:</translation> +<translation id="5650795167354946011">След инсталирането на приставката кликнете тук за опресняване</translation> <translation id="6845533974506654842">натискане</translation> <translation id="8244226242650769279">карта с изображения</translation> -<translation id="1383141426028388991">Неуспешно инсталиране на приставката от <ph name="URL"/></translation> <translation id="2548326553472216322">Няма скорошни търсения</translation> <translation id="5944544982112848342">2048 (висока степен на сложност)</translation> <translation id="3040011195152428237">връзка</translation> -<translation id="8281246460978372009">След като инсталирате приставката, кликнете тук, за да опресните прозореца</translation> +<translation id="2745343197843472802">Изтеглете приставката</translation> +<translation id="5776402066334188252">Моля, потвърдете, че искате да инсталирате тази приставка. Трябва да инсталирате само приставки, на които имате доверие.</translation> +<translation id="4003986561708175844">Необходимата приставка не е инсталирана</translation> +<translation id="3018094406922859308">Приставката се изтегля...</translation> <translation id="7364796246159120393">Избор на файл</translation> <translation id="8964020114565522021">Плъзнете файла тук</translation> <translation id="838869780401515933">отмятане</translation> <translation id="2846343701378493991">1024 (средна степен на сложност)</translation> <translation id="5476505524087279545">премахване на отметката</translation> -<translation id="679352192834563463">Няма приставка, с която може да се покаже това съдържание</translation> <translation id="3789841737615482174">Инсталиране</translation> +<translation id="5253117816378681419">Моля, потвърдете, че искате да инсталирате приставката <ph name="PLUGIN"/>. Трябва да инсталирате само приставки, на които имате доверие.</translation> <translation id="6663448176199120256">Скорошни търсения</translation> -<translation id="3600343118165084788">Кликнете тук, за да изтеглите приставката</translation> +<translation id="2597378329261239068">Този документ е защитен с парола. Моля, въведете я.</translation> <translation id="6807599807928161586">уеб зона</translation> <translation id="5939518447894949180">Повторно задаване</translation> -<translation id="3771786644471114952">Изтегляне на приставката</translation> <translation id="1842960171412779397">Избиране</translation> +<translation id="7638452146404718955">Кликнете тук, за да изтеглите приставката</translation> <translation id="6119846243427417423">активиране</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> файла</translation> -<translation id="3926627843712816530">Моля, потвърдете, че искате да инсталирате тази приставка. Инсталирайте само тези приставки, които считате за надеждни.</translation> -<translation id="4838490908464673667">Необходимата приставка не е инсталирана</translation> +<translation id="4470547978413275879">Не е инсталирана приставката <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">Няма налична приставка за показване на това съдържание</translation> <translation id="8597182159515967513">заглавие</translation> <translation id="2653659639078652383">Изпращане</translation> +<translation id="8475551193147984329">Необходима е приставката <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_bn.xtb b/webkit/glue/resources/webkit_strings_bn.xtb index 098985f..1a29278 100644 --- a/webkit/glue/resources/webkit_strings_bn.xtb +++ b/webkit/glue/resources/webkit_strings_bn.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="bn"> -<translation id="4420062214988137980">প্ল্যাগইন ইনস্টলেশন ব্যর্থ</translation> +<translation id="4519964825805946997"><ph name="URL"/>-এর থেকে প্ল্যাগ-ইন ইনস্টল করতে ব্যর্থ হয়েছে</translation> <translation id="1235745349614807883">সাম্প্রতিক অনুসন্ধানগুলি সাফ করুন</translation> -<translation id="3825324228893189080">অতিরিক্ত প্ল্যাগইন প্রয়োজনীয়</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> প্ল্যাগইন ইনস্টল হয় নি</translation> <translation id="5048533449481078685">তালিকা নির্দেশক</translation> +<translation id="372362261556059955">অতিরিক্ত প্লাগ-ইন দরকার</translation> <translation id="4202807286478387388">লাফ দিন</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">দয়া করে নিশ্চিত করুন, আপনি <ph name="PLUGIN"/> প্ল্যাগইন ইনস্টল করতে চান৷ আপনি বিশ্বাস করেন কেবল এমন প্ল্যাগইনই ইনস্টল করা উচিত৷</translation> <translation id="7658239707568436148">বাতিল</translation> <translation id="795667975304826397">কোনও ফাইল চয়ন করা হয় নি</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> প্ল্যাগইন প্রয়োজনীয়</translation> -<translation id="8662565117025751661">প্ল্যাগইন ডাউনলোড হচ্ছে...</translation> +<translation id="1416462845279468967">প্লাগ-ইন ইনস্টলেশান ব্যর্থ হয়েছে</translation> <translation id="8141602879876242471">এটি অনুসন্ধানযোগ্য সূচি৷ অনুসন্ধানের মূলশব্দ প্রবেশ করান:</translation> +<translation id="5650795167354946011">প্ল্যাগ-ইন ইনস্টল করার পরে, রিফ্রেশ করার জন্য এখানে ক্লিক করুন</translation> <translation id="6845533974506654842">টিপুন</translation> <translation id="8244226242650769279">ছবি মানচিত্র</translation> -<translation id="1383141426028388991"><ph name="URL"/> থেকে প্ল্যাগইন ইনস্টল করতে ব্যর্থ হয়েছে</translation> <translation id="2548326553472216322">কোন সাম্প্রতিক অনুসন্ধান নেই</translation> <translation id="5944544982112848342">2048 (উচ্চ গ্রেড)</translation> <translation id="3040011195152428237">লিঙ্ক</translation> -<translation id="8281246460978372009">প্ল্যাগইন ইনস্টল করার পরে, রিফ্রেশ করার জন্য এখানে ক্লিক করুন</translation> +<translation id="2745343197843472802">প্লাগ-ইন পান</translation> +<translation id="5776402066334188252">আপনি প্ল্যাগ-ইন ইনস্টল করতে চান কি না দয়া করে নিশ্চিত করুন৷ আপনার কেবল সেই প্ল্যাগ-ইনগুলি ইনস্টল করা উচিত যা আপনি বিশ্বাস করেন৷</translation> +<translation id="4003986561708175844">প্রয়োজনীয় প্ল্যাগ-ইন ইনস্টল করা নেই</translation> +<translation id="3018094406922859308">প্লাগ-ইন ডাউনলোড হচ্ছে...</translation> <translation id="7364796246159120393">ফাইল চয়ন করুন</translation> <translation id="8964020114565522021">ফাইল এখানে টেনে আনুন</translation> <translation id="838869780401515933">চেক করুন</translation> <translation id="2846343701378493991">1024 (মধ্যম গ্রেড)</translation> <translation id="5476505524087279545">আনচেক</translation> -<translation id="679352192834563463">এই সামগ্রী প্রদর্শন করার জন্য কোনও প্ল্যাগইন উপলব্ধ নেই</translation> <translation id="3789841737615482174">ইনস্টল করুন</translation> +<translation id="5253117816378681419">আপনি <ph name="PLUGIN"/> প্ল্যাগ-ইনটি ইনস্টল করতে চান কি না দয়া করে নিশ্চিত করুন৷ আপনার কেবল সেই প্ল্যাগ-ইনগুলি ইনস্টল করার উচিত যেগুলিকে আপনি বিশ্বাস করেন৷</translation> <translation id="6663448176199120256">সাম্প্রতিক অনুসন্ধানগুলি</translation> -<translation id="3600343118165084788">প্ল্যাগ ডাউনলোড করার জন্য এখানে ডাউনলোড করুন</translation> +<translation id="2597378329261239068">এই দস্তাবেজটি পাসওয়ার্ড সুরক্ষিত৷ দয়া করে একটি পাসওয়ার্ড লিখুন৷</translation> <translation id="6807599807928161586">ওয়েব এলাকা</translation> <translation id="5939518447894949180">রিসেট করুন</translation> -<translation id="3771786644471114952">প্ল্যাগইন প্রাপ্ত করুন</translation> <translation id="1842960171412779397">নির্বাচন করুন</translation> +<translation id="7638452146404718955">প্ল্যাগ-ইন ডাউনলোড করার জন্য এখানে ক্লিক করুন</translation> <translation id="6119846243427417423">সক্রিয় করুন</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> টি ফাইল</translation> -<translation id="3926627843712816530">আপনি প্ল্যাগইন ইন্স্টল করতে চান তা দয়া করে নিশ্চিত করুন৷ আপনি বিশ্বাস করেন কেবল এমন প্ল্যাগইনই ইনস্টল করা উচিত৷</translation> -<translation id="4838490908464673667">প্রয়োজনীয় প্ল্যাগইন ইনস্টল করা নেই</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> প্লাগ-ইন ইনস্টল নেই</translation> +<translation id="6765711848403622008">এই সামগ্রী প্রদর্শন করার জন্য কোনও প্ল্যাগ-ইন উপলব্ধ নেই</translation> <translation id="8597182159515967513">শিরোনামা</translation> <translation id="2653659639078652383">জমা</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> প্লাগ-ইন প্রয়োজন</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ca.xtb b/webkit/glue/resources/webkit_strings_ca.xtb index b5b1aa7..6f3dc90 100644 --- a/webkit/glue/resources/webkit_strings_ca.xtb +++ b/webkit/glue/resources/webkit_strings_ca.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ca"> -<translation id="4420062214988137980">Error en la instal·lació del complement</translation> +<translation id="4519964825805946997">S'ha produït un error en instal·lar el connector des de <ph name="URL"/></translation> <translation id="1235745349614807883">Esborra les cerques recents</translation> -<translation id="3825324228893189080">Es necessita un complement addicional</translation> -<translation id="2965480764085142436">El complement <ph name="PLUGIN"/> no està instal·lat</translation> <translation id="5048533449481078685">marcador de llistes</translation> +<translation id="372362261556059955">Es necessita un connector addicional</translation> <translation id="4202807286478387388">salta</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Confirma que vols instal·lar el complement <ph name="PLUGIN"/>. Només hauries d'instal·lar complements fiables.</translation> <translation id="7658239707568436148">Cancel·la</translation> <translation id="795667975304826397">No heu seleccionat cap fitxer.</translation> -<translation id="1275511093094545429">Es necessita el complement <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">S'està baixant el complement...</translation> +<translation id="1416462845279468967">S'ha produït un error en instal·lar el connector </translation> <translation id="8141602879876242471">És un índex on es poden realitzar cerques. Introdueix els termes de cerca:</translation> +<translation id="5650795167354946011">Després d'instal·lar el connector, feu clic aquí per actualitzar</translation> <translation id="6845533974506654842">prem</translation> <translation id="8244226242650769279">mapa d'imatges</translation> -<translation id="1383141426028388991">S'ha produït un error en instal·lar el connector des de <ph name="URL"/></translation> <translation id="2548326553472216322">No hi ha cerques recents</translation> <translation id="5944544982112848342">2048 (Gran)</translation> <translation id="3040011195152428237">enllaç</translation> -<translation id="8281246460978372009">Després d'instal·lar el complement, feu clic aquí per actualitzar.</translation> +<translation id="2745343197843472802">Obtén el connector</translation> +<translation id="5776402066334188252">Confirmeu que voleu instal·lar aquest connector. Us recomanem que només instal·leu connectors de la vostra confiança.</translation> +<translation id="4003986561708175844">El connector necessari no està instal·lat</translation> +<translation id="3018094406922859308">S'està baixant el connector...</translation> <translation id="7364796246159120393">Selecciona el fitxer</translation> <translation id="8964020114565522021">Arrossegueu el fitxer aquí.</translation> <translation id="838869780401515933">marca</translation> <translation id="2846343701378493991">1024 (Mitjà)</translation> <translation id="5476505524087279545">desmarca</translation> -<translation id="679352192834563463">No hi ha cap complement disponible per mostrar aquest contingut</translation> <translation id="3789841737615482174">Instal·la</translation> +<translation id="5253117816378681419">Confirmeu que voleu instal·lar el connector <ph name="PLUGIN"/>. Us recomanem que només instal·leu connectors de la vostra confiança.</translation> <translation id="6663448176199120256">Cerques recents</translation> -<translation id="3600343118165084788">Feu clic aquí per baixar el complement</translation> +<translation id="2597378329261239068">Aquest document està protegit mitjançant contrasenya. Introduïu una contrasenya.</translation> <translation id="6807599807928161586">àrea web</translation> <translation id="5939518447894949180">Restablir</translation> -<translation id="3771786644471114952">Obtén el complement</translation> <translation id="1842960171412779397">selecciona</translation> +<translation id="7638452146404718955">Feu clic aquí per baixar el connector</translation> <translation id="6119846243427417423">activa</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> fitxers</translation> -<translation id="3926627843712816530">Confirma que vols instal·lar aquest complement. Només hauries d'instal·lar complements fiables.</translation> -<translation id="4838490908464673667">El complement necessari no està instal·lat</translation> +<translation id="4470547978413275879">El connector <ph name="PLUGIN"/> no està instal·lat</translation> +<translation id="6765711848403622008">No hi ha cap connector disponible per mostrar aquest contingut</translation> <translation id="8597182159515967513">Capçalera</translation> <translation id="2653659639078652383">Envia</translation> +<translation id="8475551193147984329">Es necessita el connector <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_cs.xtb b/webkit/glue/resources/webkit_strings_cs.xtb index 33026e2..33a0d12 100644 --- a/webkit/glue/resources/webkit_strings_cs.xtb +++ b/webkit/glue/resources/webkit_strings_cs.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="cs"> -<translation id="4420062214988137980">Nepodařilo se nainstalovat plugin</translation> +<translation id="4519964825805946997">Instalace pluginu z adresy URL <ph name="URL"/> se nezdařila</translation> <translation id="1235745349614807883">Smazat nedávná vyhledávání</translation> -<translation id="3825324228893189080">Je potřeba další plugin</translation> -<translation id="2965480764085142436">Není nainstalován plugin <ph name="PLUGIN"/></translation> <translation id="5048533449481078685">značka seznamu</translation> +<translation id="372362261556059955">Je zapotřebí další plugin</translation> <translation id="4202807286478387388">přejít</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Potvrďte prosím, že si přejete instalovat plugin <ph name="PLUGIN"/>. Měli byste instalovat pouze takové pluginy, kterým důvěřujete.</translation> <translation id="7658239707568436148">Zrušit</translation> <translation id="795667975304826397">Soubor nevybrán</translation> -<translation id="1275511093094545429">Je potřeba plugin <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Stahování pluginu...</translation> +<translation id="1416462845279468967">Instalace pluginu selhala</translation> <translation id="8141602879876242471">Toto je prohledávatelný index. Zadejte hledaná klíčová slova:</translation> +<translation id="5650795167354946011">Po instalaci pluginu obnovte okno kliknutím sem</translation> <translation id="6845533974506654842">zmáčknout</translation> <translation id="8244226242650769279">obrázková mapa</translation> -<translation id="1383141426028388991">Nepodařilo se nainstalovat plugin z adresy <ph name="URL"/></translation> <translation id="2548326553472216322">Žádná nedávná vyhledávání</translation> <translation id="5944544982112848342">2048 (vysoká kvalita)</translation> <translation id="3040011195152428237">odkaz</translation> -<translation id="8281246460978372009">Po instalaci pluginu klikněte sem pro obnovení</translation> +<translation id="2745343197843472802">Získat plugin</translation> +<translation id="5776402066334188252">Potvrďte prosím, zda tento plugin chcete nainstalovat. Instalujte pouze pluginy, kterým důvěřujete.</translation> +<translation id="4003986561708175844">Požadovaný plugin není nainstalován</translation> +<translation id="3018094406922859308">Stahování pluginu...</translation> <translation id="7364796246159120393">Vybrat soubor</translation> <translation id="8964020114565522021">Přetáhnout soubor sem</translation> <translation id="838869780401515933">zaškrtnout</translation> <translation id="2846343701378493991">1024 (Střední kvalita)</translation> <translation id="5476505524087279545">odstranit zaškrtnutí</translation> -<translation id="679352192834563463">Není k dispozici žádný plugin pro zobrazení tohoto obsahu</translation> <translation id="3789841737615482174">Instalovat</translation> +<translation id="5253117816378681419">Potvrďte prosím, zda chcete nainstalovat plugin <ph name="PLUGIN"/>. Instalujte pouze pluginy, kterým důvěřujete.</translation> <translation id="6663448176199120256">Nedávná vyhledávání</translation> -<translation id="3600343118165084788">Pro stažení pluginu klikněte sem</translation> +<translation id="2597378329261239068">Tento dokument je chráněn heslem. Zadejte prosím heslo.</translation> <translation id="6807599807928161586">oblast webu</translation> <translation id="5939518447894949180">Resetovat</translation> -<translation id="3771786644471114952">Získat plugin</translation> <translation id="1842960171412779397">zvolit</translation> +<translation id="7638452146404718955">Plugin můžete stáhnout kliknutím sem</translation> <translation id="6119846243427417423">aktivovat</translation> <translation id="8444882422881193423">Počet souborů: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Potvrďte, prosím, že si přejete instalovat tento plugin. Měli byste instalovat pouze takové pluginy, kterým důvěřujete.</translation> -<translation id="4838490908464673667">Požadovaný plugin není nainstalován</translation> +<translation id="4470547978413275879">Není nainstalován plugin <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">Není k dispozici žádný plugin k zobrazení tohoto obsahu</translation> <translation id="8597182159515967513">záhlaví</translation> <translation id="2653659639078652383">Odeslat</translation> +<translation id="8475551193147984329">Je požadován plugin <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_da.xtb b/webkit/glue/resources/webkit_strings_da.xtb index a923897..78f06ff 100644 --- a/webkit/glue/resources/webkit_strings_da.xtb +++ b/webkit/glue/resources/webkit_strings_da.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="da"> -<translation id="4420062214988137980">Installation af plugin mislykkedes</translation> +<translation id="4519964825805946997">Installation af plugin fra <ph name="URL"/> mislykkedes</translation> <translation id="1235745349614807883">Slet nylige søgninger</translation> -<translation id="3825324228893189080">Ekstra plugin påkrævet</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> plugin er ikke installeret</translation> <translation id="5048533449481078685">listemarkering</translation> +<translation id="372362261556059955">Ekstra plugin påkrævet</translation> <translation id="4202807286478387388">hop</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Bekræft venligst, at du ønsker at installere plugin'et <ph name="PLUGIN"/>. Du bør udelukkende installere plugins, som du stoler på.</translation> <translation id="7658239707568436148">Annuller</translation> <translation id="795667975304826397">Der er ikke valgt nogen fil</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> Plugin påkrævet</translation> -<translation id="8662565117025751661">Downloader plugin ...</translation> +<translation id="1416462845279468967">Installation af plugin mislykkedes</translation> <translation id="8141602879876242471">Der kan søges i dette indeks. Indtast søge-nøgleord:</translation> +<translation id="5650795167354946011">Når du har installeret plugin'et, skal du klikke her for at opdatere</translation> <translation id="6845533974506654842">tryk</translation> <translation id="8244226242650769279">billedekort</translation> -<translation id="1383141426028388991">Mislykket installation af plugin fra <ph name="URL"/></translation> <translation id="2548326553472216322">Ingen nylige søgninger</translation> <translation id="5944544982112848342">2048 (Høj klasse)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Når du har installeret plugin'et, skal du klikke her for at opdatere</translation> +<translation id="2745343197843472802">Hent plugin</translation> +<translation id="5776402066334188252">Bekræft, at du gerne vil installere dette plugin. Du skal kun installere plugins, som du har tillid til.</translation> +<translation id="4003986561708175844">Det krævede plugin er ikke installeret</translation> +<translation id="3018094406922859308">Downloader plugin...</translation> <translation id="7364796246159120393">Vælg fil</translation> <translation id="8964020114565522021">Træk filer hertil</translation> <translation id="838869780401515933">marker</translation> <translation id="2846343701378493991">1024 (Mellemklasse)</translation> <translation id="5476505524087279545">fjern markering</translation> -<translation id="679352192834563463">Intet tilgængeligt plugin kan vise dette indhold</translation> <translation id="3789841737615482174">Installer</translation> +<translation id="5253117816378681419">Bekræft, at du vil installere dette <ph name="PLUGIN"/>-plugin. Du skal kun installere plugins, som du har tillid til.</translation> <translation id="6663448176199120256">Nylige søgninger</translation> -<translation id="3600343118165084788">Klik her for at downloade plugin</translation> +<translation id="2597378329261239068">Dette dokument er adgangskodebeskyttet. Indtast en adgangskode.</translation> <translation id="6807599807928161586">webområde</translation> <translation id="5939518447894949180">Nulstil</translation> -<translation id="3771786644471114952">Hent plugin</translation> <translation id="1842960171412779397">vælg</translation> +<translation id="7638452146404718955">Klik her for at downloade plugin</translation> <translation id="6119846243427417423">aktiver</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> filer</translation> -<translation id="3926627843712816530">Bekræft venligst, at du gerne vil installere dette plugin. Du bør udelukkende installere plugins, som du stoler på.</translation> -<translation id="4838490908464673667">Det krævede plugin er ikke installeret</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/>-plugin er ikke installeret</translation> +<translation id="6765711848403622008">Intet tilgængeligt plugin kan vise dette indhold</translation> <translation id="8597182159515967513">overskrift</translation> <translation id="2653659639078652383">Indsend</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/>-plugin er påkrævet</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_de.xtb b/webkit/glue/resources/webkit_strings_de.xtb index 76411ed..45fab1b 100644 --- a/webkit/glue/resources/webkit_strings_de.xtb +++ b/webkit/glue/resources/webkit_strings_de.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="de"> -<translation id="4420062214988137980">Plug-in-Installation fehlgeschlagen</translation> +<translation id="4519964825805946997">Installation des Plug-ins von <ph name="URL"/> fehlgeschlagen</translation> <translation id="1235745349614807883">Vor kurzem durchgeführte Suchanfragen löschen</translation> -<translation id="3825324228893189080">Zusätzliches Plug-in erforderlich</translation> -<translation id="2965480764085142436">Plug-in <ph name="PLUGIN"/> nicht installiert</translation> <translation id="5048533449481078685">Listenmarkierung</translation> +<translation id="372362261556059955">Zusätzliches Plug-in erforderlich</translation> <translation id="4202807286478387388">springen</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Bestätigen Sie, dass Sie das Plug-in <ph name="PLUGIN"/> installieren möchten. Sie sollten nur vertrauenswürdige Plug-ins installieren.</translation> <translation id="7658239707568436148">Abbrechen</translation> <translation id="795667975304826397">Keine Datei ausgewählt</translation> -<translation id="1275511093094545429">Plug-in <ph name="PLUGIN"/> erforderlich</translation> -<translation id="8662565117025751661">Plug-in wird heruntergeladen...</translation> +<translation id="1416462845279468967">Plug-in-Installation fehlgeschlagen</translation> <translation id="8141602879876242471">Dieser Index kann durchsucht werden. Geben Sie Suchbegriffe ein:</translation> +<translation id="5650795167354946011">Klicken Sie nach der Installation des Plug-ins hier, um eine Aktualisierung durchzuführen.</translation> <translation id="6845533974506654842">klicken</translation> <translation id="8244226242650769279">Imagemap</translation> -<translation id="1383141426028388991">Installation des Plug-ins von <ph name="URL"/> fehlgeschlagen</translation> <translation id="2548326553472216322">Keine vor kurzem durchgeführte Suchanfragen</translation> <translation id="5944544982112848342">2048 (High Grade)</translation> <translation id="3040011195152428237">Link</translation> -<translation id="8281246460978372009">Klicken Sie nach der Installation des Plug-ins hier, um eine Aktualisierung durchzuführen.</translation> +<translation id="2745343197843472802">Plug-in abrufen</translation> +<translation id="5776402066334188252">Bitte bestätigen Sie, dass Sie dieses Plug-in installieren möchten. Installieren Sie nur Plug-ins, denen Sie vertrauen.</translation> +<translation id="4003986561708175844">Das erforderliche Plug-in ist nicht installiert.</translation> +<translation id="3018094406922859308">Plug-in wird heruntergeladen...</translation> <translation id="7364796246159120393">Datei auswählen</translation> <translation id="8964020114565522021">Datei hier ablegen</translation> <translation id="838869780401515933">auswählen</translation> <translation id="2846343701378493991">1024 (mittlere Stufe)</translation> <translation id="5476505524087279545">Auswahl aufheben</translation> -<translation id="679352192834563463">Kein Plug-in zum Anzeigen dieses Contents verfügbar</translation> <translation id="3789841737615482174">Installieren</translation> +<translation id="5253117816378681419">Bitte bestätigen Sie, dass Sie das Plug-in <ph name="PLUGIN"/> installieren möchten. Installieren Sie nur Plug-ins, denen Sie vertrauen.</translation> <translation id="6663448176199120256">Vor kurzem durchgeführte Suchanfragen</translation> -<translation id="3600343118165084788">Klicken Sie hier, um das Plug-in herunterzuladen.</translation> +<translation id="2597378329261239068">Dieses Dokument ist passwortgeschützt. Geben Sie ein Passwort ein.</translation> <translation id="6807599807928161586">Webbereich</translation> <translation id="5939518447894949180">Zurücksetzen</translation> -<translation id="3771786644471114952">Plug-in abrufen</translation> <translation id="1842960171412779397">auswählen</translation> +<translation id="7638452146404718955">Hier klicken, um das Plug-in herunterzuladen</translation> <translation id="6119846243427417423">aktivieren</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> Dateien</translation> -<translation id="3926627843712816530">Bestätigen Sie, dass Sie dieses Plug-in installieren möchten. Sie sollten nur vertrauenswürdige Plug-ins installieren.</translation> -<translation id="4838490908464673667">Das erforderliche Plug-in ist nicht installiert</translation> +<translation id="4470547978413275879">Plug-in <ph name="PLUGIN"/> nicht installiert</translation> +<translation id="6765711848403622008">Kein Plug-in zum Anzeigen dieses Contents verfügbar</translation> <translation id="8597182159515967513">Kopfzeile</translation> <translation id="2653659639078652383">Senden</translation> +<translation id="8475551193147984329">Plug-in <ph name="PLUGIN"/> ist erforderlich</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_el.xtb b/webkit/glue/resources/webkit_strings_el.xtb index dd75011..509307e 100644 --- a/webkit/glue/resources/webkit_strings_el.xtb +++ b/webkit/glue/resources/webkit_strings_el.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="el"> -<translation id="4420062214988137980">Η εγκατάσταση της προσθήκης απέτυχε</translation> +<translation id="4519964825805946997">Η εγκατάσταση της προσθήκης από τη διεύθυνση <ph name="URL"/> απέτυχε</translation> <translation id="1235745349614807883">Εκκαθάριση πρόσφατων αναζητήσεων</translation> -<translation id="3825324228893189080">Απαιτείται επιπλέον προσθήκη</translation> -<translation id="2965480764085142436">Η προσθήκη <ph name="PLUGIN"/> δεν έχει εγκατασταθεί</translation> <translation id="5048533449481078685">δείκτης λίστας</translation> +<translation id="372362261556059955">Απαιτείται επιπλέον προσθήκη</translation> <translation id="4202807286478387388">μεταπήδηση</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Επιβεβαιώστε ότι θέλετε να εγκαταστήσετε την προσθήκη <ph name="PLUGIN"/>. Πρέπει να εγκαθιστάτε μόνο προσθήκες που θεωρείτε αξιόπιστες.</translation> <translation id="7658239707568436148">Ακύρωση</translation> <translation id="795667975304826397">Δεν έχει επιλεγεί κανένα αρχείο</translation> -<translation id="1275511093094545429">Χρειάζεται η προσθήκη <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Λήψη προσθήκης...</translation> +<translation id="1416462845279468967">Η εγκατάσταση προσθήκης απέτυχε</translation> <translation id="8141602879876242471">Πρόκειται για ευρετήριο με δυνατότητα αναζήτησης. Πληκτρολογήστε λέξεις-κλειδιά αναζήτησης:</translation> +<translation id="5650795167354946011">Μετά την εγκατάσταση της προσθήκης, κάντε κλικ εδώ για ανανέωση των δεδομένων</translation> <translation id="6845533974506654842">πατήστε</translation> <translation id="8244226242650769279">χάρτης εικόνας</translation> -<translation id="1383141426028388991">Η εγκατάσταση της προσθήκης από τη διεύθυνση <ph name="URL"/> απέτυχε</translation> <translation id="2548326553472216322">Δεν υπάρχουν πρόσφατες αναζητήσεις</translation> <translation id="5944544982112848342">2048 (Υψηλός βαθμός)</translation> <translation id="3040011195152428237">σύνδεσμος</translation> -<translation id="8281246460978372009">Μετά την εγκατάσταση της προσθήκης, κάντε κλικ εδώ για ανανέωση</translation> +<translation id="2745343197843472802">Λήψη προσθήκης</translation> +<translation id="5776402066334188252">Επιβεβαιώστε ότι θέλετε να εγκαταστήσετε αυτή την προσθήκη. Πρέπει να εγκαθιστάτε μόνο προσθήκες που θεωρείτε αξιόπιστες.</translation> +<translation id="4003986561708175844">Η απαιτούμενη προσθήκη δεν έχει εγκατασταθεί</translation> +<translation id="3018094406922859308">Λήψη προσθήκης...</translation> <translation id="7364796246159120393">Επιλογή αρχείου</translation> <translation id="8964020114565522021">Σύρετε το αρχείο εδώ</translation> <translation id="838869780401515933">ενεργοποίηση</translation> <translation id="2846343701378493991">1024 (Μέτριος βαθμός)</translation> <translation id="5476505524087279545">απενεργοποίηση</translation> -<translation id="679352192834563463">Δεν υπάρχει διαθέσιμη προσθήκη για την εμφάνιση του περιεχομένου</translation> <translation id="3789841737615482174">Εγκατάσταση</translation> +<translation id="5253117816378681419">Επιβεβαιώστε ότι θέλετε να εγκαταστήσετε την προσθήκη <ph name="PLUGIN"/>. Πρέπει να εγκαθιστάτε μόνο προσθήκες που θεωρείτε αξιόπιστες.</translation> <translation id="6663448176199120256">Πρόσφατες αναζητήσεις</translation> -<translation id="3600343118165084788">Κάντε κλικ εδώ για να κατεβάσετε την προσθήκη</translation> +<translation id="2597378329261239068">Αυτό το έγγραφο προστατεύεται με κωδικό πρόσβασης. Πληκτρολογήστε έναν κωδικό πρόσβασης.</translation> <translation id="6807599807928161586">περιοχή ιστού</translation> <translation id="5939518447894949180">Επαναφορά</translation> -<translation id="3771786644471114952">Λήψη προσθήκης</translation> <translation id="1842960171412779397">επιλογή</translation> +<translation id="7638452146404718955">Κάντε κλικ εδώ για να κάνετε λήψη της προσθήκης</translation> <translation id="6119846243427417423">ενεργοποίηση</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> αρχεία</translation> -<translation id="3926627843712816530">Επιβεβαιώστε ότι θέλετε να εγκαταστήσετε αυτή την προσθήκη. Πρέπει να εγκαθιστάτε μόνο προσθήκες που θεωρείτε αξιόπιστες.</translation> -<translation id="4838490908464673667">Η απαιτούμενη προσθήκη δεν έχει εγκατασταθεί</translation> +<translation id="4470547978413275879">Η προσθήκη <ph name="PLUGIN"/> δεν έχει εγκατασταθεί</translation> +<translation id="6765711848403622008">Δεν υπάρχει διαθέσιμη προσθήκη για την εμφάνιση αυτού του περιεχομένου</translation> <translation id="8597182159515967513">επικεφαλίδα</translation> <translation id="2653659639078652383">Υποβολή</translation> +<translation id="8475551193147984329">Απαιτείται η προσθήκη <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_en-GB.xtb b/webkit/glue/resources/webkit_strings_en-GB.xtb index ed7a1b6..14befa8 100644 --- a/webkit/glue/resources/webkit_strings_en-GB.xtb +++ b/webkit/glue/resources/webkit_strings_en-GB.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="en-GB"> -<translation id="4420062214988137980">Plug-in installation failed</translation> +<translation id="4519964825805946997">Failed to install plug-in from <ph name="URL"/></translation> <translation id="1235745349614807883">Clear Recent Searches</translation> -<translation id="3825324228893189080">Additional plug-in needed</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> plug-in is not installed</translation> <translation id="5048533449481078685">list marker</translation> +<translation id="372362261556059955">Additional plug-in needed</translation> <translation id="4202807286478387388">jump</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Please confirm that you would like to install the <ph name="PLUGIN"/> plug-in. You should only install plug-ins that you trust.</translation> <translation id="7658239707568436148">Cancel</translation> <translation id="795667975304826397">No file chosen</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> plug-in needed</translation> -<translation id="8662565117025751661">Downloading plug-in...</translation> +<translation id="1416462845279468967">Plug-in installation failed</translation> <translation id="8141602879876242471">This is a searchable index. Enter search keywords:</translation> +<translation id="5650795167354946011">After installing the plug-in, click here to refresh</translation> <translation id="6845533974506654842">press</translation> <translation id="8244226242650769279">image map</translation> -<translation id="1383141426028388991">Failed to install plug-in from <ph name="URL"/></translation> <translation id="2548326553472216322">No recent searches</translation> <translation id="5944544982112848342">2048 (High Grade)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">After installing the plug-in, click here to refresh</translation> +<translation id="2745343197843472802">Get Plug-in</translation> +<translation id="5776402066334188252">Please confirm that you would like to install this plug-in. You should only install plug-ins that you trust.</translation> +<translation id="4003986561708175844">The plug-in required is not installed</translation> +<translation id="3018094406922859308">Downloading plug-in...</translation> <translation id="7364796246159120393">Choose File</translation> <translation id="8964020114565522021">Drag file here</translation> <translation id="838869780401515933">tick</translation> <translation id="2846343701378493991">1024 (Medium Grade)</translation> <translation id="5476505524087279545">untick</translation> -<translation id="679352192834563463">No plug-in available to display this content</translation> <translation id="3789841737615482174">Install</translation> +<translation id="5253117816378681419">Please confirm that you would like to install the <ph name="PLUGIN"/> plug-in. You should only install plug-ins that you trust.</translation> <translation id="6663448176199120256">Recent Searches</translation> -<translation id="3600343118165084788">Click here to download plug-in</translation> +<translation id="2597378329261239068">This document is password-protected. Please enter a password.</translation> <translation id="6807599807928161586">web area</translation> <translation id="5939518447894949180">Reset</translation> -<translation id="3771786644471114952">Get Plug-in</translation> <translation id="1842960171412779397">select</translation> +<translation id="7638452146404718955">Click here to download plug-in</translation> <translation id="6119846243427417423">activate</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> files</translation> -<translation id="3926627843712816530">Please confirm that you would like to install this plug-in. You should only install plug-ins that you trust.</translation> -<translation id="4838490908464673667">The required plug-in is not installed</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> plug-in is not installed</translation> +<translation id="6765711848403622008">No plug-in available to display this content</translation> <translation id="8597182159515967513">heading</translation> <translation id="2653659639078652383">Submit</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> plug-in needed</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_es-419.xtb b/webkit/glue/resources/webkit_strings_es-419.xtb index d7e05f4..12bc57b 100644 --- a/webkit/glue/resources/webkit_strings_es-419.xtb +++ b/webkit/glue/resources/webkit_strings_es-419.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="es-419"> -<translation id="4420062214988137980">Error en la instalación del plug-in</translation> +<translation id="4519964825805946997">Error al instalar el complemento desde <ph name="URL"/></translation> <translation id="1235745349614807883">Eliminar búsquedas recientes</translation> -<translation id="3825324228893189080">Se necesita un plug-in adicional</translation> -<translation id="2965480764085142436">El plug-in <ph name="PLUGIN"/> no está instalado</translation> <translation id="5048533449481078685">marcador de listas</translation> +<translation id="372362261556059955">Se necesita un complemento adicional</translation> <translation id="4202807286478387388">saltar</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Confirma que deseas instalar el plug-in <ph name="PLUGIN"/>. Solo debes instalar plug-in fiables.</translation> <translation id="7658239707568436148">Cancelar</translation> <translation id="795667975304826397">No se eligió ningún archivo</translation> -<translation id="1275511093094545429">Se requiere el plug-in <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Descargando plug-in...</translation> +<translation id="1416462845279468967">Error de instalación del complemento</translation> <translation id="8141602879876242471">Se trata de un índice que admite búsquedas. Escribe las palabras clave de búsqueda:</translation> +<translation id="5650795167354946011">Después de instalar el complemento, haz clic aquí para actualizar</translation> <translation id="6845533974506654842">hacer clic</translation> <translation id="8244226242650769279">mapa de imágenes</translation> -<translation id="1383141426028388991">Error al instalar el complemento desde <ph name="URL"/></translation> <translation id="2548326553472216322">No hay búsquedas recientes</translation> <translation id="5944544982112848342">2048 (Grado elevado)</translation> <translation id="3040011195152428237">enlace</translation> -<translation id="8281246460978372009">Tras instalar el complemento, haz clic aquí para actualizar.</translation> +<translation id="2745343197843472802">Obtener complemento</translation> +<translation id="5776402066334188252">Confirma que deseas instalar este complemento. Sólo deberías instalar los complementos confiables.</translation> +<translation id="4003986561708175844">El complemento requerido no está instalado</translation> +<translation id="3018094406922859308">Descargando complemento...</translation> <translation id="7364796246159120393">Seleccionar archivo</translation> <translation id="8964020114565522021">Arrastre el archivo hasta aquí</translation> <translation id="838869780401515933">marcar</translation> <translation id="2846343701378493991">1024 (Mediano)</translation> <translation id="5476505524087279545">desmarcar</translation> -<translation id="679352192834563463">No hay ningún plug-in disponible para mostrar este contenido</translation> <translation id="3789841737615482174">Instalar</translation> +<translation id="5253117816378681419">Confirma que deseas instalar el complemento <ph name="PLUGIN"/>. Sólo deberías instalar los complementos confiables.</translation> <translation id="6663448176199120256">Búsquedas recientes</translation> -<translation id="3600343118165084788">Haz clic aquí para descargar el plug-in.</translation> +<translation id="2597378329261239068">Este documento está protegido por contraseña. Ingresa una contraseña.</translation> <translation id="6807599807928161586">área web</translation> <translation id="5939518447894949180">Restablecer</translation> -<translation id="3771786644471114952">Obtener plug-in</translation> <translation id="1842960171412779397">seleccionar</translation> +<translation id="7638452146404718955">Haz clic aquí para descargar el complemento</translation> <translation id="6119846243427417423">activar</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> archivos</translation> -<translation id="3926627843712816530">Confirma que deseas instalar este plug-in. Solo debes instalar plug-in fiables.</translation> -<translation id="4838490908464673667">El plug-in necesario no está instalado.</translation> +<translation id="4470547978413275879">El complemento <ph name="PLUGIN"/> no está instalado</translation> +<translation id="6765711848403622008">No se encuentra disponible ningún complemento para mostrar este contenido</translation> <translation id="8597182159515967513">cabecera</translation> <translation id="2653659639078652383">Enviar</translation> +<translation id="8475551193147984329">Se necesita el complemento <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_es.xtb b/webkit/glue/resources/webkit_strings_es.xtb index c95525d..5f9a245 100644 --- a/webkit/glue/resources/webkit_strings_es.xtb +++ b/webkit/glue/resources/webkit_strings_es.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="es"> -<translation id="4420062214988137980">Error en la instalación del plug-in</translation> +<translation id="4519964825805946997">Se ha producido un error al descargar el complemento de la página <ph name="URL"/>.</translation> <translation id="1235745349614807883">Eliminar búsquedas recientes</translation> -<translation id="3825324228893189080">Se necesita un plug-in adicional</translation> -<translation id="2965480764085142436">El plug-in <ph name="PLUGIN"/> no está instalado</translation> <translation id="5048533449481078685">marcador de listas</translation> +<translation id="372362261556059955">Se necesita un complemento adicional</translation> <translation id="4202807286478387388">saltar</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Confirma que deseas instalar el plug-in <ph name="PLUGIN"/>. Solo debes instalar plug-in fiables.</translation> <translation id="7658239707568436148">Cancelar</translation> <translation id="795667975304826397">No se ha seleccionado ningun archivo</translation> -<translation id="1275511093094545429">Se requiere el plug-in <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Descargando plug-in...</translation> +<translation id="1416462845279468967">Se ha producido un error al instalar el complemento.</translation> <translation id="8141602879876242471">Se trata de un índice que admite búsquedas. Introduce las palabras clave de búsqueda:</translation> +<translation id="5650795167354946011">Una vez que hayas instalado el complemento, haz clic aquí para actualizar la ventana.</translation> <translation id="6845533974506654842">pulsar</translation> <translation id="8244226242650769279">mapa de imágenes</translation> -<translation id="1383141426028388991">Error al instalar el plugin desde <ph name="URL"/></translation> <translation id="2548326553472216322">No hay búsquedas recientes</translation> <translation id="5944544982112848342">2048 (Grado elevado)</translation> <translation id="3040011195152428237">enlace</translation> -<translation id="8281246460978372009">Tras instalar el complemento, haz clic aquí para actualizar.</translation> +<translation id="2745343197843472802">Obtener complemento</translation> +<translation id="5776402066334188252">Confirma que quieres instalar este complemento. Solo debes instalar complementos en los que confíes.</translation> +<translation id="4003986561708175844">No está instalado el complemento necesario.</translation> +<translation id="3018094406922859308">Cargando complemento...</translation> <translation id="7364796246159120393">Seleccionar archivo</translation> <translation id="8964020114565522021">Arrastrar archivo hasta aquí</translation> <translation id="838869780401515933">marcar</translation> <translation id="2846343701378493991">1024 (Mediano)</translation> <translation id="5476505524087279545">desmarcar</translation> -<translation id="679352192834563463">No hay ningún plug-in disponible para mostrar este contenido</translation> <translation id="3789841737615482174">Instalar</translation> +<translation id="5253117816378681419">Confirma que quieres instalar el complemento <ph name="PLUGIN"/>. Solo debes instalar complementos en los que confíes.</translation> <translation id="6663448176199120256">Búsquedas recientes</translation> -<translation id="3600343118165084788">Haz clic aquí para descargar el plug-in.</translation> +<translation id="2597378329261239068">Este documento está protegido por contraseña. Introduce una contraseña.</translation> <translation id="6807599807928161586">área web</translation> <translation id="5939518447894949180">Restablecer</translation> -<translation id="3771786644471114952">Obtener plug-in</translation> <translation id="1842960171412779397">seleccionar</translation> +<translation id="7638452146404718955">Haz clic aquí para descargar el complemento.</translation> <translation id="6119846243427417423">activar</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> archivos</translation> -<translation id="3926627843712816530">Confirma que deseas instalar este plug-in. Solo debes instalar plug-in fiables.</translation> -<translation id="4838490908464673667">El plug-in necesario no está instalado.</translation> +<translation id="4470547978413275879">El complemento <ph name="PLUGIN"/> no está instalado.</translation> +<translation id="6765711848403622008">No hay ningún complemento disponible para mostrar este contenido.</translation> <translation id="8597182159515967513">cabecera</translation> <translation id="2653659639078652383">Enviar</translation> +<translation id="8475551193147984329">Es necesario el complemento <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_et.xtb b/webkit/glue/resources/webkit_strings_et.xtb index c449c06..2ac3c7a 100644 --- a/webkit/glue/resources/webkit_strings_et.xtb +++ b/webkit/glue/resources/webkit_strings_et.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="et"> -<translation id="4420062214988137980">Lisandmooduli install ebaõnnestus</translation> +<translation id="4519964825805946997">Pistikprogrammi installimine asukohast <ph name="URL"/> ebaõnnestus.</translation> <translation id="1235745349614807883">Kustuta viimased otsingud</translation> -<translation id="3825324228893189080">Vajalik täiendav lisandmoodul</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> lisandmoodul ei ole installitud</translation> <translation id="5048533449481078685">loendilooja</translation> +<translation id="372362261556059955">Vaja on täiendavat pistikprogrammi</translation> <translation id="4202807286478387388">liigu</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Palun kinnitage, et soovite installida selle lisandmooduli <ph name="PLUGIN"/>. Te peaksite installima lisandmooduleid, mida usaldate.</translation> <translation id="7658239707568436148">Loobu</translation> <translation id="795667975304826397">Ühtegi faili pole valitud</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> vajalik lisandmoodul</translation> -<translation id="8662565117025751661">Lisandmooduli allalaadimine...</translation> +<translation id="1416462845279468967">Pistikprogrammi installimine nurjus</translation> <translation id="8141602879876242471">See on otsitav indeks. Sisestage otsingu jaoks märksõnad:</translation> +<translation id="5650795167354946011">Pärast lisandmooduli installimist klõpsake värskendamiseks siin</translation> <translation id="6845533974506654842">vajuta</translation> <translation id="8244226242650769279">hüperpilt</translation> -<translation id="1383141426028388991">Lisandmooduli installimine aadressilt <ph name="URL"/> ebaõnnestus.</translation> <translation id="2548326553472216322">Pole viimaseid otsingud</translation> <translation id="5944544982112848342">2048 (kõrge)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Pärast lisandmooduli installimist klõpsake värskendamiseks siia</translation> +<translation id="2745343197843472802">Hangi pistikprogramm</translation> +<translation id="5776402066334188252">Palun kinnitage, et soovite pistikprogrammi installida. Peaksite installima vaid usaldusväärseid pistikprogramme.</translation> +<translation id="4003986561708175844">Nõutav pistikprogramm ei ole installitud</translation> +<translation id="3018094406922859308">Pistikprogrammi allalaadimine...</translation> <translation id="7364796246159120393">Vali fail</translation> <translation id="8964020114565522021">Lohistage fail siia</translation> <translation id="838869780401515933">mrgista</translation> <translation id="2846343701378493991">1024 (keskmine)</translation> <translation id="5476505524087279545">eemalda mrgistus</translation> -<translation id="679352192834563463">Selle sisu kuvamiseks pole saadaval lisandmoodulit</translation> <translation id="3789841737615482174">Installi</translation> +<translation id="5253117816378681419">Palun kinnitage, et soovite pistikprogrammi <ph name="PLUGIN"/> installida. Peaksite installima vaid usaldusväärseid pistikprogramme.</translation> <translation id="6663448176199120256">Viimased otsingud</translation> -<translation id="3600343118165084788">Lisandmooduli allalaadimiseks klõpsake siia.</translation> +<translation id="2597378329261239068">Dokument on parooliga kaitstud. Sisestage parool.</translation> <translation id="6807599807928161586">veebiala</translation> <translation id="5939518447894949180">Lähtesta</translation> -<translation id="3771786644471114952">Hangi lisandmoodul</translation> <translation id="1842960171412779397">vali</translation> +<translation id="7638452146404718955">Pistikprogrammi allalaadimiseks klõpsake siin</translation> <translation id="6119846243427417423">aktiveeri</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> faili</translation> -<translation id="3926627843712816530">Palun kinnitage, et soovite installida selle lisandmooduli. Te peaksite installima lisandmooduleid, mida usaldate.</translation> -<translation id="4838490908464673667">Nõutav lisandmoodul pole installitud</translation> +<translation id="4470547978413275879">Pistikprogramm <ph name="PLUGIN"/> ei ole installitud</translation> +<translation id="6765711848403622008">Sisu kuvamiseks ei ole saadaval pistikprogrammi</translation> <translation id="8597182159515967513">pealkiri</translation> <translation id="2653659639078652383">Esita</translation> +<translation id="8475551193147984329">Vajalik on pistikprogramm <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_fi.xtb b/webkit/glue/resources/webkit_strings_fi.xtb index 50f3a69..4a1b6a3 100644 --- a/webkit/glue/resources/webkit_strings_fi.xtb +++ b/webkit/glue/resources/webkit_strings_fi.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="fi"> -<translation id="4420062214988137980">Laajennuksen asennus epäonnistui</translation> +<translation id="4519964825805946997">Laajennuksen asennus osoitteesta <ph name="URL"/> epäonnistui</translation> <translation id="1235745349614807883">Poista viimeisimmät haut</translation> -<translation id="3825324228893189080">Lisälaajennus tarvitaan</translation> -<translation id="2965480764085142436">Laajennusta <ph name="PLUGIN"/> ei asennettu</translation> <translation id="5048533449481078685">luettelon merkitsijä</translation> +<translation id="372362261556059955">Toinen laajennus vaaditaan</translation> <translation id="4202807286478387388">siirry</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Vahvista, että haluat asentaa laajennuksen <ph name="PLUGIN"/>. Kannattaa asentaa vain luotettavia laajennuksia.</translation> <translation id="7658239707568436148">Peruuta</translation> <translation id="795667975304826397">Ei valittua tiedostoa</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> laajennus tarvitaan</translation> -<translation id="8662565117025751661">Ladataan laajennusta...</translation> +<translation id="1416462845279468967">Laajennuksen asennus epäonnistui</translation> <translation id="8141602879876242471">Tämä on haettavissa oleva hakemisto. Anna hakusanat:</translation> +<translation id="5650795167354946011">Päivitä laajennuksen asennuksen jälkeen napsauttamalla tästä</translation> <translation id="6845533974506654842">paina</translation> <translation id="8244226242650769279">kuvakartta</translation> -<translation id="1383141426028388991">Laajennuksen asennus osoitteesta <ph name="URL"/> epäonnistui</translation> <translation id="2548326553472216322">Ei viimeisimpiä hakuja</translation> <translation id="5944544982112848342">2048 (korkea taso)</translation> <translation id="3040011195152428237">linkki</translation> -<translation id="8281246460978372009">Päivitä laajennuksen asennuksen jälkeen napsauttamalla tästä</translation> +<translation id="2745343197843472802">Hanki laajennus</translation> +<translation id="5776402066334188252">Vahvista, että haluat asentaa tämän laajennuksen. Suosittelemme asentamaan vain laajennuksia, joihin luotat.</translation> +<translation id="4003986561708175844">Vaadittua laajennusta ei ole asennettu</translation> +<translation id="3018094406922859308">Laajennusta ladataan...</translation> <translation id="7364796246159120393">Valitse tiedosto</translation> <translation id="8964020114565522021">Vedä tiedosto tähän</translation> <translation id="838869780401515933">valitse</translation> <translation id="2846343701378493991">1024 (keskitaso)</translation> <translation id="5476505524087279545">poista valinta</translation> -<translation id="679352192834563463">Tämän sisällön näyttämiseen ei ole saatavissa laajennusta</translation> <translation id="3789841737615482174">Asenna</translation> +<translation id="5253117816378681419">Vahvista, että haluat asentaa laajennuksen <ph name="PLUGIN"/>. Suosittelemme asentamaan vain laajennuksia, joihin luotat.</translation> <translation id="6663448176199120256">Viimeisimmät haut</translation> -<translation id="3600343118165084788">Lataa laajennus napsauttamalla tätä</translation> +<translation id="2597378329261239068">Tämä asiakirja on suojattu salasanalla. Anna salasana.</translation> <translation id="6807599807928161586">verkkoalue</translation> <translation id="5939518447894949180">Tyhjennä</translation> -<translation id="3771786644471114952">Hae laajennus</translation> <translation id="1842960171412779397">Valitse</translation> +<translation id="7638452146404718955">Lataa laajennus napsauttamalla tätä</translation> <translation id="6119846243427417423">aktivoi</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> tiedostoa</translation> -<translation id="3926627843712816530">Vahvista, että haluat asentaa tämän laajennuksen. Kannattaa asentaa vain luotettavia laajennuksia.</translation> -<translation id="4838490908464673667">Vaadittua laajennusta ei ole asennettu</translation> +<translation id="4470547978413275879">Laajennusta <ph name="PLUGIN"/> ei asennettu</translation> +<translation id="6765711848403622008">Tämän sisällön näyttämiseen ei ole saatavissa laajennusta</translation> <translation id="8597182159515967513">otsikko</translation> <translation id="2653659639078652383">Lähetä</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/>-laajennus vaaditaan</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_fil.xtb b/webkit/glue/resources/webkit_strings_fil.xtb index 5ed7e04..43f88c3 100644 --- a/webkit/glue/resources/webkit_strings_fil.xtb +++ b/webkit/glue/resources/webkit_strings_fil.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="fil"> -<translation id="4420062214988137980">Nabigong pag-install sa plugin</translation> +<translation id="4519964825805946997">Nabigong ma-install ang plug-in mula sa <ph name="URL"/></translation> <translation id="1235745349614807883">Lisiman ang Kasalukuyang Mga Paghahanap</translation> -<translation id="3825324228893189080">Kailangan ng karagdagang plugin</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> hindi na-install ang plugin</translation> <translation id="5048533449481078685">Ilista ang marker</translation> +<translation id="372362261556059955">Kinakailangan ang karagdagang plug-in</translation> <translation id="4202807286478387388">tumalon</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Mangyaring kumpirmahin na nais mong i-install ang <ph name="PLUGIN"/> plugin. Dapat mo lamang i-install ang mga plugin na pinagkakatiwalaan mo.</translation> <translation id="7658239707568436148">Ikansela</translation> <translation id="795667975304826397">Walang napiling file</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> kinakailangang plugin</translation> -<translation id="8662565117025751661">Nagda-download ng plugin...</translation> +<translation id="1416462845279468967">Nabigo ang pag-install ng plug-in</translation> <translation id="8141602879876242471">Isa itong paghahanap ng index. Ipasok ang paghahanap sa mga keyword:</translation> +<translation id="5650795167354946011">Pagkatapos i-install ng plug-in, mag-click dito upang mag-refresh</translation> <translation id="6845533974506654842">pindutin</translation> <translation id="8244226242650769279">mapa ng imahe</translation> -<translation id="1383141426028388991">Nabigong i-install ang plugin mula sa <ph name="URL"/></translation> <translation id="2548326553472216322">Walang kamakailang mga paghahanap</translation> <translation id="5944544982112848342">2048 (Pinakamataas na Marka)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Matapos ang pag-install ng plugin, mag-click dito upang mag-refresh</translation> +<translation id="2745343197843472802">Kumuha ng Plug-in</translation> +<translation id="5776402066334188252">Pakikumpirma na nais mong i-install ang plug-in na ito. Dapat mong i-install lamang ang mga plug-in na iyong pinagkakatiwalaan.</translation> +<translation id="4003986561708175844">Hindi na-install ang kinakailangang plug-in</translation> +<translation id="3018094406922859308">Nagda-download ng plug-in...</translation> <translation id="7364796246159120393">Pumili ng File</translation> <translation id="8964020114565522021">Kaldkarin dito ang file</translation> <translation id="838869780401515933">I-tsek</translation> <translation id="2846343701378493991">1024 (Katamtamang Grado)</translation> <translation id="5476505524087279545">i-uncheck</translation> -<translation id="679352192834563463">Walang magagamit na plugin na ipapakita sa nilalaman nito</translation> <translation id="3789841737615482174">Install</translation> +<translation id="5253117816378681419">Pakikumpirma na gusto mong i-install ang <ph name="PLUGIN"/> plug-in na ito. Dapat mong i-install lamang ang mga plug-in na iyong pinagkakatiwalaan.</translation> <translation id="6663448176199120256">Kasalukuyang Mga Paghahanap</translation> -<translation id="3600343118165084788">Mag-click dito upagn mai-download ang plugin</translation> +<translation id="2597378329261239068">Protektado ng password ang dokumentong ito. Mangyaring magpasok ng password.</translation> <translation id="6807599807928161586">web area</translation> <translation id="5939518447894949180">I-reset</translation> -<translation id="3771786644471114952">Kunin ang Plugin</translation> <translation id="1842960171412779397">piliin</translation> +<translation id="7638452146404718955">Mag-click dito upang ma-download ang plug-in</translation> <translation id="6119846243427417423">isaaktibo</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> mga file</translation> -<translation id="3926627843712816530">Mangyaring kumpirmahin na dapat gusto mong i-install sa plugin na ito. Dapat mo lamang i-install ang mga plugin na pinagkakatiwalaan mo.</translation> -<translation id="4838490908464673667">Ang kinakailangan na plugin ay hindi na-install</translation> +<translation id="4470547978413275879">Hindi naka-install ang <ph name="PLUGIN"/> na plug-in</translation> +<translation id="6765711848403622008">Walang magagamit na plug-in upang maipakita ang nilalamang ito</translation> <translation id="8597182159515967513">heading</translation> <translation id="2653659639078652383">Isumite</translation> +<translation id="8475551193147984329">Kinakailangan ang plug-in na <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_fr.xtb b/webkit/glue/resources/webkit_strings_fr.xtb index 1f78547..00ab953 100644 --- a/webkit/glue/resources/webkit_strings_fr.xtb +++ b/webkit/glue/resources/webkit_strings_fr.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="fr"> -<translation id="4420062214988137980">Échec de l'installation du plug-in</translation> +<translation id="4519964825805946997">Échec de l'installation du plug-in depuis <ph name="URL"/></translation> <translation id="1235745349614807883">Effacer les recherches récentes</translation> -<translation id="3825324228893189080">Plug-in supplémentaire requis</translation> -<translation id="2965480764085142436">Le plug-in <ph name="PLUGIN"/> n'est pas installé.</translation> <translation id="5048533449481078685">marqueur de liste</translation> +<translation id="372362261556059955">Plug-in supplémentaire requis</translation> <translation id="4202807286478387388">accéder</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/> × <ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Veuillez confirmer que vous souhaitez installer le plug-in <ph name="PLUGIN"/>. Veillez à installer uniquement des plug-ins approuvés.</translation> <translation id="7658239707568436148">Annuler</translation> <translation id="795667975304826397">Aucun fichier choisi</translation> -<translation id="1275511093094545429">Plug-in <ph name="PLUGIN"/> requis</translation> -<translation id="8662565117025751661">Téléchargement du plug-in...</translation> +<translation id="1416462845279468967">Échec de l'installation du plug-in</translation> <translation id="8141602879876242471">Vous pouvez lancer des recherches dans cet index. Pour cela, entrez des mots clés de recherche :</translation> +<translation id="5650795167354946011">Après l'installation du plug-in, cliquez ici pour actualiser.</translation> <translation id="6845533974506654842">appuyer</translation> <translation id="8244226242650769279">image map</translation> -<translation id="1383141426028388991">Échec de l'installation du plugin depuis <ph name="URL"/></translation> <translation id="2548326553472216322">Aucune recherche récente</translation> <translation id="5944544982112848342">2048 (haute sécurité)</translation> <translation id="3040011195152428237">Lien</translation> -<translation id="8281246460978372009">Après l'installation du plug-in, cliquez ici pour actualiser.</translation> +<translation id="2745343197843472802">Télécharger le plug-in</translation> +<translation id="5776402066334188252">Merci de confirmer que vous souhaitez installer ce plug-in. N'installez que les plug-ins que vous considérez fiables.</translation> +<translation id="4003986561708175844">Le plug-in requis n'est pas installé.</translation> +<translation id="3018094406922859308">Téléchargement du plug-in...</translation> <translation id="7364796246159120393">Choisissez un fichier</translation> <translation id="8964020114565522021">Placer le fichier ici</translation> <translation id="838869780401515933">cocher</translation> <translation id="2846343701378493991">1024 (sécurité moyenne)</translation> <translation id="5476505524087279545">décocher</translation> -<translation id="679352192834563463">Aucun plug-in disponible pour afficher ce contenu</translation> <translation id="3789841737615482174">Installer</translation> +<translation id="5253117816378681419">Merci de confirmer que vous souhaitez installer le plug-in <ph name="PLUGIN"/>. N'installez que les plug-ins que vous considérez fiables.</translation> <translation id="6663448176199120256">Recherches récentes</translation> -<translation id="3600343118165084788">Cliquez ici pour télécharger le plug-in</translation> +<translation id="2597378329261239068">Ce document est protégé par mot de passe. Veuillez saisir ce dernier.</translation> <translation id="6807599807928161586">Zone Web</translation> <translation id="5939518447894949180">Réinitialiser</translation> -<translation id="3771786644471114952">Ajouter le plug-in</translation> <translation id="1842960171412779397">sélectionner</translation> +<translation id="7638452146404718955">Cliquer ici pour télécharger le plug-in</translation> <translation id="6119846243427417423">activer</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> fichiers</translation> -<translation id="3926627843712816530">Veuillez confirmer que vous souhaitez installer ce plug-in. Vous devez uniquement installer des plug-ins approuvés.</translation> -<translation id="4838490908464673667">Le plug-in requis n'est pas installé.</translation> +<translation id="4470547978413275879">Le plug-in <ph name="PLUGIN"/> n'est pas installé.</translation> +<translation id="6765711848403622008">Aucun plug-in disponible pour afficher ce contenu</translation> <translation id="8597182159515967513">en-tête</translation> <translation id="2653659639078652383">Valider</translation> +<translation id="8475551193147984329">Le plug-in <ph name="PLUGIN"/> est requis.</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_gu.xtb b/webkit/glue/resources/webkit_strings_gu.xtb index fb40c72..e7160bb 100644 --- a/webkit/glue/resources/webkit_strings_gu.xtb +++ b/webkit/glue/resources/webkit_strings_gu.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="gu"> -<translation id="4420062214988137980">પ્લગઇન ઇન્સ્ટોલેશન નિષ્ફળ થયું છે</translation> +<translation id="4519964825805946997"><ph name="URL"/> થી પ્લગ-ઇન ઇન્સ્ટોલ કરવામાં નિષ્ફળ રહ્યાં</translation> <translation id="1235745349614807883">હાલની શોધને સાફ કરો</translation> -<translation id="3825324228893189080">વધારાના પ્લગઇનની જરૂરિયાત</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> પ્લગઇન ઇન્સ્ટોલ કરેલું નથી</translation> <translation id="5048533449481078685">સૂચિ માર્કર</translation> +<translation id="372362261556059955">વધારાનું પ્લગ-ઇન આવશ્યક છે </translation> <translation id="4202807286478387388">જંપ કરો</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">કૃપા કરીને પુષ્ટિ કરો કે તમને <ph name="PLUGIN"/> પ્લગઇન ઇન્સ્ટોલ કરવું ગમશે. તમારે ફક્ત તે જ પ્લગઇન્સ ઇન્સ્ટોલ કરવા જોઈએ જેના પર તમે વિશ્વાસ કરો છો.</translation> <translation id="7658239707568436148">રદ કરો</translation> <translation id="795667975304826397">કોઈ ફાઇલ પસંદ કરેલી નથી</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> પ્લગઇનની જરૂરિયાત છે</translation> -<translation id="8662565117025751661">પ્લગઇન ડાઉનલોડ કરી રહ્યું છે...</translation> +<translation id="1416462845279468967">પ્લગ-ઇન ઇન્સ્ટોલેશન નિષ્ફળ ગયું</translation> <translation id="8141602879876242471">આ એક શોધસક્ષમ અનુક્રમણિકા છે. શોધ કીવર્ડ્સ દાખલ કરો:</translation> +<translation id="5650795167354946011">પ્લગ-ઇન ઇન્સ્ટોલ કર્યા પછી, રીફ્રેશ કરવા અહીં ક્લિક કરો</translation> <translation id="6845533974506654842">દબાવો</translation> <translation id="8244226242650769279">છબી નકશો</translation> -<translation id="1383141426028388991"><ph name="URL"/> માંથી પ્લગઇન ઇન્સ્ટોલ કરવામાં નિષ્ફળ</translation> <translation id="2548326553472216322">હાલની શોધો નથી</translation> <translation id="5944544982112848342">2048 (ઉચ્ચ ગ્રેડ)</translation> <translation id="3040011195152428237">લિંક</translation> -<translation id="8281246460978372009">પ્લગઇન ઇન્સ્ટોલ કર્યા પછી, રીફ્રેશ કરવા અહીં ક્લિક કરો</translation> +<translation id="2745343197843472802">પ્લગ-ઇન મેળવો</translation> +<translation id="5776402066334188252">કૃપા કરીને પુષ્ટી કરો કે તમે આ પ્લગ-ઇન ઇન્સ્ટોલ કરવાનું પસંદ કરશો. તમારે ફક્ત તે જ પ્લગ-ઇન્સ ઇન્સ્ટોલ કરવા જોઈએ જે વિશ્વસ્ત હોય.</translation> +<translation id="4003986561708175844">જોઈતું પ્લગ-ઇન ઇન્સ્ટોલ કરેલું નથી</translation> +<translation id="3018094406922859308">પ્લગ-ઇન ડાઉનલોડ કરી રહ્યું છે...</translation> <translation id="7364796246159120393">ફાઇલ પસંદ કરો</translation> <translation id="8964020114565522021">ફાઇલને અહીં ખેંચો</translation> <translation id="838869780401515933">તપાસો</translation> <translation id="2846343701378493991">1024 (મધ્યમ ગ્રેડ)</translation> <translation id="5476505524087279545">અનચેક કરો</translation> -<translation id="679352192834563463">આ સમાગ્રી પ્રદર્શિત કરવા માટે કોઈ પ્લગઇન ઉપલબ્ધ નથી</translation> <translation id="3789841737615482174">ઇન્સ્ટોલ કરો</translation> +<translation id="5253117816378681419">કૃપા કરીને પુષ્ટી કરો કે તમે <ph name="PLUGIN"/> પ્લગ-ઇન ઇન્સ્ટોલ કરવાનું પસંદ કરશો. તમારે ફક્ત તે જ પ્લગ-ઇન્સ ઇન્સ્ટોલ કરવા જોઈએ જે વિશ્વસ્ત હોય.</translation> <translation id="6663448176199120256">તાજેતરની શોધ</translation> -<translation id="3600343118165084788">પ્લગઇન ડાઉનલોડ કરવા માટે અહીં ક્લિક કરો</translation> +<translation id="2597378329261239068">આ દસ્તાવેજ પાસવર્ડ સુરક્ષિત છે. કૃપા કરીને પાસવર્ડ દાખલ કરો.</translation> <translation id="6807599807928161586">વેબ ક્ષેત્ર</translation> <translation id="5939518447894949180">રીસેટ કરો</translation> -<translation id="3771786644471114952">પ્લગઇન મેળવો</translation> <translation id="1842960171412779397">પસંદ કરો</translation> +<translation id="7638452146404718955">પ્લગ-ઇન ડાઉનલોડ કરવા માટે અહીં ક્લિક કરો</translation> <translation id="6119846243427417423">સક્રિય કરો</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ફાઇલો</translation> -<translation id="3926627843712816530">કૃપા કરીને પુષ્ટિ કરો કે તમને આ પ્લગઇન ઇન્સ્ટોલ કરવું ગમશે. તમારે ફક્ત તે જ પ્લગઇન્સ ઇન્સ્ટોલ કરવા જોઈએ જેના પર તમે વિશ્વાસ કરો છો.</translation> -<translation id="4838490908464673667">જોઈતું પ્લગઇન ઇન્સ્ટોલ કરેલું નથી</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> પ્લગ-ઇન ઇન્સ્ટોલ કરેલું નથી</translation> +<translation id="6765711848403622008">આ સામગ્રી પ્રદર્શિત કરવા માટે કોઈ પ્લગઇન ઉપલબ્ધ નથી</translation> <translation id="8597182159515967513">મથાળું</translation> <translation id="2653659639078652383">સબમિટ કરો</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> પ્લગ-ઇન આવશ્યક છે </translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_hi.xtb b/webkit/glue/resources/webkit_strings_hi.xtb index 8522437..e9bf9e7 100644 --- a/webkit/glue/resources/webkit_strings_hi.xtb +++ b/webkit/glue/resources/webkit_strings_hi.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="hi"> -<translation id="4420062214988137980">प्लगइन स्थापना असफ़ल रही</translation> +<translation id="4519964825805946997"><ph name="URL"/> से प्लग-इन स्थापित करने में विफल हुआ</translation> <translation id="1235745349614807883">हाल ही की खोजें साफ़ करें</translation> -<translation id="3825324228893189080">अतिरिक्त प्लगइन आवश्यक</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> प्लगइन स्थापित नहीं किया गया है</translation> <translation id="5048533449481078685">सूची चिन्हक</translation> +<translation id="372362261556059955">अतिरिक्त प्लग-इन की आवश्यकता है</translation> <translation id="4202807286478387388">जाएँ</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">कृपया पुष्टि करें कि आप <ph name="PLUGIN"/> प्लगइन स्थापित करना चाहते हैं. आपके केवल वे प्लगइन स्थापित करने चाहिए जिनपर आप भरोसा करते हों.</translation> <translation id="7658239707568436148">रद्द करें</translation> <translation id="795667975304826397">कोई फाइल नहीं चुनी गई</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> प्लगइन आवश्यक</translation> -<translation id="8662565117025751661">प्लगइन डाउनलोड कर रहा है ...</translation> +<translation id="1416462845279468967">प्लग-इन स्थापना विफल हुई</translation> <translation id="8141602879876242471">यह एक खोजने योग्य इंडेक्स है. खोज कुंजीशब्द प्रविष्ट करें :</translation> +<translation id="5650795167354946011">प्लग-इन स्थापित करने के बाद, रीफ़्रेश करने के लिए यहां क्लिक करें</translation> <translation id="6845533974506654842">दबाएँ</translation> <translation id="8244226242650769279">चित्र मैप</translation> -<translation id="1383141426028388991"><ph name="URL"/> से प्लगइन इंस्टाल करने में असफ़ल रहा</translation> <translation id="2548326553472216322">हाल ही में कोई खोज नहीं</translation> <translation id="5944544982112848342">2048 (उच्च ग्रेड)</translation> <translation id="3040011195152428237">लिंक</translation> -<translation id="8281246460978372009">प्लगइन स्थापित करने के बाद, पुन: ताज़ा करने के लिए यहाँ क्लिक करें</translation> +<translation id="2745343197843472802">प्लग-इन प्राप्त करें</translation> +<translation id="5776402066334188252">कृपया पुष्टि करें कि आप यह प्लग-इन स्थापित करना चाहेंगे. आपको केवल वे प्लग-इन स्थापित करने चाहिए जिन पर आप विश्वास करते हैं.</translation> +<translation id="4003986561708175844">आवश्यक प्लग-इन स्थापित नहीं है</translation> +<translation id="3018094406922859308">प्लग-इन डाउनलोड किया जा रहा है...</translation> <translation id="7364796246159120393">फ़ाइल चुनें</translation> <translation id="8964020114565522021">फाइल खींचकर यहाँ लाएं</translation> <translation id="838869780401515933">चेक करें</translation> <translation id="2846343701378493991">1024 (मध्यम ग्रेड)</translation> <translation id="5476505524087279545">अनचेक करें</translation> -<translation id="679352192834563463">इस सामग्री को प्रदर्शित करने के लिए कोई प्लगइन उपलब्ध नहीं है</translation> <translation id="3789841737615482174">स्थापित करें</translation> +<translation id="5253117816378681419">कृपया पुष्टि करें कि आप <ph name="PLUGIN"/> प्लग-इन स्थापित करना चाहेंगे. आपको केवल वे प्लग-इन स्थापित करने चाहिए जिन पर आप विश्वास करते हैं.</translation> <translation id="6663448176199120256">हाल ही में की गई खोजें</translation> -<translation id="3600343118165084788">प्लगइन डाउनलोड करने के लिए यहाँ क्लिक करें</translation> +<translation id="2597378329261239068">यह दस्तावेज़ पासवर्ड सुरक्षित है. कृपया एक पासवर्ड दर्ज करें.</translation> <translation id="6807599807928161586">वेब क्षेत्र</translation> <translation id="5939518447894949180">पुन: सेट करें</translation> -<translation id="3771786644471114952">प्लगइन प्राप्त करें</translation> <translation id="1842960171412779397">चुनें</translation> +<translation id="7638452146404718955">प्लग-इन डाउनलोड करने के लिए यहां क्लिक करें</translation> <translation id="6119846243427417423">सक्रिय करें</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> फ़ाइलें</translation> -<translation id="3926627843712816530">कृपया पुष्टि करें कि आप यह प्लगइन स्थापित करना चाहते हैं. आपके केवल वे प्लगइन स्थापित करने चाहिए जिनपर आप भरोसा करते हों.</translation> -<translation id="4838490908464673667">आवश्यक प्लगइन स्थापित नहीं है</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> प्लग-इन स्थापित नहीं है</translation> +<translation id="6765711848403622008">इस सामग्री को प्रदर्शित करने के लिए कोई प्लग-इन उपलब्ध नहीं है</translation> <translation id="8597182159515967513">हेडिंग</translation> <translation id="2653659639078652383">जमा करें</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> प्लग-इन की आवश्यकता है</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_hr.xtb b/webkit/glue/resources/webkit_strings_hr.xtb index bc93649..89458bb 100644 --- a/webkit/glue/resources/webkit_strings_hr.xtb +++ b/webkit/glue/resources/webkit_strings_hr.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="hr"> -<translation id="4420062214988137980">Nije uspjela instalacija dodatka</translation> +<translation id="4519964825805946997">Nije uspjela instalacija dodatka s adrese <ph name="URL"/></translation> <translation id="1235745349614807883">Obriši najnovija pretraživanja</translation> -<translation id="3825324228893189080">Potreban je dodatak</translation> -<translation id="2965480764085142436">Nije instaliran dodatak za <ph name="PLUGIN"/></translation> <translation id="5048533449481078685">oznaka popisa</translation> +<translation id="372362261556059955">Potreban je dodatni dodatak</translation> <translation id="4202807286478387388">skoči</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Potvrdite da želite instalirati dodatak za <ph name="PLUGIN"/> Instalirajte samo one dodatke kojima vjerujete.</translation> <translation id="7658239707568436148">Odustani</translation> <translation id="795667975304826397">Nije odabrana niti jedna datoteka.</translation> -<translation id="1275511093094545429">Potreban je dodatak za <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Preuzimanje dodatka...</translation> +<translation id="1416462845279468967">Nije uspjela instalacija dodatka</translation> <translation id="8141602879876242471">Ovaj je indeks moguće pretraživati. Unesite ključne riječi za pretraživanje:</translation> +<translation id="5650795167354946011">Nakon instalacije dodatka kliknite ovdje za osvježenje stranice</translation> <translation id="6845533974506654842">pritisni</translation> <translation id="8244226242650769279">karta slika</translation> -<translation id="1383141426028388991">Nije uspjela instalacija dodatka s <ph name="URL"/></translation> <translation id="2548326553472216322">Nema najnovijih pretraživanja</translation> <translation id="5944544982112848342">2048 (visoki stupanj)</translation> <translation id="3040011195152428237">veza</translation> -<translation id="8281246460978372009">Nakon instalacije dodatka, kliknite ovdje za osvježenje stranice</translation> +<translation id="2745343197843472802">Nabavi dodatak</translation> +<translation id="5776402066334188252">Potvrdite da želite instalirati dodatak. Instalirajte samo dodatke koje smatrate pouzdanima.</translation> +<translation id="4003986561708175844">Potreban dodatak nije instaliran</translation> +<translation id="3018094406922859308">Preuzimanje dodatka...</translation> <translation id="7364796246159120393">Odaberi datoteku</translation> <translation id="8964020114565522021">Povucite datoteku ovamo</translation> <translation id="838869780401515933">označi</translation> <translation id="2846343701378493991">1024 (srednji)</translation> <translation id="5476505524087279545">ukloni oznaku</translation> -<translation id="679352192834563463">Nema dostupnog dodatka za prikaz ovog sadržaja</translation> <translation id="3789841737615482174">Instaliraj</translation> +<translation id="5253117816378681419">Potvrdite da želite instalirati dodatak <ph name="PLUGIN"/>. Instalirajte samo dodatke koje smatrate pouzdanima.</translation> <translation id="6663448176199120256">Najnovija pretraživanja</translation> -<translation id="3600343118165084788">Kliknite ovdje za preuzimanje dodatka</translation> +<translation id="2597378329261239068">Ovaj je dokument zaštićen zaporkom. Unesite zaporku.</translation> <translation id="6807599807928161586">web područje</translation> <translation id="5939518447894949180">Ponovno postavi</translation> -<translation id="3771786644471114952">Dohvati dodatak</translation> <translation id="1842960171412779397">odaberi</translation> +<translation id="7638452146404718955">Kliknite ovdje za preuzimanje dodatka</translation> <translation id="6119846243427417423">aktiviraj</translation> <translation id="8444882422881193423">Broj datoteka: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Potvrdite da želite instalirati ovaj dodatak. Instalirajte samo one dodatke kojima vjerujete.</translation> -<translation id="4838490908464673667">Potreban dodatak nije instaliran</translation> +<translation id="4470547978413275879">Nije instaliran dodatak za <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">Nema dostupnog dodatka za prikaz ovog sadržaja</translation> <translation id="8597182159515967513">naslov</translation> <translation id="2653659639078652383">Pošalji</translation> +<translation id="8475551193147984329">Potreban je dodatak <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_hu.xtb b/webkit/glue/resources/webkit_strings_hu.xtb index 7a04612..848f2df 100644 --- a/webkit/glue/resources/webkit_strings_hu.xtb +++ b/webkit/glue/resources/webkit_strings_hu.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="hu"> -<translation id="4420062214988137980">A plugin telepítése nem sikerült</translation> +<translation id="4519964825805946997">A plug-in telepítése nem sikerült a következő helyről: <ph name="URL"/></translation> <translation id="1235745349614807883">Friss keresések törlése</translation> -<translation id="3825324228893189080">További plugin szükséges</translation> -<translation id="2965480764085142436">A(z) <ph name="PLUGIN"/> plugin nem lett telepítve</translation> <translation id="5048533449481078685">listajelölő</translation> +<translation id="372362261556059955">További plug-in szükséges</translation> <translation id="4202807286478387388">Mehet</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Kérjük, erősítse meg, hogy telepíteni szeretné a(z) <ph name="PLUGIN"/> plugint. Csak azokat a plugineket telepítse, amelyekben megbízik.</translation> <translation id="7658239707568436148">Mégse</translation> <translation id="795667975304826397">Nem lett fájl kiválasztva</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> plugin szükséges</translation> -<translation id="8662565117025751661">Plugin letöltése...</translation> +<translation id="1416462845279468967">A plug-in telepítése sikertelen</translation> <translation id="8141602879876242471">Ez egy kereshető index. Írjon be keresési kulcsszavakat:</translation> +<translation id="5650795167354946011">A plug-in telepítését követően kattintson ide a frissítéshez</translation> <translation id="6845533974506654842">Gomb lenyomása</translation> <translation id="8244226242650769279">képtérkép</translation> -<translation id="1383141426028388991">A plugin telepítése nem sikerült a következő helyről: <ph name="URL"/></translation> <translation id="2548326553472216322">Nincsenek friss keresések</translation> <translation id="5944544982112848342">2048 (magasfokú)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">A plugin telepítését követően ide kattintson a frissítéshez</translation> +<translation id="2745343197843472802">Plug-in beszerzése</translation> +<translation id="5776402066334188252">Kérjük, igazolja, hogy ezt a plug-int szeretné telepíteni. Csak azokat a plug-ineket telepítse, amelyekben megbízik.</translation> +<translation id="4003986561708175844">A szükséges plug-in nem lett telepítve</translation> +<translation id="3018094406922859308">Plug-in letöltése...</translation> <translation id="7364796246159120393">Fájl kiválasztása</translation> <translation id="8964020114565522021">Húzza át ide a fájlt</translation> <translation id="838869780401515933">Megjelölés</translation> <translation id="2846343701378493991">1024 (Közepes)</translation> <translation id="5476505524087279545">Megjelölés eltávolítása</translation> -<translation id="679352192834563463">Nincs elérhető plugin a tartalom megjelenítéséhez</translation> <translation id="3789841737615482174">Telepítés</translation> +<translation id="5253117816378681419">Kérjük, erősítse meg, hogy valóban telepíteni szeretné a következő plug-int: <ph name="PLUGIN"/>. Csak azokat a plug-ineket telepítse, amelyekben megbízik.</translation> <translation id="6663448176199120256">Friss keresések</translation> -<translation id="3600343118165084788">Ha ide kattint, letöltheti a plugint</translation> +<translation id="2597378329261239068">Ez a dokumentum jelszóval védett. Kérjük, adja meg a jelszót.</translation> <translation id="6807599807928161586">internetes terület</translation> <translation id="5939518447894949180">Visszaállítás</translation> -<translation id="3771786644471114952">Plugin beszerzése</translation> <translation id="1842960171412779397">Kiválasztás</translation> +<translation id="7638452146404718955">Ide kattintva letöltheti a plug-int</translation> <translation id="6119846243427417423">Aktiválás</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> fájl</translation> -<translation id="3926627843712816530">Kérjük, erősítse meg, hogy telepíteni szeretné ezt a plugint. Csak azokat a plugineket telepítse, amelyekben megbízik.</translation> -<translation id="4838490908464673667">A szükséges plugin nem lett telepítve</translation> +<translation id="4470547978413275879">A következő plug-in nincs telepítve: <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">Nincs elérhető plug-in a tartalom megjelenítéséhez</translation> <translation id="8597182159515967513">fejléc</translation> <translation id="2653659639078652383">Elküldés</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> plug-in szükséges</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_id.xtb b/webkit/glue/resources/webkit_strings_id.xtb index d174e84..6451c08 100644 --- a/webkit/glue/resources/webkit_strings_id.xtb +++ b/webkit/glue/resources/webkit_strings_id.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="id"> -<translation id="4420062214988137980">Penginstalan plug-in gagal</translation> +<translation id="4519964825805946997">Gagal memasang pengaya dari <ph name="URL"/></translation> <translation id="1235745349614807883">Hapus Penelusuran Barusan</translation> -<translation id="3825324228893189080">Diperlukan plug-in tambahan</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> plug-in belum terinstal</translation> <translation id="5048533449481078685">penanda daftar</translation> +<translation id="372362261556059955">Diperlukan pengaya tambahan</translation> <translation id="4202807286478387388">lompati</translation> <translation id="4611115858363067980"><ph name="FILENAME"/> - <ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Konfirmasikan bahwa Anda ingin menginstal plug-in<ph name="PLUGIN"/>. Sebaiknya hanya instal plug-in yang Anda percaya.</translation> <translation id="7658239707568436148">Batal</translation> <translation id="795667975304826397">Tidak ada file yang dipilih</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> diperlukan plug-in</translation> -<translation id="8662565117025751661">Mengunduh plug-in...</translation> +<translation id="1416462845279468967">Pemasangan pengaya gagal</translation> <translation id="8141602879876242471">Terdapat indeks yang dapat dicari. Masukkan kata kunci penelusuran:</translation> +<translation id="5650795167354946011">Setelah memasang pengaya, klik di sini untuk menyegarkan</translation> <translation id="6845533974506654842">tekan</translation> <translation id="8244226242650769279">gambar peta</translation> -<translation id="1383141426028388991">Gagal menginstal plug-in dari <ph name="URL"/></translation> <translation id="2548326553472216322">Tidak ada penelusuran terkini</translation> <translation id="5944544982112848342">2048 (Tingkat Tinggi)</translation> <translation id="3040011195152428237">tautan</translation> -<translation id="8281246460978372009">Setelah menginstal plug-in, klik di sini untuk me-refresh</translation> +<translation id="2745343197843472802">Dapatkan Pengaya</translation> +<translation id="5776402066334188252">Konfirmasikan bahwa Anda ingin memasang pengaya ini. Anda harus memasang pengaya yang dipercayai saja.</translation> +<translation id="4003986561708175844">Pengaya yang diperlukan belum terpasang</translation> +<translation id="3018094406922859308">Mengunduh pengaya...</translation> <translation id="7364796246159120393">Pilih Berkas</translation> <translation id="8964020114565522021">Tarik file ke sini</translation> <translation id="838869780401515933">centangi</translation> <translation id="2846343701378493991">1024 (Tingkat Menengah)</translation> <translation id="5476505524087279545">batalkan centang</translation> -<translation id="679352192834563463">Tidak tersedia plug-in untuk menampilkan konten ini</translation> <translation id="3789841737615482174">Instal</translation> +<translation id="5253117816378681419">Konfirmasikan bahwa Anda ingin memasang pengaya <ph name="PLUGIN"/>. Anda harus memasang pengaya yang Anda percayai saja.</translation> <translation id="6663448176199120256">Penelusuran Barusan</translation> -<translation id="3600343118165084788">Klik di sini untuk mengunduh plug-in</translation> +<translation id="2597378329261239068">Dokumen ini dilindungi sandi. Masukkan sandi.</translation> <translation id="6807599807928161586">area Web</translation> <translation id="5939518447894949180">Atur ulang</translation> -<translation id="3771786644471114952">Dapatkan Plug-in</translation> <translation id="1842960171412779397">pilih</translation> +<translation id="7638452146404718955">Klik di sini untuk mengunduh pengaya</translation> <translation id="6119846243427417423">aktifkan</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> berkas</translation> -<translation id="3926627843712816530">Konfirmasikan bahwa Anda ingin menginstal plug-in ini. Sebaiknya hanya instal plug-in yang Anda percaya.</translation> -<translation id="4838490908464673667">Plug-in yang diperlukan belum terinstal</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> pengaya belum terpasang</translation> +<translation id="6765711848403622008">Tidak tersedia pengaya untuk menampilkan konten ini</translation> <translation id="8597182159515967513">kepala</translation> <translation id="2653659639078652383">Kirim</translation> +<translation id="8475551193147984329">Pengaya <ph name="PLUGIN"/> diperlukan</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_it.xtb b/webkit/glue/resources/webkit_strings_it.xtb index f599db0..61c1e79 100644 --- a/webkit/glue/resources/webkit_strings_it.xtb +++ b/webkit/glue/resources/webkit_strings_it.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="it"> -<translation id="4420062214988137980">Installazione plug-in non riuscita</translation> +<translation id="4519964825805946997">Installazione del plug-in da <ph name="URL"/> non riuscita</translation> <translation id="1235745349614807883">Cancella ricerche recenti</translation> -<translation id="3825324228893189080">Plug-in aggiuntivo necessario</translation> -<translation id="2965480764085142436">Plug-in <ph name="PLUGIN"/> non installato</translation> <translation id="5048533449481078685">indicatore elenco</translation> +<translation id="372362261556059955">È necessario un plug-in aggiuntivo</translation> <translation id="4202807286478387388">vai</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Conferma l'installazione del plug-in <ph name="PLUGIN"/>. Ti invitiamo a installare solo i plug-in che ritieni affidabili.</translation> <translation id="7658239707568436148">Annulla</translation> <translation id="795667975304826397">Nessun file selezionato</translation> -<translation id="1275511093094545429">Plug-in <ph name="PLUGIN"/> necessario</translation> -<translation id="8662565117025751661">Download del plug-in in corso...</translation> +<translation id="1416462845279468967">Installazione del plug-in non riuscita</translation> <translation id="8141602879876242471">Questo è un indice di ricerca. Inserisci le parole chiave di ricerca:</translation> +<translation id="5650795167354946011">Dopo aver installato il plug-in, fai clic qui per aggiornare</translation> <translation id="6845533974506654842">premi</translation> <translation id="8244226242650769279">image map</translation> -<translation id="1383141426028388991">Installazione plug-in da <ph name="URL"/> non riuscita</translation> <translation id="2548326553472216322">Nessuna ricerca recente</translation> <translation id="5944544982112848342">2048 (alta qualità)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Dopo aver installato il plug-in, fai clic qui per aggiornare</translation> +<translation id="2745343197843472802">Scarica plug-in</translation> +<translation id="5776402066334188252">Conferma l'installazione del plug-in. Dovresti installare soltanto plug-in attendibili.</translation> +<translation id="4003986561708175844">Il plug-in richiesto non è installato</translation> +<translation id="3018094406922859308">Download del plug-in in corso...</translation> <translation id="7364796246159120393">Scegli file</translation> <translation id="8964020114565522021">Trascina il file qui</translation> <translation id="838869780401515933">seleziona</translation> <translation id="2846343701378493991">1024 (Medium Grade)</translation> <translation id="5476505524087279545">deseleziona</translation> -<translation id="679352192834563463">Nessun plug-in disponibile per visualizzare il contenuto</translation> <translation id="3789841737615482174">Installa</translation> +<translation id="5253117816378681419">Conferma che desideri installare il plug-in <ph name="PLUGIN"/>. Dovresti installare soltanto plug-in attendibili.</translation> <translation id="6663448176199120256">Ricerche recenti</translation> -<translation id="3600343118165084788">Fai clic qui per scaricare il plug-in</translation> +<translation id="2597378329261239068">Questo documento è protetto da password. Inserisci una password.</translation> <translation id="6807599807928161586">area web</translation> <translation id="5939518447894949180">Ripristina</translation> -<translation id="3771786644471114952">Aggiungi plug-in</translation> <translation id="1842960171412779397">seleziona</translation> +<translation id="7638452146404718955">Fai clic qui per scaricare il plug-in</translation> <translation id="6119846243427417423">attiva</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> file</translation> -<translation id="3926627843712816530">Conferma l'installazione del plug-in. Ti invitiamo a installare solo i plug-in che ritieni affidabili.</translation> -<translation id="4838490908464673667">Il plug-in richiesto non è installato</translation> +<translation id="4470547978413275879">Il plug-in <ph name="PLUGIN"/> non è installato</translation> +<translation id="6765711848403622008">Nessun plug-in disponibile per visualizzare questo contenuto</translation> <translation id="8597182159515967513">intestazione</translation> <translation id="2653659639078652383">Invia</translation> +<translation id="8475551193147984329">È necessario il plug-in <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_iw.xtb b/webkit/glue/resources/webkit_strings_iw.xtb index 652d600..436b298 100644 --- a/webkit/glue/resources/webkit_strings_iw.xtb +++ b/webkit/glue/resources/webkit_strings_iw.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="iw"> -<translation id="4420062214988137980">התקנת פלגא-אין נכשלה</translation> +<translation id="4519964825805946997">התקנת הפלאגין מתוך <ph name="URL"/> נכשלה</translation> <translation id="1235745349614807883">הסר חיפושים אחרונים</translation> -<translation id="3825324228893189080">דרוש תוסף נוסף</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> אינו מותקן</translation> <translation id="5048533449481078685">סמן רשימה</translation> +<translation id="372362261556059955">פלאגין נוסף נחוץ</translation> <translation id="4202807286478387388">קפוץ</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">אשר שברצונך להתקין את התוסף <ph name="PLUGIN"/>. עליך להתקין רק תוספים אתה בוטח.</translation> <translation id="7658239707568436148">ביטול</translation> <translation id="795667975304826397">לא נבחר קובץ</translation> -<translation id="1275511093094545429">נדרש plugin <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">מוריד תוסף...</translation> +<translation id="1416462845279468967">התקנת הפלאגין נכשלה</translation> <translation id="8141602879876242471">זהו אינדקס שניתן לבצע בו חיפוש. הזן מילות מפתח לחיפוש:</translation> +<translation id="5650795167354946011">לאחר התקנת הפלאגין, לחץ כאן לרענון</translation> <translation id="6845533974506654842">לחץ</translation> <translation id="8244226242650769279">מפת תמונות</translation> -<translation id="1383141426028388991">התקנת התוסף (plugin) מ-<ph name="URL"/> נכשלה</translation> <translation id="2548326553472216322">אין חיפושים אחרונים</translation> <translation id="5944544982112848342">2048 (High Grade)</translation> <translation id="3040011195152428237">קישור</translation> -<translation id="8281246460978372009">לאחר התקנת התוסף, לחץ כאן לרענון</translation> +<translation id="2745343197843472802">השג פלאגין</translation> +<translation id="5776402066334188252">אשר שברצונך להתקין פלאגין זה. יש להתקין רכיבי פלאגין שאתה בוטח בהם בלבד.</translation> +<translation id="4003986561708175844">הפלאגין הדרוש אינו מותקן</translation> +<translation id="3018094406922859308">מוריד פלאגין...</translation> <translation id="7364796246159120393">בחר קובץ</translation> <translation id="8964020114565522021">גרור את הקובץ לכאן</translation> <translation id="838869780401515933">סמן</translation> <translation id="2846343701378493991">1024 (Medium Grade)</translation> <translation id="5476505524087279545">בטל סימון</translation> -<translation id="679352192834563463">אין תוסף זמין להצגת תוכן זה</translation> <translation id="3789841737615482174">התקן</translation> +<translation id="5253117816378681419">אשר שברצונך להתקין את הפלאגין <ph name="PLUGIN"/>. יש להתקין רכיבי פלאגין שאתה בוטח בהם בלבד.</translation> <translation id="6663448176199120256">חיפושים אחרונים</translation> -<translation id="3600343118165084788">לחץ כאן להורדת התוסף</translation> +<translation id="2597378329261239068">מסמך זה מוגן באמצעות סיסמה. הזן סיסמה.</translation> <translation id="6807599807928161586">אזור אינטרנט</translation> <translation id="5939518447894949180">אפס</translation> -<translation id="3771786644471114952">קבל תוסף</translation> <translation id="1842960171412779397">בחר</translation> +<translation id="7638452146404718955">לחץ כאן להורדת פלאגין</translation> <translation id="6119846243427417423">הפעל</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> קבצים</translation> -<translation id="3926627843712816530">אנא אשר שברצונך להתקין תוסף זה. עליך להתקין רק תוספים שבהם אתה בוטח.</translation> -<translation id="4838490908464673667">התוסף המבוקש אינו מותקן</translation> +<translation id="4470547978413275879">הפלאגין <ph name="PLUGIN"/> אינו מותקן</translation> +<translation id="6765711848403622008">אין פלאגין זמין להצגת תוכן זה</translation> <translation id="8597182159515967513">כותרת</translation> <translation id="2653659639078652383">שלח</translation> +<translation id="8475551193147984329">הפלאגין <ph name="PLUGIN"/> דרוש</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ja.xtb b/webkit/glue/resources/webkit_strings_ja.xtb index c16df86..2eccba2 100644 --- a/webkit/glue/resources/webkit_strings_ja.xtb +++ b/webkit/glue/resources/webkit_strings_ja.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ja"> -<translation id="4420062214988137980">プラグインのインストールが失敗しました</translation> +<translation id="4519964825805946997"><ph name="URL"/> からプラグインをインストールできませんでした</translation> <translation id="1235745349614807883">最近の検索履歴を消去</translation> -<translation id="3825324228893189080">追加の必要なプラグイン</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> プラグインはインストールされていません</translation> <translation id="5048533449481078685">リスト マーカー</translation> +<translation id="372362261556059955">追加のプラグインが必要です</translation> <translation id="4202807286478387388">ジャンプ</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143"><ph name="PLUGIN"/> プラグインのインストールを確認してください。信頼できるプラグインだけインストールしてください。</translation> <translation id="7658239707568436148">キャンセル</translation> <translation id="795667975304826397">選択されていません</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> プラグインが必要です</translation> -<translation id="8662565117025751661">プラグインをダウンロードしています...</translation> +<translation id="1416462845279468967">プラグインをインストールできませんでした</translation> <translation id="8141602879876242471">このインデックスは検索できます。キーワードを入力してください:</translation> +<translation id="5650795167354946011">プラグインをインストールした後は、ここをクリックして更新を行ってください</translation> <translation id="6845533974506654842">押す</translation> <translation id="8244226242650769279">イメージ マップ</translation> -<translation id="1383141426028388991"><ph name="URL"/> からプラグインをインストールできませんでした</translation> <translation id="2548326553472216322">最近の検索はありません</translation> <translation id="5944544982112848342">2048 (高)</translation> <translation id="3040011195152428237">リンク</translation> -<translation id="8281246460978372009">プラグインをインストールした後は、ここをクリックして更新してください</translation> +<translation id="2745343197843472802">プラグインをダウンロード</translation> +<translation id="5776402066334188252">このプラグインをインストールしてもよいかご確認ください。信頼できるプラグインのみをインストールする必要があります。</translation> +<translation id="4003986561708175844">必要なプラグインがインストールされていません</translation> +<translation id="3018094406922859308">プラグインをダウンロードしています...</translation> <translation id="7364796246159120393">ファイルを選択</translation> <translation id="8964020114565522021">ファイルをここにドラッグ</translation> <translation id="838869780401515933">チェックを付ける</translation> <translation id="2846343701378493991">1024 (中)</translation> <translation id="5476505524087279545">チェックを外す</translation> -<translation id="679352192834563463">このコンテンツの表示に使用できるプラグインはありません</translation> <translation id="3789841737615482174">インストール</translation> +<translation id="5253117816378681419">この <ph name="PLUGIN"/> プラグインをインストールしてもよいかご確認ください。信頼できるプラグインのみをインストールする必要があります。</translation> <translation id="6663448176199120256">最近の検索</translation> -<translation id="3600343118165084788">ここをクリックしてプラグインをダウンロード</translation> +<translation id="2597378329261239068">このドキュメントはパスワードで保護されています。パスワードを入力してください。</translation> <translation id="6807599807928161586">ウェブ領域</translation> <translation id="5939518447894949180">リセット</translation> -<translation id="3771786644471114952">プラグインの取得</translation> <translation id="1842960171412779397">選択</translation> +<translation id="7638452146404718955">ここをクリックしてプラグインをダウンロード</translation> <translation id="6119846243427417423">アクティブにする</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ファイル</translation> -<translation id="3926627843712816530">このプラグインのインストールを確認してください。信頼できるプラグインだけインストールしてください。</translation> -<translation id="4838490908464673667">必要なプラグインがインストールされていません</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> プラグインがインストールされていません</translation> +<translation id="6765711848403622008">このコンテンツの表示に使用できるプラグインはありません</translation> <translation id="8597182159515967513">見出し</translation> <translation id="2653659639078652383">送信</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> プラグインが必要です</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_kn.xtb b/webkit/glue/resources/webkit_strings_kn.xtb index 1dacc42..61dbd2c 100644 --- a/webkit/glue/resources/webkit_strings_kn.xtb +++ b/webkit/glue/resources/webkit_strings_kn.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="kn"> -<translation id="4420062214988137980">ಪ್ಲಗ್ಇನ್ ಇನ್ಸ್ಟಾಲೇಶನ್ ವಿಫಲವಾಗಿದೆ</translation> +<translation id="4519964825805946997"><ph name="URL"/> ನಿಂದ ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಸ್ಥಾಪಿಸುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ</translation> <translation id="1235745349614807883">ಇತ್ತೀಚಿನ ಹುಡುಕಾಟವನ್ನು ತೆರವುಗೊಳಿಸಿ</translation> -<translation id="3825324228893189080">ಹೆಚ್ಚುವರಿ ಪ್ಲಗ್ಇನ್ಗಳ ಅವಶ್ಯಕತೆಯಿದೆ</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> ಪ್ಲಗ್ಇನ್ ಇನ್ಸ್ಟಾಲ್ ಆಗಿಲ್ಲ</translation> <translation id="5048533449481078685">ಪಟ್ಟಿ ಗುರುತು</translation> +<translation id="372362261556059955">ಹೆಚ್ಚುವರಿ ಪ್ಲಗ್-ಇನ್ ಅಗತ್ಯವಿದೆ</translation> <translation id="4202807286478387388">ಹಾರು</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">ದಯವಿಟ್ಟು <ph name="PLUGIN"/> ಪ್ಲಗ್ಇನ್ ಅನ್ನು ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ ಎಂದು ಖಚಿತಪಡಿಸಿ. ನೀವು ನಂಬಿರುವ ಪ್ಲಗ್ಇನ್ಸ್ ಅನ್ನು ಮಾತ್ರ ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಬೇಕು.</translation> <translation id="7658239707568436148">ರದ್ದುಮಾಡು</translation> <translation id="795667975304826397">ಯಾವುದೇ ಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿಲ್ಲ</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> ಪ್ಲಗ್ಇನ್ ಅವಶ್ಯಕತೆಯಿದೆ</translation> -<translation id="8662565117025751661">ಡೌನ್ಲೋಡ್ ಆಗುತ್ತಿರುವ ಪ್ಲಗ್ ಇನ್...</translation> +<translation id="1416462845279468967">ಪ್ಲಗ್-ಇನ್ ಅಳವಡಿಸುವಿಕೆಯು ವಿಫಲವಾಗಿದೆ</translation> <translation id="8141602879876242471">ಇದು ಹುಡುಕಾಡಬಹುದಾದ ಸೂಚಿಕೆ ಹುಡುಕಾಟ ಕೀವರ್ಡ್ಗಳನ್ನು ನಮೂದಿಸಿ:</translation> +<translation id="5650795167354946011">ಪ್ಲಗ್-ಇನ್ ಸ್ಥಾಪನೆ ಮಾಡಿದ ನಂತರ, ರಿಫ್ರೆಶ್ ಮಾಡಲು ಇಲ್ಲಿ ಕ್ಲಿಕ್ ಮಾಡಿ</translation> <translation id="6845533974506654842">ಒತ್ತಿ</translation> <translation id="8244226242650769279">ಇಮೇಜ್ ನಕ್ಷೆ</translation> -<translation id="1383141426028388991"><ph name="URL"/> ನಿಂದ ಪ್ಲಗ್ಇನ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ</translation> <translation id="2548326553472216322">ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು ಇಲ್ಲ</translation> <translation id="5944544982112848342">2048 (ಉನ್ನತ ಶ್ರೇಣಿ)</translation> <translation id="3040011195152428237">ಲಿಂಕ್</translation> -<translation id="8281246460978372009">ಪ್ಲಗ್ಇನ್ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ನಂತರ, ತಾಜಾಮಾಡಲು ಇಲ್ಲಿ ಕ್ಲಿಕ್ ಮಾಡಿ</translation> +<translation id="2745343197843472802">ಪ್ಲಗ್-ಇನ್ ಪಡೆಯಿರಿ</translation> +<translation id="5776402066334188252">ನೀವು ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲು ಬಯಸುವುದಾದಲ್ಲಿ ದಯವಿಟ್ಟು ಖಚಿತಪಡಿಸಿ. ನಿಮಗೆ ನಂಬಿಕೆ ಇರುವ ಫ್ಲಗ್-ಇನ್ಗಳನ್ನು ಮಾತ್ರ ನೀವು ಸ್ಥಾಪಿಸಬೇಕು.</translation> +<translation id="4003986561708175844">ಅಗತ್ಯವಿರುವ ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಅಳವಡಿಸಲಾಗಿಲ್ಲ</translation> +<translation id="3018094406922859308">ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation> <translation id="7364796246159120393">ಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿ</translation> <translation id="8964020114565522021">ಇಲ್ಲಿ ಫೈಲ್ ಅನ್ನು ಎಳೆಯಿರಿ</translation> <translation id="838869780401515933">ಪರಿಶೀಲಿಸು</translation> <translation id="2846343701378493991">1024 (ಮದ್ಯಮ ಶ್ರೇಣಿ)</translation> <translation id="5476505524087279545">ಪರೀಕ್ಷಿಸಬೇಡಿ</translation> -<translation id="679352192834563463">ಈ ವಿಷಯವನ್ನು ಪ್ರದರ್ಶಿಸಲು ಯಾವುದೇ ಪ್ಲಗ್ಇನ್ ಲಭ್ಯವಿಲ್ಲ</translation> <translation id="3789841737615482174">ಇನ್ಸ್ಟಾಲ್</translation> +<translation id="5253117816378681419">ನೀವು <ph name="PLUGIN"/> ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಅಳವಡಿಸಲು ಬಯಸುವುದಾದಲ್ಲಿ ದಯವಿಟ್ಟು ಖಚಿತಪಡಿಸಿ. ನೀವು ನಂಬುವಂತಹ ಫ್ಲಗ್-ಇನ್ಗಳನ್ನು ಮಾತ್ರ ನೀವು ಅಳವಡಿಸಬೇಕು.</translation> <translation id="6663448176199120256">ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು</translation> -<translation id="3600343118165084788">ಪ್ಲಗ್ಇನ್ ಅನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಇಲ್ಲಿ ಕ್ಲಿಕ್ ಮಾಡಿ</translation> +<translation id="2597378329261239068">ಈ ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ಪಾಸ್ವರ್ಡ್ನಿಂದ ರಕ್ಷಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ.</translation> <translation id="6807599807928161586">ವೆಬ್ ಪ್ರದೇಶ</translation> <translation id="5939518447894949180">ಮರುಹೊಂದಿಸು</translation> -<translation id="3771786644471114952">ಪ್ಲಗ್ಇನ್ ಪಡೆಯಿರಿ</translation> <translation id="1842960171412779397">ಆಯ್ಕೆ ಮಾಡಿ</translation> +<translation id="7638452146404718955">ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಇಲ್ಲಿ ಕ್ಲಿಕ್ ಮಾಡಿ</translation> <translation id="6119846243427417423">ಸಕ್ರಿಯಗೊಳಿಸು</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ಫೈಲ್ಗಳು</translation> -<translation id="3926627843712816530">ಈ ಪ್ಲಗ್ಇನ್ ಅನ್ನು ನೀವು ಇನ್ಸ್ಟಾಲ್ಮಾಡಲು ಬಯಸುತ್ತೀರಾ ಎಂದು ದಯವಿಟ್ಟು ಖಚಿತಪಡಿಸಿ. ನೀವು ನಂಬಿರುವ ಪ್ಲಗಿನ್ಸ್ ಅನ್ನು ಮಾತ್ರ ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಬೇಕು.</translation> -<translation id="4838490908464673667">ಅವಶ್ಯಕವಾಗಿರುವ ಪ್ಲಗ್ಇನ್ ಇನ್ಸ್ಟಾಲ್ ಆಗಿಲ್ಲ</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> ನ ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ</translation> +<translation id="6765711848403622008">ಈ ವಿಷಯವನ್ನು ಪ್ರದರ್ಶಿಸಲು ಯಾವುದೇ ಪ್ಲಗ್-ಇನ್ ಲಭ್ಯವಿಲ್ಲ</translation> <translation id="8597182159515967513">ಶೀರ್ಷಿಕೆ</translation> <translation id="2653659639078652383">ಸಲ್ಲಿಸು</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> ಪ್ಲಗ್-ಇನ್ ಅಗತ್ಯವಿದೆ</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ko.xtb b/webkit/glue/resources/webkit_strings_ko.xtb index c3b3e3e..819c8ce 100644 --- a/webkit/glue/resources/webkit_strings_ko.xtb +++ b/webkit/glue/resources/webkit_strings_ko.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ko"> -<translation id="4420062214988137980">플러그인 설치 실패</translation> +<translation id="4519964825805946997"><ph name="URL"/>의 플러그인 설치 실패</translation> <translation id="1235745349614807883">최근 검색 삭제</translation> -<translation id="3825324228893189080">추가 플러그인 필요</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> 플러그인이 설치되지 않음</translation> <translation id="5048533449481078685">목록 표시기</translation> +<translation id="372362261556059955">추가 플러그인 필요</translation> <translation id="4202807286478387388">건너뛰기</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143"><ph name="PLUGIN"/> 플러그인을 설치할 것인지 확인해 주세요. 신뢰하는 플러그인만 설치해야 합니다.</translation> <translation id="7658239707568436148">취소</translation> <translation id="795667975304826397">선택된 파일 없음</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> 플러그인 필요</translation> -<translation id="8662565117025751661">플러그인 다운로드 중...</translation> +<translation id="1416462845279468967">플러그인 설치 실패</translation> <translation id="8141602879876242471">이것은 검색 색인합니다. 검색 키워드 입력:</translation> +<translation id="5650795167354946011">플러그인 설치 후 여기를 클릭하여 새로고침</translation> <translation id="6845533974506654842">누르기</translation> <translation id="8244226242650769279">이미지 지도</translation> -<translation id="1383141426028388991"><ph name="URL"/>의 플러그인 설치 실패</translation> <translation id="2548326553472216322">최근 수행된 검색 없음</translation> <translation id="5944544982112848342">2048(높은 등급)</translation> <translation id="3040011195152428237">링크</translation> -<translation id="8281246460978372009">플러그인 설치 후 여기를 클릭하여 새로고침</translation> +<translation id="2745343197843472802">플러그인 가져오기</translation> +<translation id="5776402066334188252">플러그인을 설치할지 여부를 확인하시기 바랍니다. 신뢰할 수 있는 플러그인만 설치해야 합니다.</translation> +<translation id="4003986561708175844">필수 플러그인이 설치되지 않음</translation> +<translation id="3018094406922859308"> 플러그인 다운로드 중...</translation> <translation id="7364796246159120393">파일 선택</translation> <translation id="8964020114565522021">여기로 파일 드래그</translation> <translation id="838869780401515933">선택</translation> <translation id="2846343701378493991">1024(중간 등급)</translation> <translation id="5476505524087279545">선택취소</translation> -<translation id="679352192834563463">이 콘텐츠를 표시하는 데 사용할 플러그인 없음</translation> <translation id="3789841737615482174">설치</translation> +<translation id="5253117816378681419"><ph name="PLUGIN"/> 플러그인을 설치할지 여부를 확인하시기 바랍니다. 신뢰할 수 있는 플러그인만 설치해야 합니다.</translation> <translation id="6663448176199120256">최근 수행된 검색</translation> -<translation id="3600343118165084788">여기를 클릭하여 플러그인을 다운로드합니다.</translation> +<translation id="2597378329261239068">문서가 비밀번호로 보호되고 있습니다. 비밀번호를 입력하세요.</translation> <translation id="6807599807928161586">웹 영역</translation> <translation id="5939518447894949180">재설정</translation> -<translation id="3771786644471114952">플러그인 가져오기</translation> <translation id="1842960171412779397">선택</translation> +<translation id="7638452146404718955">여기를 클릭하여 플러그인 다운로드</translation> <translation id="6119846243427417423">활성화</translation> <translation id="8444882422881193423">파일 <ph name="NUMBER_OF_FILES"/>개</translation> -<translation id="3926627843712816530">해당 플러그인을 설치할 것인지 확인해 주세요. 신뢰하는 플러그인만 설치해야 합니다.</translation> -<translation id="4838490908464673667">필수 플러그인이 설치되지 않음</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> 플러그인이 설치되지 않음</translation> +<translation id="6765711848403622008">이 콘텐츠를 표시하는 데 사용할 플러그인 없음</translation> <translation id="8597182159515967513">항목</translation> <translation id="2653659639078652383">제출</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> 플러그인 필요</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_lt.xtb b/webkit/glue/resources/webkit_strings_lt.xtb index 9975381..8e8a7a7 100644 --- a/webkit/glue/resources/webkit_strings_lt.xtb +++ b/webkit/glue/resources/webkit_strings_lt.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="lt"> -<translation id="4420062214988137980">Papildinio įdiegti nepavyko</translation> +<translation id="4519964825805946997">Nepavyko įdiegti papildinio iš <ph name="URL"/></translation> <translation id="1235745349614807883">Išvalyti pastarąsias paieškas</translation> -<translation id="3825324228893189080">Reikia papidomo papildinio</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> papildinys neįdiegtas</translation> <translation id="5048533449481078685">sąrašo žymeklis</translation> +<translation id="372362261556059955">Reikia papildomo papildinio</translation> <translation id="4202807286478387388">peršokti</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Patvirtinkite, kad norite diegti <ph name="PLUGIN"/> papildinį. Diekite tik tuos papildinius, kuriais tikrai pasitikite.</translation> <translation id="7658239707568436148">Atšaukti</translation> <translation id="795667975304826397">Nepasirinktas joks failas</translation> -<translation id="1275511093094545429">Reikia <ph name="PLUGIN"/> papildinio (-ių)</translation> -<translation id="8662565117025751661">Siunčiamas papildinys...</translation> +<translation id="1416462845279468967">Papildinio diegimas nepavyko</translation> <translation id="8141602879876242471">Tai yra ieškotinas indeksas. Įveskite paieškos raktinių žodžių:</translation> +<translation id="5650795167354946011">Įdiegę papildinį spustelėkite čia, kad puslapis būtų atnaujintas</translation> <translation id="6845533974506654842">paspausti</translation> <translation id="8244226242650769279">paveikslėlio žemėlapis</translation> -<translation id="1383141426028388991">Nepavyko įdiegti papildinio iš <ph name="URL"/></translation> <translation id="2548326553472216322">Pastaruoju metu paieškų nevykdyta</translation> <translation id="5944544982112848342">2048 (Aukšto laipsnio)</translation> <translation id="3040011195152428237">nuoroda</translation> -<translation id="8281246460978372009">Įdiegę papildinį paspauskite čia, kad būtų perkrautas puslapis</translation> +<translation id="2745343197843472802">Gauti papildinį</translation> +<translation id="5776402066334188252">Patvirtinkite, kad norite įdiegti šį papildinį. Turėtumėte diegti tik tuos papildinius, kurie yra patikimi.</translation> +<translation id="4003986561708175844">Neįdiegtas reikalingas papildinys</translation> +<translation id="3018094406922859308">Atsisiunčiamas papildinys...</translation> <translation id="7364796246159120393">Pasirinkti failą</translation> <translation id="8964020114565522021">Vilkite failą čia</translation> <translation id="838869780401515933">tikrinti</translation> <translation id="2846343701378493991">1024 (vidutinio lygio)</translation> <translation id="5476505524087279545">Nuimti žymėjimą</translation> -<translation id="679352192834563463">Nėra papildinio, galinčio parodyti šį turinį</translation> <translation id="3789841737615482174">Diegti</translation> +<translation id="5253117816378681419">Patvirtinkite, kad norite įdiegti šį „<ph name="PLUGIN"/>“ papildinį. Turėtumėte diegti tik tuos papildinius, kurie patikimi.</translation> <translation id="6663448176199120256">Naujausios paieškos</translation> -<translation id="3600343118165084788">Spustelėkite čia, kad atsisiųstumėte papildinį</translation> +<translation id="2597378329261239068">Šis dokumentas apsaugotas slaptažodžiu. Įveskite slaptažodį.</translation> <translation id="6807599807928161586">interneto sritis</translation> <translation id="5939518447894949180">Nustatyti iš naujo</translation> -<translation id="3771786644471114952">Siųsti papildinį</translation> <translation id="1842960171412779397">pasirinkti</translation> +<translation id="7638452146404718955">Spustelėkite čia, kad atsisiųstumėte papildinį</translation> <translation id="6119846243427417423">aktyvinti</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> failai (-ų)</translation> -<translation id="3926627843712816530">Patvirtinkite, kad norite diegti šį papildinį. Diekite tik tuos papildinius, kuriais tikrai pasitikite.</translation> -<translation id="4838490908464673667">Neįdiegtas reikalingas papildinys</translation> +<translation id="4470547978413275879">„<ph name="PLUGIN"/>“ papildinys neįdiegtas</translation> +<translation id="6765711848403622008">Nėra papildinio, kad būtų galima pateikti šį turinį</translation> <translation id="8597182159515967513">antraštė</translation> <translation id="2653659639078652383">Pateikti</translation> +<translation id="8475551193147984329">Reikia „<ph name="PLUGIN"/>“ papildinio</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_lv.xtb b/webkit/glue/resources/webkit_strings_lv.xtb index 6b7dfd5..c97eb32 100644 --- a/webkit/glue/resources/webkit_strings_lv.xtb +++ b/webkit/glue/resources/webkit_strings_lv.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="lv"> -<translation id="4420062214988137980">Spraudņa iestatīšana neizdevās</translation> +<translation id="4519964825805946997">Neizdevās instalēt spraudni no <ph name="URL"/></translation> <translation id="1235745349614807883">Dzēst nesenos meklējumus</translation> -<translation id="3825324228893189080">Nepieciešams papildus spraudnis</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> spraudnis nav iestatīts</translation> <translation id="5048533449481078685">sarakstu marķieris</translation> +<translation id="372362261556059955">Nepieciešams papildu spraudnis</translation> <translation id="4202807286478387388">lekt</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Lūdzu, apstipriniet, ka vēlaties iestatīt <ph name="PLUGIN"/> spraudni. Jums vajadzētu iestatīt tikai tos spraudņus, kuriem uzticaties.</translation> <translation id="7658239707568436148">Atcelt</translation> <translation id="795667975304826397">Nav izvēlēts neviens fails</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> nepieciešams spraudnis</translation> -<translation id="8662565117025751661">Spraudņu lejupielāde...</translation> +<translation id="1416462845279468967">Spraudņa instalēšana neizdevās</translation> <translation id="8141602879876242471">Šis ir indekss ar meklēšanas iespējām. Ievadīt meklēšanas atslēgvārdus:</translation> +<translation id="5650795167354946011">Pēc spraudņa instalēšanas noklikšķiniet šeit, lai atsvaidzinātu</translation> <translation id="6845533974506654842">nospiest</translation> <translation id="8244226242650769279">attēlu karte</translation> -<translation id="1383141426028388991">Neizdevās instalēt spraudni no <ph name="URL"/></translation> <translation id="2548326553472216322">Nav nesenu meklējumu</translation> <translation id="5944544982112848342">2048 (Augsta Atzīme)</translation> <translation id="3040011195152428237">saite</translation> -<translation id="8281246460978372009">Pēc spraudņa iestatīšanas, nospiediet šeit, lai atsvaidzinātu</translation> +<translation id="2745343197843472802">Lejupielādēt spraudni</translation> +<translation id="5776402066334188252">Lūdzu, apstipriniet, ka vēlaties instalēt šo spraudni. Ieteicams instalēt tikai tos spraudņus, kuriem uzticaties.</translation> +<translation id="4003986561708175844">Nepieciešamais spraudnis nav instalēts</translation> +<translation id="3018094406922859308">Notiek spraudņa lejupielāde...</translation> <translation id="7364796246159120393">Izvēlieties failu</translation> <translation id="8964020114565522021">Ievelciet failu šeit</translation> <translation id="838869780401515933">prbaudt</translation> <translation id="2846343701378493991">1024 (Vidēja Atzīme)</translation> <translation id="5476505524087279545">neprbaudt</translation> -<translation id="679352192834563463">Nav pieejamu spraudņu, lai attēlotu saturu</translation> <translation id="3789841737615482174">Iestatīt</translation> +<translation id="5253117816378681419">Lūdzu, apstipriniet, ka vēlaties instalēt <ph name="PLUGIN"/> spraudni. Jums ir jāinstalē tikai tie spraudņi, kuriem uzticaties.</translation> <translation id="6663448176199120256">Neseni meklējumi</translation> -<translation id="3600343118165084788">Klikšķiniet šeit, lai lejupielādētu spraudni</translation> +<translation id="2597378329261239068">Šis dokuments ir aizsargāts ar paroli. Lūdzu, ievadiet paroli.</translation> <translation id="6807599807928161586">tīmekļa apgabals</translation> <translation id="5939518447894949180">Atiestatīt</translation> -<translation id="3771786644471114952">Iegūt spraudni</translation> <translation id="1842960171412779397">Atlasiet</translation> +<translation id="7638452146404718955">Noklikšķiniet šeit, lai lejupielādētu spraudni</translation> <translation id="6119846243427417423">aktivizt</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> faili</translation> -<translation id="3926627843712816530">Lūdzu, apstipriniet, ka vēlaties iestatīt šo spraudni. Jums vajadzētu iestatīt tikai tos spraudņus, kuriem uzticaties.</translation> -<translation id="4838490908464673667">Nepieciešamais spraudnis nav iestatīts</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> spraudnis nav instalēts</translation> +<translation id="6765711848403622008">Nav pieejams neviens spraudnis, kas var attēlot šo saturu</translation> <translation id="8597182159515967513">Virsraksts</translation> <translation id="2653659639078652383">Iesniegt</translation> +<translation id="8475551193147984329">Nepieciešams <ph name="PLUGIN"/> spraudnis</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ml.xtb b/webkit/glue/resources/webkit_strings_ml.xtb index d7db730..437330d 100644 --- a/webkit/glue/resources/webkit_strings_ml.xtb +++ b/webkit/glue/resources/webkit_strings_ml.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ml"> -<translation id="4420062214988137980">പ്ലഗിന് ഇന്സ്റ്റൊളേഷന് പരാജയപ്പെട്ടു</translation> +<translation id="4519964825805946997"><ph name="URL"/> എന്നതില് നിന്നുള്ള പ്ലഗ്-ഇന് ഇന്സ്റ്റാളുചെയ്യുന്നതിന് പരാജയപ്പെട്ടു</translation> <translation id="1235745349614807883">അടുത്തിടെയുള്ള തിരയലുകള് മായ്ക്കുക</translation> -<translation id="3825324228893189080">കൂടുതല് പ്ലഗിന് ആവശ്യമാണ്</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> പ്ലഗിന് ഇന്സ്റ്റോള് ചെയ്തില്ല</translation> <translation id="5048533449481078685">പട്ടിക മാര്ക്കര്</translation> +<translation id="372362261556059955">കൂടുതല് പ്ലഗ്-ഇന് ആവശ്യമുണ്ട്</translation> <translation id="4202807286478387388">jump</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143"><ph name="PLUGIN"/> പ്ലഗിന് ഇന്സ്റ്റാള് ചെയ്യാന് നിങ്ങള് താല്പര്യപ്പെടുന്നുവെന്ന് ദയവായി ഉറപ്പുവരുത്തുക. നിങ്ങള്ക്ക് വിശ്വാസ്യതയുള്ള പ്ലഗിനുകള് മാത്രം നിങ്ങള് ഇന്സ്റ്റാള് ചെയ്യുക.</translation> <translation id="7658239707568436148">റദ്ദാക്കുക</translation> <translation id="795667975304826397">ഒരു ഫയലും തിരഞ്ഞെടുത്തിട്ടില്ല</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> പ്ലഗിന് ആവശ്യമുണ്ട്</translation> -<translation id="8662565117025751661">പ്ലഗ് ഇന് ഡൌണ്ലോഡ് ചെയ്യുകയാണ്...</translation> +<translation id="1416462845279468967">പ്ലഗ്-ഇന് ഇന്സ്റ്റാളേഷന് പരാജയപ്പെട്ടു</translation> <translation id="8141602879876242471">ഇത് തിരയാവുന്ന സൂചികയാണ്. തിരയല് കീവേഡുകള് നല്കുക:</translation> +<translation id="5650795167354946011">പ്ലഗ്-ഇന് ഇന്സ്റ്റാളുചെയ്തതിനുശേഷം, പുതുക്കുന്നതിന് ഇവിടെ ക്ലിക്കുചെയ്യുക</translation> <translation id="6845533974506654842">അമര്ത്തുക</translation> <translation id="8244226242650769279">ഇമേജ് മാപ്പ്</translation> -<translation id="1383141426028388991"><ph name="URL"/> ല് നിന്ന് പ്ലഗ്-ഇന് ഇന്സ്റ്റോള് ചെയ്യുന്നതില് പരാജയപ്പെട്ടു</translation> <translation id="2548326553472216322">സമീപകാല തിരയലുകള് ഇല്ല</translation> <translation id="5944544982112848342">2048 (High Grade)</translation> <translation id="3040011195152428237">ലിങ്ക്</translation> -<translation id="8281246460978372009">പ്ലഗിന് ഇന്സ്റ്റാള് ചെയ്തതിന് ശേഷം, പുതുക്കുന്നതിനായി ഇവിടെ ക്ലിക്കുചെയ്യുക</translation> +<translation id="2745343197843472802">പ്ലഗ്-ഇന് നേടുക</translation> +<translation id="5776402066334188252">നിങ്ങള് ഈ പ്ലഗ്-ഇന് ഇന്സ്റ്റാളുചെയ്യാന് താല്പ്പര്യപ്പെടുന്നുവെന്നത് ദയവായി സ്ഥിരീകരിക്കുക. നിങ്ങള് വിശ്വസിക്കുന്ന പ്ലഗ്-ഇനുകള് മാത്രമേ ഇന്സ്റ്റാള് ചെയ്യാവൂ.</translation> +<translation id="4003986561708175844">ആവശ്യമായ പ്ലഗ്-ഇന് ഇന്സ്റ്റാളുചെയ്തില്ല</translation> +<translation id="3018094406922859308">പ്ലഗ്-ഇന് ഡൌണ്ലോഡുചെയ്യുന്നു...</translation> <translation id="7364796246159120393">ഫയല് തിരഞ്ഞെടുക്കൂ</translation> <translation id="8964020114565522021">ഇവിടെ ഫയല് ഇഴയ്ക്കുക</translation> <translation id="838869780401515933">പരിശോധിക്കൂ</translation> <translation id="2846343701378493991">1024 (മീഡിയം ഗ്രേഡ്)</translation> <translation id="5476505524087279545">അണ്ചെക്ക് ചെയ്യുക</translation> -<translation id="679352192834563463">ഈ ഉള്ളടക്കം പ്രദര്ശിപ്പിക്കുന്നതിന് ഒരു പ്ലഗിനും ലഭ്യമല്ല</translation> <translation id="3789841737615482174">ഇന്സ്റ്റോള് ചെയ്യുക</translation> +<translation id="5253117816378681419">നിങ്ങള് ഈ <ph name="PLUGIN"/> പ്ലഗ്-ഇന് ഇന്സ്റ്റാളുചെയ്യാന് താല്പ്പര്യപ്പെടുന്നുവെന്നത് ദയവായി സ്ഥിരീകരിക്കുക. നിങ്ങള് വിശ്വസിക്കുന്ന പ്ലഗ്-ഇനുകള് മാത്രമേ ഇന്സ്റ്റാള് ചെയ്യാവൂ.</translation> <translation id="6663448176199120256">സമീപകാല തിരയലുകള്</translation> -<translation id="3600343118165084788">പ്ലഗ്-ഇന് ഡൌണ്ലോഡ് ചെയ്യുന്നതിനായി ഇവിടെ ക്ലിക്കുചെയ്യുക</translation> +<translation id="2597378329261239068">ഈ പ്രമാണം പാസ്വേഡ് പരിരക്ഷിതമാണ്. ദയവായി ഒരു പാസ്വേഡ് നല്കുക.</translation> <translation id="6807599807928161586">വെബ് മേഖല</translation> <translation id="5939518447894949180">വീണ്ടും സജ്ജീകരിക്കുക</translation> -<translation id="3771786644471114952">പ്ലഗിന് നേടുക</translation> <translation id="1842960171412779397">തിരഞ്ഞെടുക്കൂ</translation> +<translation id="7638452146404718955">പ്ലഗ്-ഇന് ഡൌണ്ലോഡുചെയ്യുന്നതിന് ഇവിടെ ക്ലിക്കുചെയ്യുക</translation> <translation id="6119846243427417423">ആക്റ്റിവേറ്റ് ചെയ്യുക</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ഫയലുകള്</translation> -<translation id="3926627843712816530">പ്ലഗിന് ഇന്സ്റ്റോള് ചെയ്യാന് നിങ്ങള് താല്പര്യപ്പെടുന്നുവെന്ന് ദയവായി ഉറപ്പുവരുത്തുക. നിങ്ങള്ക്ക് വിശ്വാസ്യതയുള്ള പ്ലഗിനുകള് മാത്രം നിങ്ങള് ഇന്സ്റ്റോള് ചെയ്യുക.</translation> -<translation id="4838490908464673667">ആവശ്യമായ പ്ലഗിന് ഇന്സ്റ്റാള് ചെയ്തില്ല</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> പ്ലഗ്-ഇന് ഇന്സ്റ്റാളുചെയ്തില്ല</translation> +<translation id="6765711848403622008">ഈ ഉള്ളടക്കം പ്രദര്ശിപ്പിക്കുന്നതിന് പ്ലഗ്-ഇന്നൊന്നും ലഭ്യമല്ല</translation> <translation id="8597182159515967513">തലക്കെട്ട്</translation> <translation id="2653659639078652383">സമര്പ്പിക്കൂ</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> പ്ലഗ്-ഇന് ആവശ്യമുണ്ട്</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_mr.xtb b/webkit/glue/resources/webkit_strings_mr.xtb index fd6c4a4..3061c16 100644 --- a/webkit/glue/resources/webkit_strings_mr.xtb +++ b/webkit/glue/resources/webkit_strings_mr.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="mr"> -<translation id="4420062214988137980">प्लगइन स्थापना अयशस्वी</translation> +<translation id="4519964825805946997"><ph name="URL"/> वरून प्लग-इन स्थापित करणे अयशस्वी</translation> <translation id="1235745349614807883">अलीकडील शोध साफ करा</translation> -<translation id="3825324228893189080">अतिरिक्त प्लगइन आवश्यक</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> प्लगइन स्थापित नाही</translation> <translation id="5048533449481078685">सूची चिन्हक</translation> +<translation id="372362261556059955">अतिरिक्त प्लग-इन आवश्यक</translation> <translation id="4202807286478387388">जंप करा</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">कृपया आपण <ph name="PLUGIN"/> हे प्लगइन स्थापित करू इच्छिता याची पुष्टी करा. आपण केवळ आपल्याला विश्वास असलेले प्लगइन स्थापित केले पाहिजेत.</translation> <translation id="7658239707568436148">रद्द करा</translation> <translation id="795667975304826397">कोणतीही फाइल निवडलेली नाही</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> प्लगइन आवश्यक</translation> -<translation id="8662565117025751661">प्लगइन डाउनलोड करीत आहे...</translation> +<translation id="1416462845279468967">प्लग-इन स्थापना अयशस्वी</translation> <translation id="8141602879876242471">ही शोध घेण्यायोग्य अनुक्रमणिका आहे. शोध कीवर्ड प्रविष्ट करा:</translation> +<translation id="5650795167354946011">प्लग-इन स्थापित केल्यानंतर, रीफ्रेश करण्यासाठी येथे क्लिक करा</translation> <translation id="6845533974506654842">दाबा</translation> <translation id="8244226242650769279">प्रतिमा नकाशा</translation> -<translation id="1383141426028388991"><ph name="URL"/> वरून प्लगइन स्थापित करण्यात अयशस्वी</translation> <translation id="2548326553472216322">अलीकडील शोध नाहीत</translation> <translation id="5944544982112848342">2048 (उच्च ग्रेड)</translation> <translation id="3040011195152428237">दुवा</translation> -<translation id="8281246460978372009">प्लगइन स्थापित केल्यानंतर, रीफ्रेश करण्यासाठी येथे क्लिक करा</translation> +<translation id="2745343197843472802">प्लग-इन मिळवा</translation> +<translation id="5776402066334188252">कृपया आपण हे प्लग-इन स्थापित करण्यास इच्छुक असल्याची पुष्टी करा. आपण केवळ विश्वासार्ह असलेली प्लग-इन्स फक्त स्थापित करावीत.</translation> +<translation id="4003986561708175844">आवश्यक असलेले प्लग-इन स्थापित नाही</translation> +<translation id="3018094406922859308">प्लग-इन डाउनलोड करीत आहे...</translation> <translation id="7364796246159120393">फाइल निवडा</translation> <translation id="8964020114565522021">फाइल येथे ड्रॅग करा</translation> <translation id="838869780401515933">तपासा</translation> <translation id="2846343701378493991">1024 (मध्यम प्रत)</translation> <translation id="5476505524087279545">अनचेक</translation> -<translation id="679352192834563463">ही सामग्री प्रदर्शित करण्यासाठी कोणतेही प्लगइन उपलब्ध नाही</translation> <translation id="3789841737615482174">स्थापना करा</translation> +<translation id="5253117816378681419">कृपया आपल्याला प्लग-इन <ph name="PLUGIN"/> स्थापित करणे आवडत असल्याची पुष्टी करा. आपण आपला विश्वास असलेले प्लग-इन्स फक्त स्थापित करावे. </translation> <translation id="6663448176199120256">अलीकडील शोध</translation> -<translation id="3600343118165084788">प्लगइन डाउनलोड करण्यासाठी येथे क्लिक करा</translation> +<translation id="2597378329261239068">हा दस्तऐवज संकेतशब्द संरक्षित आहे. कृपया संकेतशब्द प्रविष्ट करा.</translation> <translation id="6807599807928161586">वेब क्षेत्र</translation> <translation id="5939518447894949180">रीसेट करा</translation> -<translation id="3771786644471114952">प्लगइन मिळवा</translation> <translation id="1842960171412779397">निवडा</translation> +<translation id="7638452146404718955">प्लग-इन डाउनलोड करण्यासाठी येथे क्लिक करा</translation> <translation id="6119846243427417423">सक्रिय करा</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> फायली</translation> -<translation id="3926627843712816530">कृपया आपण हे प्लगइन स्थापित करू इच्छिता याची पुष्टी करा. आपण ज्यांचेवर विश्वास करता केवळ असेच प्लगइन स्थापित करावेत.</translation> -<translation id="4838490908464673667">आवश्यक प्लगइन स्थापित नाही</translation> +<translation id="4470547978413275879">प्लग-इन <ph name="PLUGIN"/> स्थापित केले नाही</translation> +<translation id="6765711848403622008">ही सामग्री प्रदर्शित करण्यासाठी कोणतेही प्लग-इन उपलब्ध नाही</translation> <translation id="8597182159515967513">शीर्षलेख</translation> <translation id="2653659639078652383">सबमिट करा</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> प्लग-इन आवश्यक ,,,</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_nl.xtb b/webkit/glue/resources/webkit_strings_nl.xtb index c9cea68..df39241 100644 --- a/webkit/glue/resources/webkit_strings_nl.xtb +++ b/webkit/glue/resources/webkit_strings_nl.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="nl"> -<translation id="4420062214988137980">Installatie van plug-in mislukt</translation> +<translation id="4519964825805946997">Het installeren van de invoegtoepassing van <ph name="URL"/> is mislukt</translation> <translation id="1235745349614807883">Recente zoekopdrachten wissen</translation> -<translation id="3825324228893189080">Aanvullende plug-in vereist</translation> -<translation id="2965480764085142436">De plug-in <ph name="PLUGIN"/> is niet geïnstalleerd</translation> <translation id="5048533449481078685">lijstmarkering</translation> +<translation id="372362261556059955">Aanvullende invoegtoepassing vereist</translation> <translation id="4202807286478387388">Gaan naar</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Bevestig dat u de plugin <ph name="PLUGIN"/> wilt installeren. Installeer alleen plug-ins die u vertrouwt.</translation> <translation id="7658239707568436148">Annuleren</translation> <translation id="795667975304826397">Geen bestand gekozen</translation> -<translation id="1275511093094545429">Plug-in <ph name="PLUGIN"/> vereist</translation> -<translation id="8662565117025751661">Plug-in downloaden...</translation> +<translation id="1416462845279468967">De installatie van de invoegtoepassing is mislukt</translation> <translation id="8141602879876242471">Dit is een doorzoekbare index. Geef zoekwoorden op:</translation> +<translation id="5650795167354946011">Klik hier na het installeren van de invoegtoepassing om te vernieuwen</translation> <translation id="6845533974506654842">Indrukken</translation> <translation id="8244226242650769279">image map</translation> -<translation id="1383141426028388991">Kan plug-in niet installeren van <ph name="URL"/></translation> <translation id="2548326553472216322">Geen recente zoekopdrachten</translation> <translation id="5944544982112848342">2048 (hoog niveau)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Klik hier na het installeren van de plug-in om te vernieuwen</translation> +<translation id="2745343197843472802">Invoegtoepassing downloaden</translation> +<translation id="5776402066334188252">Bevestig dat u deze invoegtoepassing wilt installeren. U moet alleen invoegtoepassingen installeren die u vertrouwt.</translation> +<translation id="4003986561708175844">De vereiste invoegtoepassing is niet geïnstalleerd</translation> +<translation id="3018094406922859308">Invoegtoepassing downloaden...</translation> <translation id="7364796246159120393">Bestand kiezen</translation> <translation id="8964020114565522021">Sleep bestand hier naartoe</translation> <translation id="838869780401515933">Selecteren</translation> <translation id="2846343701378493991">1024 (gemiddeld niveau)</translation> <translation id="5476505524087279545">Deselecteren</translation> -<translation id="679352192834563463">Er is geen plug-in beschikbaar om deze inhoud weer te geven</translation> <translation id="3789841737615482174">Installeren</translation> +<translation id="5253117816378681419">Bevestig dat u de invoegtoepassing van <ph name="PLUGIN"/> wilt installeren. U moet alleen invoegtoepassingen installeren die u vertrouwt.</translation> <translation id="6663448176199120256">Recente zoekopdrachten</translation> -<translation id="3600343118165084788">Klik hier om de plug-in te downloaden</translation> +<translation id="2597378329261239068">Dit document is beveiligd met een wachtwoord. Geef een wachtwoord op.</translation> <translation id="6807599807928161586">webgedeelte</translation> <translation id="5939518447894949180">Herstellen</translation> -<translation id="3771786644471114952">Plug-in ophalen</translation> <translation id="1842960171412779397">Selecteren</translation> +<translation id="7638452146404718955">Klik hier om de invoegtoepassing te downloaden</translation> <translation id="6119846243427417423">Activeren</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> bestanden</translation> -<translation id="3926627843712816530">Bevestig dat u deze plug-in wilt installeren. Installeer alleen plug-ins die u vertrouwt.</translation> -<translation id="4838490908464673667">De vereiste plug-in is niet geïnstalleerd</translation> +<translation id="4470547978413275879">De invoegtoepassing <ph name="PLUGIN"/> is niet geïnstalleerd</translation> +<translation id="6765711848403622008">Er is geen invoegtoepassing beschikbaar om deze inhoud weer te geven</translation> <translation id="8597182159515967513">kop</translation> <translation id="2653659639078652383">Verzenden</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/>-invoegtoepassing vereist</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_no.xtb b/webkit/glue/resources/webkit_strings_no.xtb index f8f419a..c94ad8f 100644 --- a/webkit/glue/resources/webkit_strings_no.xtb +++ b/webkit/glue/resources/webkit_strings_no.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="no"> -<translation id="4420062214988137980">Installasjon av programtillegg mislyktes</translation> +<translation id="4519964825805946997">Kunne ikke installere programtillegget fra <ph name="URL"/></translation> <translation id="1235745349614807883">Fjern nylige søk</translation> -<translation id="3825324228893189080">Ytterligere programtillegg kreves</translation> -<translation id="2965480764085142436">Programtillegget <ph name="PLUGIN"/> er ikke installert</translation> <translation id="5048533449481078685">listemarkør</translation> +<translation id="372362261556059955">Ekstra programtillegg kreves</translation> <translation id="4202807286478387388">hopp</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Du må bekrefte om du vil installere programtillegget <ph name="PLUGIN"/>. Du bør bare installere programtillegg du stoler på.</translation> <translation id="7658239707568436148">Avbryt</translation> <translation id="795667975304826397">Ingen fil valgt</translation> -<translation id="1275511093094545429">Programtillegget <ph name="PLUGIN"/> kreves</translation> -<translation id="8662565117025751661">Laster ned programtillegg...</translation> +<translation id="1416462845279468967">Installering av programtillegg mislyktes</translation> <translation id="8141602879876242471">Dette er en søkbar indeks. Angi søkeordene:</translation> +<translation id="5650795167354946011">Når programtillegget er installert, klikker du her for å oppdatere</translation> <translation id="6845533974506654842">trykk</translation> <translation id="8244226242650769279">bildekart</translation> -<translation id="1383141426028388991">Kunne ikke installere programtillegget fra <ph name="URL"/></translation> <translation id="2548326553472216322">Ingen nylige søk</translation> <translation id="5944544982112848342">2048 (sterk)</translation> <translation id="3040011195152428237">kobling</translation> -<translation id="8281246460978372009">Når programtillegget er installert, klikker du her for å oppdatere</translation> +<translation id="2745343197843472802">Finn programtillegg</translation> +<translation id="5776402066334188252">Bekreft at du ønsker å installere programtillegget. Du bør kun installere programtillegg du stoler på.</translation> +<translation id="4003986561708175844">Det nødvendige programmet er ikke installert</translation> +<translation id="3018094406922859308">Laster ned programtillegg</translation> <translation id="7364796246159120393">Velg fil</translation> <translation id="8964020114565522021">Dra filen hit</translation> <translation id="838869780401515933">merk av</translation> <translation id="2846343701378493991">1024 (middels)</translation> <translation id="5476505524087279545">fjern merke</translation> -<translation id="679352192834563463">Intet programtillegg tilgjengelig for å vise dette innholdet</translation> <translation id="3789841737615482174">Installer</translation> +<translation id="5253117816378681419">Bekreft at du ønsker å installere programtillegget <ph name="PLUGIN"/>. Du bør kun installere programtillegg du stoler på.</translation> <translation id="6663448176199120256">Nylige søk</translation> -<translation id="3600343118165084788">Klikk her for å laste ned programtillegget</translation> +<translation id="2597378329261239068">Dette dokumentet er passordbeskyttet. Skriv inn et passord.</translation> <translation id="6807599807928161586">nettområde</translation> <translation id="5939518447894949180">Tilbakestill</translation> -<translation id="3771786644471114952">Få programtillegg</translation> <translation id="1842960171412779397">velg</translation> +<translation id="7638452146404718955">Klikk her for å laste ned programtillegget</translation> <translation id="6119846243427417423">aktiver</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> filer</translation> -<translation id="3926627843712816530">Du må bekrefte om du vil installere programtillegget. Du bør bare installere programtillegg du stoler på.</translation> -<translation id="4838490908464673667">Det nødvendige programtillegget er ikke installert</translation> +<translation id="4470547978413275879">Programtillegget <ph name="PLUGIN"/> er ikke installert</translation> +<translation id="6765711848403622008">Ingen programtillegg tilgjengelig for å vise dette innholdet</translation> <translation id="8597182159515967513">overskrift</translation> <translation id="2653659639078652383">Send</translation> +<translation id="8475551193147984329">Programtillegg <ph name="PLUGIN"/> påkrevd</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_pl.xtb b/webkit/glue/resources/webkit_strings_pl.xtb index c666eb9..ea4f6cf 100644 --- a/webkit/glue/resources/webkit_strings_pl.xtb +++ b/webkit/glue/resources/webkit_strings_pl.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="pl"> -<translation id="4420062214988137980">Instalacja dodatku plug-in nie powiodła się</translation> +<translation id="4519964825805946997">Nie można zainstalować wtyczki dostępnej pod adresem <ph name="URL"/></translation> <translation id="1235745349614807883">Wyczyść ostatnie wyszukiwania</translation> -<translation id="3825324228893189080">Wymagany dodatkowy dodatek plug-in</translation> -<translation id="2965480764085142436">Dodatek plug-in <ph name="PLUGIN"/> nie został zainstalowany</translation> <translation id="5048533449481078685">znacznik listy</translation> +<translation id="372362261556059955">Potrzebna jest dodatkowa wtyczka</translation> <translation id="4202807286478387388">przejdź</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Potwierdź instalację dodatku plug-in <ph name="PLUGIN"/>. Należy instalować wyłącznie zaufane dodatki plug-in.</translation> <translation id="7658239707568436148">Anuluj</translation> <translation id="795667975304826397">Nie wybrano pliku</translation> -<translation id="1275511093094545429">Wymagany dodatek plug-in <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Pobieranie dodatku plug-in...</translation> +<translation id="1416462845279468967">Instalacja wtyczki nie powiodła się</translation> <translation id="8141602879876242471">Ten indeks można przeszukiwać. Wprowadź wyszukiwane słowa kluczowe:</translation> +<translation id="5650795167354946011">Po zainstalowaniu wtyczki kliknij tutaj, aby odświeżyć okno</translation> <translation id="6845533974506654842">naciśnij</translation> <translation id="8244226242650769279">mapa grafiki</translation> -<translation id="1383141426028388991">Nie można zainstalować wtyczki z adresu <ph name="URL"/></translation> <translation id="2548326553472216322">Brak ostatnich wyszukiwań</translation> <translation id="5944544982112848342">2048 (wysoki poziom)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Po zainstalowaniu dodatku plug-in kliknij tutaj, aby odświeżyć</translation> +<translation id="2745343197843472802">Pobierz wtyczkę</translation> +<translation id="5776402066334188252">Potwierdź zamiar zainstalowania tej wtyczki. Należy instalować wyłącznie zaufane wtyczki.</translation> +<translation id="4003986561708175844">Wymagana wtyczka nie jest zainstalowana</translation> +<translation id="3018094406922859308">Trwa pobieranie wtyczki...</translation> <translation id="7364796246159120393">Wybierz plik</translation> <translation id="8964020114565522021">Przeciągnij plik tutaj</translation> <translation id="838869780401515933">zaznacz</translation> <translation id="2846343701378493991">1024 (średni poziom)</translation> <translation id="5476505524087279545">odznacz</translation> -<translation id="679352192834563463">Brak dostępnego dodatku plug-in umożliwiającego wyświetlenie tej treści</translation> <translation id="3789841737615482174">Zainstaluj</translation> +<translation id="5253117816378681419">Potwierdź zamiar zainstalowania wtyczki <ph name="PLUGIN"/>. Należy instalować wyłącznie zaufane wtyczki.</translation> <translation id="6663448176199120256">Ostatnie wyszukiwania</translation> -<translation id="3600343118165084788">Kliknij tutaj, aby pobrać dodatek plug-in</translation> +<translation id="2597378329261239068">Ten dokument jest chroniony hasłem. Wprowadź hasło.</translation> <translation id="6807599807928161586">obszar sieci</translation> <translation id="5939518447894949180">Resetuj</translation> -<translation id="3771786644471114952">Pobierz dodatek plug-in</translation> <translation id="1842960171412779397">wybierz</translation> +<translation id="7638452146404718955">Kliknij tutaj, aby pobrać wtyczkę</translation> <translation id="6119846243427417423">aktywuj</translation> <translation id="8444882422881193423">Liczba plików: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Potwierdź instalację tego dodatku plug-in. Należy instalować wyłącznie zaufane dodatki plug-in.</translation> -<translation id="4838490908464673667">Wymagany dodatek plug-in nie został zainstalowany</translation> +<translation id="4470547978413275879">Wtyczka <ph name="PLUGIN"/> nie jest zainstalowana</translation> +<translation id="6765711848403622008">Brak dostępnej wtyczki umożliwiającej wyświetlenie tej treści</translation> <translation id="8597182159515967513">nagłówek</translation> <translation id="2653659639078652383">Prześlij</translation> +<translation id="8475551193147984329">Potrzebna jest wtyczka <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_pt-BR.xtb b/webkit/glue/resources/webkit_strings_pt-BR.xtb index 5dfc2d3..b34c7cb 100644 --- a/webkit/glue/resources/webkit_strings_pt-BR.xtb +++ b/webkit/glue/resources/webkit_strings_pt-BR.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="pt-BR"> -<translation id="4420062214988137980">Falha de instalação de plug-in</translation> +<translation id="4519964825805946997">Falha ao instalar o plug-in de <ph name="URL"/></translation> <translation id="1235745349614807883">Limpar pesquisas recentes</translation> -<translation id="3825324228893189080">Plug-in adicional necessário</translation> -<translation id="2965480764085142436">O plug-in <ph name="PLUGIN"/> não está instalado</translation> <translation id="5048533449481078685">marcador de lista</translation> +<translation id="372362261556059955">Plug-in adicional necessário</translation> <translation id="4202807286478387388">pular</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Confirme se deseja instalar este plug-in <ph name="PLUGIN"/>. Instale somente plug-ins confiáveis.</translation> <translation id="7658239707568436148">Cancelar</translation> <translation id="795667975304826397">Nenhum arquivo selecionado</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> plug-in necessário</translation> -<translation id="8662565117025751661">Fazendo download do plug-in...</translation> +<translation id="1416462845279468967">Falha na instalação do plug-in</translation> <translation id="8141602879876242471">Este é um índice pesquisável. Insira palavras-chave de pesquisa:</translation> +<translation id="5650795167354946011">Depois de instalar o plug-in, clique aqui para atualizar</translation> <translation id="6845533974506654842">pressione</translation> <translation id="8244226242650769279">mapa de imagens</translation> -<translation id="1383141426028388991">Falha ao instalar o plug-in de <ph name="URL"/></translation> <translation id="2548326553472216322">Nenhuma pesquisa recente</translation> <translation id="5944544982112848342">2048 (Nível alto)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Depois de instalar o plug-in, clique aqui para atualizar</translation> +<translation id="2745343197843472802">Obter plug-in</translation> +<translation id="5776402066334188252">Confirme se você deseja instalar este plug-in. Você deve instalar apenas plug-ins em que confia.</translation> +<translation id="4003986561708175844">O plug-in necessário não está instalado</translation> +<translation id="3018094406922859308">Fazendo download do plug-in...</translation> <translation id="7364796246159120393">Escolher arquivo</translation> <translation id="8964020114565522021">Arraste o arquivo até aquil</translation> <translation id="838869780401515933">marcar</translation> <translation id="2846343701378493991">1024 (Nível médio)</translation> <translation id="5476505524087279545">desmarcar</translation> -<translation id="679352192834563463">Nenhum plug-in disponível para exibir este conteúdo</translation> <translation id="3789841737615482174">Instalar</translation> +<translation id="5253117816378681419">Confirme se você deseja instalar o plug-in do <ph name="PLUGIN"/>. Você deve instalar apenas plug-ins em que você confia.</translation> <translation id="6663448176199120256">Pesquisas recentes</translation> -<translation id="3600343118165084788">Clique aqui para fazer download do plug-in</translation> +<translation id="2597378329261239068">Este documento está protegido por senha. Digite a senha.</translation> <translation id="6807599807928161586">área da web</translation> <translation id="5939518447894949180">Redefinir</translation> -<translation id="3771786644471114952">Obter plug-in</translation> <translation id="1842960171412779397">selecione</translation> +<translation id="7638452146404718955">Clique aqui para fazer download do plug-in</translation> <translation id="6119846243427417423">ativar</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> arquivos</translation> -<translation id="3926627843712816530">Confirme se deseja instalar este plug-in. Instale somente plug-ins confiáveis.</translation> -<translation id="4838490908464673667">O plug-in necessário não está instalado</translation> +<translation id="4470547978413275879">O plug-in do <ph name="PLUGIN"/> não está instalado</translation> +<translation id="6765711848403622008">Nenhum plug-in disponível para exibir este conteúdo</translation> <translation id="8597182159515967513">cabeçalho</translation> <translation id="2653659639078652383">Enviar</translation> +<translation id="8475551193147984329">Plug-in do <ph name="PLUGIN"/> necessário</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_pt-PT.xtb b/webkit/glue/resources/webkit_strings_pt-PT.xtb index 4b585e5..817cdf4 100644 --- a/webkit/glue/resources/webkit_strings_pt-PT.xtb +++ b/webkit/glue/resources/webkit_strings_pt-PT.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="pt-PT"> -<translation id="4420062214988137980">A instalação do plug-in falhou</translation> +<translation id="4519964825805946997">Falha ao instalar o plug-in de <ph name="URL"/></translation> <translation id="1235745349614807883">Limpar pesquisas recentes</translation> -<translation id="3825324228893189080">Plug-in adicional necessário</translation> -<translation id="2965480764085142436">O plug-in <ph name="PLUGIN"/> não está instalado</translation> <translation id="5048533449481078685">marcador de lista</translation> +<translation id="372362261556059955">Plug-in adicional requerido</translation> <translation id="4202807286478387388">ir para</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Confirme que pretende instalar o plug-in <ph name="PLUGIN"/>. Apenas deverá instalar plug-ins fidedignos.</translation> <translation id="7658239707568436148">Cancelar</translation> <translation id="795667975304826397">Nenhum ficheiro seleccionado</translation> -<translation id="1275511093094545429">Plug-in <ph name="PLUGIN"/> necessário</translation> -<translation id="8662565117025751661">A transferir o plug-in…</translation> +<translation id="1416462845279468967">A instalação do plug-in falhou</translation> <translation id="8141602879876242471">Este índice é pesquisável. Introduza palavras-chave de pesquisa:</translation> +<translation id="5650795167354946011">Após instalar o plug-in, clique aqui para actualizar</translation> <translation id="6845533974506654842">premir</translation> <translation id="8244226242650769279">mapa de imagem</translation> -<translation id="1383141426028388991">Falha ao instalar plug-in de <ph name="URL"/></translation> <translation id="2548326553472216322">Nenhuma pesquisa recente</translation> <translation id="5944544982112848342">2048 (Tamanho grande)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">Após instalar o plug-in, clique aqui para actualizar</translation> +<translation id="2745343197843472802">Obter plug-in</translation> +<translation id="5776402066334188252">Confirme se pretende instalar este plug-in. Deve instalar apenas plug-ins fidedignos.</translation> +<translation id="4003986561708175844">O plug-in necessário não está instalado</translation> +<translation id="3018094406922859308">A transferir plug-in...</translation> <translation id="7364796246159120393">Escolher ficheiro</translation> <translation id="8964020114565522021">Arraste o ficheiro para aqui</translation> <translation id="838869780401515933">verificar</translation> <translation id="2846343701378493991">1024 (Tamanho médio)</translation> <translation id="5476505524087279545">desmarcar</translation> -<translation id="679352192834563463">Nenhum plug-in disponível para apresentar este conteúdo</translation> <translation id="3789841737615482174">Instalar</translation> +<translation id="5253117816378681419">Confirme se pretende instalar o plug-in do <ph name="PLUGIN"/>. Deve instalar apenas plug-ins fidedignos.</translation> <translation id="6663448176199120256">Pesquisas recentes</translation> -<translation id="3600343118165084788">Clique aqui para transferir o plug-in</translation> +<translation id="2597378329261239068">Este documento está protegido por palavra-passe. Introduza uma palavra-passe.</translation> <translation id="6807599807928161586">Área Web</translation> <translation id="5939518447894949180">Repor</translation> -<translation id="3771786644471114952">Obter plug-in</translation> <translation id="1842960171412779397">seleccionar</translation> +<translation id="7638452146404718955">Clique aqui para transferir o plug-in</translation> <translation id="6119846243427417423">activar</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ficheiros</translation> -<translation id="3926627843712816530">Confirme que pretende instalar este plug-in. Apenas deverá instalar plug-ins fidedignos.</translation> -<translation id="4838490908464673667">O plug-in necessário não está instalado</translation> +<translation id="4470547978413275879">O plug-in do <ph name="PLUGIN"/> não está instalado</translation> +<translation id="6765711848403622008">Nenhum plug-in disponível para apresentar este conteúdo</translation> <translation id="8597182159515967513">cabeçalho</translation> <translation id="2653659639078652383">Submeter</translation> +<translation id="8475551193147984329">Plug-in do <ph name="PLUGIN"/> necessário</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ro.xtb b/webkit/glue/resources/webkit_strings_ro.xtb index 72c8f43..2f8ec55 100644 --- a/webkit/glue/resources/webkit_strings_ro.xtb +++ b/webkit/glue/resources/webkit_strings_ro.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ro"> -<translation id="4420062214988137980">Instalarea plug-in-ului a eşuat</translation> +<translation id="4519964825805946997">Instalarea pluginului de la <ph name="URL"/> a eşuat</translation> <translation id="1235745349614807883">Ştergeţi căutările recente</translation> -<translation id="3825324228893189080">Este necesar un plug-in suplimentar</translation> -<translation id="2965480764085142436">Plug-in-ul <ph name="PLUGIN"/> nu este instalat</translation> <translation id="5048533449481078685">marcator listă</translation> +<translation id="372362261556059955">Este necesar un plugin suplimentar</translation> <translation id="4202807286478387388">Salt</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Confirmaţi că doriţi să instalaţi plug-in-ul <ph name="PLUGIN"/>. Ar trebui să instalaţi numai plug-in-uri în care aveţi încredere.</translation> <translation id="7658239707568436148">Anulaţi</translation> <translation id="795667975304826397">Nu s-au ales fişiere</translation> -<translation id="1275511093094545429">Este necesar plug-in-ul <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Se descarcă plug-inul...</translation> +<translation id="1416462845279468967">Instalarea pluginului a eşuat</translation> <translation id="8141602879876242471">Acesta este un index în care se poate căuta. Introduceţi cuvintele cheie pentru căutare:</translation> +<translation id="5650795167354946011">După instalarea pluginului, faceţi clic aici pentru a actualiza</translation> <translation id="6845533974506654842">Apăsaţi</translation> <translation id="8244226242650769279">hartă cu imagini</translation> -<translation id="1383141426028388991">Instalarea plug-in-ului de la <ph name="URL"/> a eşuat</translation> <translation id="2548326553472216322">Nicio căutare recentă</translation> <translation id="5944544982112848342">2048 (Grad înalt)</translation> <translation id="3040011195152428237">link</translation> -<translation id="8281246460978372009">După instalarea plug-in-ului, faceţi clic aici pentru a reactualiza</translation> +<translation id="2745343197843472802">Descărcaţi pluginul</translation> +<translation id="5776402066334188252">Confirmaţi că doriţi să instalaţi acest plugin. Vă recomandăm să instalaţi numai pluginuri în care aveţi încredere.</translation> +<translation id="4003986561708175844">Pluginul necesar nu este instalat</translation> +<translation id="3018094406922859308">Se descarcă pluginul...</translation> <translation id="7364796246159120393">Alegeţi fişierul</translation> <translation id="8964020114565522021">Trageţi fişierul aici</translation> <translation id="838869780401515933">Bifaţi</translation> <translation id="2846343701378493991">1024 (Grad mediu)</translation> <translation id="5476505524087279545">Debifaţi</translation> -<translation id="679352192834563463">Niciun plug-in disponibil pentru a afişa acest conţinut</translation> <translation id="3789841737615482174">Instalaţi</translation> +<translation id="5253117816378681419">Confirmaţi că doriţi să instalaţi pluginul <ph name="PLUGIN"/>. Vă recomandăm să instalaţi numai pluginuri în care aveţi încredere.</translation> <translation id="6663448176199120256">Căutări recente</translation> -<translation id="3600343118165084788">Faceţi clic aici pentru a descărca plug-in-ul</translation> +<translation id="2597378329261239068">Acest document este protejat cu parolă. Introduceţi o parolă.</translation> <translation id="6807599807928161586">zona Web</translation> <translation id="5939518447894949180">Resetaţi</translation> -<translation id="3771786644471114952">Obţineţi plug-in-ul</translation> <translation id="1842960171412779397">Selectaţi</translation> +<translation id="7638452146404718955">Faceţi clic aici pentru a descărca pluginul</translation> <translation id="6119846243427417423">Activaţi</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> fişiere</translation> -<translation id="3926627843712816530">Confirmaţi că doriţi să instalaţi acest plug-in. Ar trebui să instalaţi numai plug-in-uri în care aveţi încredere.</translation> -<translation id="4838490908464673667">Plug-in-ul necesar nu este instalat</translation> +<translation id="4470547978413275879">Pluginul <ph name="PLUGIN"/> nu este instalat</translation> +<translation id="6765711848403622008">Niciun plugin disponibil pentru a afişa acest conţinut</translation> <translation id="8597182159515967513">titlu</translation> <translation id="2653659639078652383">Trimiteţi</translation> +<translation id="8475551193147984329">Este necesar pluginul <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ru.xtb b/webkit/glue/resources/webkit_strings_ru.xtb index b9fe2f3..97e2796 100644 --- a/webkit/glue/resources/webkit_strings_ru.xtb +++ b/webkit/glue/resources/webkit_strings_ru.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ru"> -<translation id="4420062214988137980">Ошибка при установке плагина</translation> +<translation id="4519964825805946997">Не удалось установить подключаемый модуль с адреса <ph name="URL"/></translation> <translation id="1235745349614807883">Очистить недавние поиски</translation> -<translation id="3825324228893189080">Необходим дополнительный плагин</translation> -<translation id="2965480764085142436">Плагин <ph name="PLUGIN"/> не установлен</translation> <translation id="5048533449481078685">маркер списка</translation> +<translation id="372362261556059955">Необходим дополнительный подключаемый модуль</translation> <translation id="4202807286478387388">перейти</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Подтвердите, что хотите установить плагин <ph name="PLUGIN"/>. Устанавливать следует модули только тех издателей, которым вы доверяете.</translation> <translation id="7658239707568436148">Отмена</translation> <translation id="795667975304826397">Файл не выбран</translation> -<translation id="1275511093094545429">Необходим плагин <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Загрузка подключаемого модуля...</translation> +<translation id="1416462845279468967">Не удалось установить подключаемый модуль</translation> <translation id="8141602879876242471">Это индекс с возможностью поиска. Введите ключевые слова для поиска:</translation> +<translation id="5650795167354946011">После установки подключаемого модуля нажмите здесь, чтобы обновить страницу</translation> <translation id="6845533974506654842">нажать</translation> <translation id="8244226242650769279">графическая карта</translation> -<translation id="1383141426028388991">Не удалось установить подключаемый модуль со следующего адреса: <ph name="URL"/></translation> <translation id="2548326553472216322">Нет недавних поисков</translation> <translation id="5944544982112848342">2048 (Крупный размер)</translation> <translation id="3040011195152428237">ссылка</translation> -<translation id="8281246460978372009">После установки подключаемого модуля нажмите здесь для обновления</translation> +<translation id="2745343197843472802">Загрузить подключаемый модуль</translation> +<translation id="5776402066334188252">Подтвердите, что вы хотите установить этот подключаемый модуль. Вы доверяете ему?</translation> +<translation id="4003986561708175844">Не установлен необходимый подключаемый модуль</translation> +<translation id="3018094406922859308">Загрузка подключаемого модуля...</translation> <translation id="7364796246159120393">Выберите файл</translation> <translation id="8964020114565522021">Перетащите файл сюда</translation> <translation id="838869780401515933">поставить галочку</translation> <translation id="2846343701378493991">1024 (Средний размер)</translation> <translation id="5476505524087279545">снять галочку</translation> -<translation id="679352192834563463">Недоступен плагин для отображения этого содержания</translation> <translation id="3789841737615482174">Установить</translation> +<translation id="5253117816378681419">Подтвердите, что вы хотите установить подключаемый модуль <ph name="PLUGIN"/>. Вы доверяете ему?</translation> <translation id="6663448176199120256">Недавние поиски</translation> -<translation id="3600343118165084788">Нажмите здесь, чтобы загрузить плагин</translation> +<translation id="2597378329261239068">Документ защищен паролем. Введите пароль.</translation> <translation id="6807599807928161586">область Интернетеа</translation> <translation id="5939518447894949180">Изменить</translation> -<translation id="3771786644471114952">Получить плагин</translation> <translation id="1842960171412779397">выбрать</translation> +<translation id="7638452146404718955">Нажмите здесь, чтобы загрузить подключаемый модуль</translation> <translation id="6119846243427417423">активировать</translation> <translation id="8444882422881193423">Число файлов: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Подтвердите, что хотите установить этот плагин. Устанавливать следует модули только тех издателей, которым вы доверяете.</translation> -<translation id="4838490908464673667">Не установлен необходимый плагин.</translation> +<translation id="4470547978413275879">Подключаемый модуль <ph name="PLUGIN"/> не установлен</translation> +<translation id="6765711848403622008">Недоступен подключаемый модуль для отображения этого содержания</translation> <translation id="8597182159515967513">заголовок</translation> <translation id="2653659639078652383">Отправить</translation> +<translation id="8475551193147984329">Необходим подключаемый модуль <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_sk.xtb b/webkit/glue/resources/webkit_strings_sk.xtb index 0804eff..71e68a9 100644 --- a/webkit/glue/resources/webkit_strings_sk.xtb +++ b/webkit/glue/resources/webkit_strings_sk.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="sk"> -<translation id="4420062214988137980">Nedal sa nainštalovať doplnkový modul</translation> +<translation id="4519964825805946997">Inštalácia doplnku z adresy <ph name="URL"/> zlyhala</translation> <translation id="1235745349614807883">Vyčistiť posledné vyhľadávania</translation> -<translation id="3825324228893189080">Vyžaduje sa ďalší doplnkový modul</translation> -<translation id="2965480764085142436">Nie je nainštalovaný doplnkový modul <ph name="PLUGIN"/></translation> <translation id="5048533449481078685">ukazovateľ v zozname</translation> +<translation id="372362261556059955">Vyžaduje sa ďalší doplnok</translation> <translation id="4202807286478387388">skok</translation> <translation id="4611115858363067980"><ph name="FILENAME"/> <ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Potvrďte, že naozaj chcete nainštalovať doplnkový modul <ph name="PLUGIN"/>. Mali by ste inštalovať len doplnkové moduly, ktorým dôverujete.</translation> <translation id="7658239707568436148">Zrušiť</translation> <translation id="795667975304826397">Nie je vybratý žiadny súbor</translation> -<translation id="1275511093094545429">Vyžaduje sa doplnkový modul <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Preberá sa doplnkový modul...</translation> +<translation id="1416462845279468967">Inštalácia doplnku zlyhala</translation> <translation id="8141602879876242471">Tento index sa dá prehľadávať. Zadajte kľúčové slová na vyhľadanie:</translation> +<translation id="5650795167354946011">Kliknutím sem po inštalácii doplnku obnovíte obsah</translation> <translation id="6845533974506654842">stlačiť</translation> <translation id="8244226242650769279">mapa obrázka</translation> -<translation id="1383141426028388991">Nepodarilo sa nainštalovať doplnok z adresy <ph name="URL"/></translation> <translation id="2548326553472216322">Žiadne posledné vyhľadávania</translation> <translation id="5944544982112848342">2048 (vysoký stupeň)</translation> <translation id="3040011195152428237">odkaz</translation> -<translation id="8281246460978372009">Po inštalácii doplnkového modulu kliknite sem kvôli obnoveniu obsahu</translation> +<translation id="2745343197843472802">Získať doplnok</translation> +<translation id="5776402066334188252">Potvrďte, že chcete nainštalovať tento doplnok. Mali by ste inštalovať len doplnky, ktorým dôverujete.</translation> +<translation id="4003986561708175844">Vyžadovaný doplnok nie je nainštalovaný</translation> +<translation id="3018094406922859308">Prebieha preberanie doplnku...</translation> <translation id="7364796246159120393">Vybrať súbor</translation> <translation id="8964020114565522021">Súbor presunúť sem</translation> <translation id="838869780401515933">označiť</translation> <translation id="2846343701378493991">1024 (stredný stupeň)</translation> <translation id="5476505524087279545">zrušiť označenie</translation> -<translation id="679352192834563463">Na zobrazenie tohto obsahu nie je k dispozícii žiadny doplnkový modul</translation> <translation id="3789841737615482174">Inštalovať</translation> +<translation id="5253117816378681419">Potvrďte, že chcete nainštalovať doplnok <ph name="PLUGIN"/>. Mali by ste inštalovať len doplnky, ktorým dôverujete.</translation> <translation id="6663448176199120256">Posledné vyhľadávania</translation> -<translation id="3600343118165084788">Kliknite sem, ak chcete prevziať doplnkový modul</translation> +<translation id="2597378329261239068">Tento dokument je chránený heslom. Zadajte heslo.</translation> <translation id="6807599807928161586">webová oblasť</translation> <translation id="5939518447894949180">Vynulovať</translation> -<translation id="3771786644471114952">Získať doplnkový modul</translation> <translation id="1842960171412779397">vybrať</translation> +<translation id="7638452146404718955">Kliknutím sem prevezmete doplnok</translation> <translation id="6119846243427417423">aktivovať</translation> <translation id="8444882422881193423">Počet súborov: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Potvrďte, že naozaj chcete nainštalovať tento doplnkový modul. Mali by ste inštalovať len doplnkové moduly, ktorým dôverujete.</translation> -<translation id="4838490908464673667">Nie je nainštalovaný vyžadovaný doplnkový modul.</translation> +<translation id="4470547978413275879">Nie je nainštalovaný doplnok <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">Na zobrazenie tohto obsahu nie je k dispozícii žiadny doplnok</translation> <translation id="8597182159515967513">nadpis</translation> <translation id="2653659639078652383">Odoslať</translation> +<translation id="8475551193147984329">Vyžaduje sa doplnok <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_sl.xtb b/webkit/glue/resources/webkit_strings_sl.xtb index 4108745..2ee1e5b 100644 --- a/webkit/glue/resources/webkit_strings_sl.xtb +++ b/webkit/glue/resources/webkit_strings_sl.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="sl"> -<translation id="4420062214988137980">Namestitev vtičnika ni bila uspešna</translation> +<translation id="4519964825805946997">Namestitev vtičnika z naslova <ph name="URL"/> ni bila uspešna</translation> <translation id="1235745349614807883">Počisti zadnja iskanja</translation> -<translation id="3825324228893189080">Potreben je dodatni vtičnik</translation> -<translation id="2965480764085142436">Vtičnik <ph name="PLUGIN"/> ni nameščen</translation> <translation id="5048533449481078685">označevalnik seznama</translation> +<translation id="372362261556059955">Potreben je dodaten vtičnik</translation> <translation id="4202807286478387388">skoči</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Prosimo potrdite, da želite namestiti vtičnik <ph name="PLUGIN"/>. Priporočamo vam, da namestite le vtičnike, ki so vredni zaupanja.</translation> <translation id="7658239707568436148">Prekliči</translation> <translation id="795667975304826397">Nobena datoteka ni izbrana</translation> -<translation id="1275511093094545429">Potreben je vtičnik <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Prenos vtičnika ...</translation> +<translation id="1416462845279468967">Namestitev vtičnika ni bila uspešna</translation> <translation id="8141602879876242471">To je kazalo, ki omogoča iskanje. Vnesite ključne besede za iskanje:</translation> +<translation id="5650795167354946011">Po namestitvi vtičnika, kliknite tu, da osvežite</translation> <translation id="6845533974506654842">pritisni</translation> <translation id="8244226242650769279">slikovni zemljevid</translation> -<translation id="1383141426028388991">Namestitev vtičnika z naslova <ph name="URL"/> ni bila uspešna</translation> <translation id="2548326553472216322">Ni zadnjih iskanj</translation> <translation id="5944544982112848342">2048 (visoka stopnja)</translation> <translation id="3040011195152428237">povezava</translation> -<translation id="8281246460978372009">Po namestitvi vtičnika za osvežitev kliknite tu</translation> +<translation id="2745343197843472802">Prenesite vtičnik</translation> +<translation id="5776402066334188252">Potrdite, da želite namestiti ta vtičnik. Nameščajte le vtičnike, ki jim zaupate.</translation> +<translation id="4003986561708175844">Zahtevani vtičnik ni nameščen</translation> +<translation id="3018094406922859308">Prenašanje vtičnika ...</translation> <translation id="7364796246159120393">Izberi datoteko</translation> <translation id="8964020114565522021">Datoteko povleci sem</translation> <translation id="838869780401515933">potrdi</translation> <translation id="2846343701378493991">1024 (srednja stopnja)</translation> <translation id="5476505524087279545">počisti izbor</translation> -<translation id="679352192834563463">Za prikaz te vsebine ni na voljo noben vtičnik</translation> <translation id="3789841737615482174">Namesti</translation> +<translation id="5253117816378681419">Potrdite, da želite namestiti ta <ph name="PLUGIN"/> vtičnik. Nameščajte le vtičnike, ki jim zaupate.</translation> <translation id="6663448176199120256">Zadnja iskanja</translation> -<translation id="3600343118165084788">Za prenos vtičnika kliknite tukaj</translation> +<translation id="2597378329261239068">Dokument je zaščiten z geslom. Vnesite geslo.</translation> <translation id="6807599807928161586">spletno področje</translation> <translation id="5939518447894949180">Ponastavi</translation> -<translation id="3771786644471114952">Dobite vtičnik</translation> <translation id="1842960171412779397">izberi</translation> +<translation id="7638452146404718955">Če želite prenesti vtičnik, kliknite tukaj</translation> <translation id="6119846243427417423">aktiviraj</translation> <translation id="8444882422881193423">Število datotek: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Potrdite, da želite namestiti ta vtičnik. Priporočamo vam, da namestite le vtičnike, ki so vredni zaupanja.</translation> -<translation id="4838490908464673667">Potrebni vtičnik ni nameščen</translation> +<translation id="4470547978413275879">Vtičnik <ph name="PLUGIN"/> ni nameščen</translation> +<translation id="6765711848403622008">Za prikaz te vsebine ni na voljo noben vtičnik</translation> <translation id="8597182159515967513">naslov</translation> <translation id="2653659639078652383">Pošlji</translation> +<translation id="8475551193147984329">Potreben je vtičnik <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_sr.xtb b/webkit/glue/resources/webkit_strings_sr.xtb index f4da790..a54c61b 100644 --- a/webkit/glue/resources/webkit_strings_sr.xtb +++ b/webkit/glue/resources/webkit_strings_sr.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="sr"> -<translation id="4420062214988137980">Инсталирање додатне компоненте није успело</translation> +<translation id="4519964825805946997">Инсталирање додатка са адресе <ph name="URL"/> није успело</translation> <translation id="1235745349614807883">Обриши недавне претраге</translation> -<translation id="3825324228893189080">Потребна је додатна компонента</translation> -<translation id="2965480764085142436">Додатна компонента <ph name="PLUGIN"/> није инсталирана</translation> <translation id="5048533449481078685">означивач листе</translation> +<translation id="372362261556059955">Потребан је још један додатак</translation> <translation id="4202807286478387388">прескочи</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Потврдите да желите да инсталирате додатну компоненту <ph name="PLUGIN"/>. Требало би да инсталирате само додатне компоненте које сматрате поузданима.</translation> <translation id="7658239707568436148">Откажи</translation> -<translation id="795667975304826397">Није одабрана ниједна датотека</translation> -<translation id="1275511093094545429">Потребна је додатна компонента <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Преузимање додатне компоненте...</translation> +<translation id="795667975304826397">Није одабрана датотека</translation> +<translation id="1416462845279468967">Инсталација додатка није успела</translation> <translation id="8141602879876242471">Ово је индекс који може да се претражује. Унесите кључне речи за претрагу:</translation> +<translation id="5650795167354946011">Након инсталирања додатка, кликните овде да бисте освежили</translation> <translation id="6845533974506654842">притисни</translation> <translation id="8244226242650769279">мапа слике</translation> -<translation id="1383141426028388991">Неуспешно инсталирање додатне компоненте са <ph name="URL"/></translation> <translation id="2548326553472216322">Нема недавних претрага</translation> <translation id="5944544982112848342">2048 (високи степен)</translation> <translation id="3040011195152428237">веза</translation> -<translation id="8281246460978372009">Након инсталирања додатне компоненте, кликните овде да бисте освежили</translation> -<translation id="7364796246159120393">Одаберите датотеку</translation> +<translation id="2745343197843472802">Преузми додатак</translation> +<translation id="5776402066334188252">Потврдите да желите да инсталирате овај додатак. Инсталирајте само додатке у које имате поверења.</translation> +<translation id="4003986561708175844">Потребан додатак није инсталиран</translation> +<translation id="3018094406922859308">Преузимање додатка...</translation> +<translation id="7364796246159120393">Одабери датотеку</translation> <translation id="8964020114565522021">Превуците датотеку овде</translation> <translation id="838869780401515933">изабери</translation> <translation id="2846343701378493991">1024 (средњи степен)</translation> <translation id="5476505524087279545">опозови избор</translation> -<translation id="679352192834563463">Нема доступне додатне компоненте за приказивање овог садржаја</translation> <translation id="3789841737615482174">Инсталирај</translation> +<translation id="5253117816378681419">Потврдите да желите да инсталирате <ph name="PLUGIN"/> додатак. Инсталирајте само додатке у које имате поверења.</translation> <translation id="6663448176199120256">Недавне претраге</translation> -<translation id="3600343118165084788">Кликните овде да бисте преузели додатну компоненту</translation> +<translation id="2597378329261239068">Овај документ је заштићен лозинком. Унесите лозинку.</translation> <translation id="6807599807928161586">веб област</translation> <translation id="5939518447894949180">Ресетуј</translation> -<translation id="3771786644471114952">Набави додатну компоненту</translation> <translation id="1842960171412779397">изабери</translation> +<translation id="7638452146404718955">Кликните овде да бисте преузели додатак</translation> <translation id="6119846243427417423">активирај</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> датотеке(а)</translation> -<translation id="3926627843712816530">Потврдите да желите да инсталирате ову додатну компоненту. Требало би да инсталирате само додатне компоненте које сматрате поузданима.</translation> -<translation id="4838490908464673667">Потребна додатна компонента није инсталирана</translation> +<translation id="4470547978413275879">Додатак <ph name="PLUGIN"/> није инсталиран</translation> +<translation id="6765711848403622008">Ниједан додатак није доступан за приказивање овог садржаја</translation> <translation id="8597182159515967513">наслов</translation> <translation id="2653659639078652383">Пошаљи</translation> +<translation id="8475551193147984329">Потребан је <ph name="PLUGIN"/> додатак</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_sv.xtb b/webkit/glue/resources/webkit_strings_sv.xtb index 4b7323c..aa42d57 100644 --- a/webkit/glue/resources/webkit_strings_sv.xtb +++ b/webkit/glue/resources/webkit_strings_sv.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="sv"> -<translation id="4420062214988137980">Installationen av plugin-programmet misslyckades</translation> +<translation id="4519964825805946997">Det gick inte att installera plugin-program från <ph name="URL"/></translation> <translation id="1235745349614807883">Rensa senaste sökningar</translation> -<translation id="3825324228893189080">Ytterligare plugin-program krävs</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/>-plugin-programmet har inte installerats</translation> <translation id="5048533449481078685">listmarkör</translation> +<translation id="372362261556059955">Ett ytterligare plugin-program krävs</translation> <translation id="4202807286478387388">fortsätta</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Bekräfta att du vill installera <ph name="PLUGIN"/>-plugin-programmet. Installera bara tillförlitliga plugin-program.</translation> <translation id="7658239707568436148">Avbryt</translation> <translation id="795667975304826397">Ingen fil har valts</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/>-pluginprogram krävs</translation> -<translation id="8662565117025751661">Laddar ned plugin-program...</translation> +<translation id="1416462845279468967">Installationen av plugin-programmet misslyckades</translation> <translation id="8141602879876242471">Det här är ett sökbart index. Skriv sökord:</translation> +<translation id="5650795167354946011">Klicka här för att uppdatera när du har installerat plugin-programmet</translation> <translation id="6845533974506654842">tryck</translation> <translation id="8244226242650769279">bildkarta</translation> -<translation id="1383141426028388991">Det gick inte att installera plugin-program från <ph name="URL"/></translation> <translation id="2548326553472216322">Inga nya sökningar</translation> <translation id="5944544982112848342">2048 (hög)</translation> <translation id="3040011195152428237">länk</translation> -<translation id="8281246460978372009">Klicka här för att uppdatera när du har installerat plugin-programmet</translation> +<translation id="2745343197843472802">Hämta plugin-program</translation> +<translation id="5776402066334188252">Bekräfta att du vill installera detta plugin-program. Installera bara plugin-program från tillförlitliga källor.</translation> +<translation id="4003986561708175844">Det begärda plugin-programmet har inte installerats</translation> +<translation id="3018094406922859308">Hämtar plugin-programmet...</translation> <translation id="7364796246159120393">Välj fil</translation> <translation id="8964020114565522021">Dra filen hit</translation> <translation id="838869780401515933">kryssa för</translation> <translation id="2846343701378493991">1024 (medel)</translation> <translation id="5476505524087279545">kryssa av</translation> -<translation id="679352192834563463">Det finns inget plugin-program för att visa det här innehållet</translation> <translation id="3789841737615482174">Installera</translation> +<translation id="5253117816378681419">Bekräfta att du vill installera plugin-programmet <ph name="PLUGIN"/>. Installera bara plugin-program från tillförlitliga källor.</translation> <translation id="6663448176199120256">Senaste sökningar</translation> -<translation id="3600343118165084788">Klicka här för att ladda ned plugin-program</translation> +<translation id="2597378329261239068">Dokumentet är lösenordsskyddat. Ange ett lösenord.</translation> <translation id="6807599807928161586">webbområde</translation> <translation id="5939518447894949180">Återställ</translation> -<translation id="3771786644471114952">Hämta plugin-program</translation> <translation id="1842960171412779397">välj</translation> +<translation id="7638452146404718955">Klicka här för att hämta plugin-programmet</translation> <translation id="6119846243427417423">aktivera</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> filer</translation> -<translation id="3926627843712816530">Bekräfta att du vill installera det här plugin-programmet. Installera bara tillförlitliga plugin-program.</translation> -<translation id="4838490908464673667">De begärda plugin-programmen har inte installerats</translation> +<translation id="4470547978413275879">Plugin-programmet <ph name="PLUGIN"/> har inte installerats</translation> +<translation id="6765711848403622008">Det finns inget plugin-program för att visa det här innehållet</translation> <translation id="8597182159515967513">rubrik</translation> <translation id="2653659639078652383">Skicka</translation> +<translation id="8475551193147984329">Plugin-programmet <ph name="PLUGIN"/> krävs</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_sw.xtb b/webkit/glue/resources/webkit_strings_sw.xtb index 9d798d8..e507aa6 100644 --- a/webkit/glue/resources/webkit_strings_sw.xtb +++ b/webkit/glue/resources/webkit_strings_sw.xtb @@ -1,43 +1,30 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="sw"> -<translation id="4420062214988137980">Usanidi wa programu-jalizi haukufaulu</translation> <translation id="1235745349614807883">Futa Utafutaji wa Hivi Karibuni</translation> -<translation id="3825324228893189080">Programu-jalizi inahitajika</translation> -<translation id="2965480764085142436">Programu-jalizi <ph name="PLUGIN"/> haijasanidiwa</translation> <translation id="5048533449481078685">kialamishi orodha</translation> <translation id="4202807286478387388">ruka</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Tafadali thibitisha kuwa ungependa kusanidi programu-jalizi <ph name="PLUGIN"/>. Unastahili kusanidi progrmau-jalizi unazoamini pekee.</translation> <translation id="7658239707568436148">Ghairi</translation> -<translation id="795667975304826397">Hakuna faili iliyochaguliwa</translation> -<translation id="1275511093094545429">Programu-jalizi <ph name="PLUGIN"/> inahitajika</translation> -<translation id="8662565117025751661">Programu-jalizi inapakuliwa</translation> +<translation id="795667975304826397">Hakuna faili lililochaguliwa</translation> <translation id="8141602879876242471">Hii ni fahirisi inayoweza kutafutwa. Weka maneno muhimu ya utafutaji.</translation> <translation id="6845533974506654842">bofya</translation> <translation id="8244226242650769279">ramani ya picha</translation> -<translation id="1383141426028388991">Imeshindwa kusanidi programu-jalizi kutoka <ph name="URL"/></translation> <translation id="2548326553472216322">Hakuna utafutaji wa hivi karibuni</translation> <translation id="5944544982112848342">2048 (Gredi ya Juu)</translation> <translation id="3040011195152428237">kiungo</translation> -<translation id="8281246460978372009">Baada ya kusakinisha programu-jalizi, bonyeza hapa kuonyesha upya</translation> <translation id="7364796246159120393">Chagua Faili</translation> <translation id="8964020114565522021">Vuta faili hapa</translation> <translation id="838869780401515933">chunguza</translation> <translation id="2846343701378493991">1024 (Gredi Wastani)</translation> <translation id="5476505524087279545">toa tiki</translation> -<translation id="679352192834563463">Hakuna programu-jalizi ya kuonyesha maudhui haya</translation> -<translation id="3789841737615482174">Sanidi</translation> +<translation id="3789841737615482174">Sakinisha</translation> <translation id="6663448176199120256">Utafutaji wa hivi karibuni</translation> -<translation id="3600343118165084788">Bofya hapa kupakua programu-jalizi</translation> <translation id="6807599807928161586">eneo wavuti</translation> <translation id="5939518447894949180">Weka upya</translation> -<translation id="3771786644471114952">Pata programu-jalizi</translation> <translation id="1842960171412779397">chagua</translation> <translation id="6119846243427417423">wezesha</translation> <translation id="8444882422881193423">faili <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Tafadali thibitisha kuwa ungependa kusanidi programu-jalizi hii. Unastahili kusanidi progrmau-jalizi unazoamini pekee.</translation> -<translation id="4838490908464673667">Programu-jalizi inayohitajika haijasanidiwa</translation> <translation id="8597182159515967513">kichwa</translation> <translation id="2653659639078652383">Wasilisha</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_ta.xtb b/webkit/glue/resources/webkit_strings_ta.xtb index 3b19b4c..47d8547 100644 --- a/webkit/glue/resources/webkit_strings_ta.xtb +++ b/webkit/glue/resources/webkit_strings_ta.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ta"> -<translation id="4420062214988137980">செருகுநிரல் நிறுவல் தோல்வியடைந்தது</translation> +<translation id="4519964825805946997"><ph name="URL"/> இலிருந்து செருகுநிரலை நிறுவுதல் தோல்வியடைந்தது</translation> <translation id="1235745349614807883">சமீபத்திய தேடல்களை சுத்தமாக்கு</translation> -<translation id="3825324228893189080">கூடுதல் செருகுநிரல் தேவைப்படுகிறது</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> செருகுநிரல் நிறுவப்படவில்லை</translation> <translation id="5048533449481078685">பட்டியல் குறிப்பான்</translation> +<translation id="372362261556059955">கூடுதல் செருகுநிரல் தேவைப்படுகிறது</translation> <translation id="4202807286478387388">தாவு</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143"><ph name="PLUGIN"/> செருகுநிரலை நிறுவ விரும்புகிறீர்கள் என்பதை உறுதிப்படுத்துக. நீங்கள் நம்பும் செருகுநிரல்களை மட்டுமே நிறுவ வேண்டும்.</translation> <translation id="7658239707568436148">ரத்துசெய்</translation> <translation id="795667975304826397">எந்த கோப்பும் தேர்ந்தெடுக்கப்டவில்லை</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> செருகுநிரல் தேவைப்படுகிறது</translation> -<translation id="8662565117025751661">செருகுநிரலைப் பதிவிறக்குகிறது...</translation> +<translation id="1416462845279468967">செருகுநிரலை நிறுவுதல் தோல்வியடைந்தது</translation> <translation id="8141602879876242471">இது தேடக்கூடிய பொருளடக்கம். தேடல் சொற்களை உள்ளிடுக:</translation> +<translation id="5650795167354946011">செருகுநிரலை நிறுவிய பின்பு புதுப்பிக்க இங்கு கிளிக்செய்க</translation> <translation id="6845533974506654842">அழுத்துக</translation> <translation id="8244226242650769279">பட மேப்</translation> -<translation id="1383141426028388991"><ph name="URL"/> இலிருந்து செருகுநிரலை நிறுவுவதில் தோல்வியடைந்தது</translation> <translation id="2548326553472216322">சமீபத்திய தேடல்கள் எதுவுமில்லை</translation> <translation id="5944544982112848342">2048 (உயர் தரம்)</translation> <translation id="3040011195152428237">இணைப்பு</translation> -<translation id="8281246460978372009">செருகுநிரலை நிறுவிய பின், புதுப்பிக்க இங்கு கிளிக் செய்க</translation> +<translation id="2745343197843472802">செருகுநிரலைப் பெறு</translation> +<translation id="5776402066334188252">இந்த செருகுநிரலை நீங்கள் நிறுவ விரும்புகிறீர்கள் என்பதை தயவுசெய்து உறுதிசெய்க. நீங்கள் நம்பும் செருகுநிரல்களை மட்டும் நீங்கள் நிறுவ வேண்டும்.</translation> +<translation id="4003986561708175844">தேவையான செருகுநிரல் நிறுவப்படவில்லை</translation> +<translation id="3018094406922859308">செருகுநிரலைப் பதிவிறக்குகிறது...</translation> <translation id="7364796246159120393">கோப்பைத் தேர்வு செய்க</translation> <translation id="8964020114565522021">கோப்பை இங்கே இழுத்து வருக</translation> <translation id="838869780401515933">சரிபார்</translation> <translation id="2846343701378493991">1024 (இடைநிலைத் தரம்)</translation> <translation id="5476505524087279545">தேர்வு நீக்கு</translation> -<translation id="679352192834563463">இந்த உள்ளடக்கத்தைக் காண்பிப்பதற்கான செருகுநிரல் கிடைக்கவில்லை</translation> <translation id="3789841737615482174">நிறுவு</translation> +<translation id="5253117816378681419"><ph name="PLUGIN"/> செருகுநிரலை நிறுவ நீங்கள் விரும்புகிறீர்கள் என்பதை தயவுசெய்து உறுதிசெய்க. நீங்கள் நம்பும் செருகுநிரல்களை மட்டும் நிறுவ வேண்டும்.</translation> <translation id="6663448176199120256">சமீபத்திய தேடல்கள்</translation> -<translation id="3600343118165084788">செருகுநிரலைப் பதிவிறக்க இங்கே கிளிக் செய்க</translation> +<translation id="2597378329261239068">இந்த ஆவணம் கடவுச்சொல் பாதுகாக்கப்பட்ட ஒன்று. தயவுசெய்து ஒரு கடவுச்சொல்லை உள்ளிடுக.</translation> <translation id="6807599807928161586">வலைப் பகுதி</translation> <translation id="5939518447894949180">மீட்டமை</translation> -<translation id="3771786644471114952">செருகுநிரலைப் பெறுக</translation> <translation id="1842960171412779397">தேர்ந்தெடு</translation> +<translation id="7638452146404718955">செருகுநிரலைப் பதிவிறக்க இங்கே கிளிக் செய்க</translation> <translation id="6119846243427417423">செயல்படுத்து</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> கோப்புகள்</translation> -<translation id="3926627843712816530">இந்த செருகுநிரலை நிறுவ விரும்புகிறீர்கள் என்பதை உறுதிப்படுத்துக. நீங்கள் நம்பும் செருகுநிரல்களை மட்டுமே நிறுவ வேண்டும்.</translation> -<translation id="4838490908464673667">தேவையான செருகுநிரல் நிறுவப்படவில்லை</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> செருகுநிரல் நிறுவப்படவில்லை</translation> +<translation id="6765711848403622008">இந்த உள்ளடக்கத்தைக் காண்பிப்பதற்கான செருகுநிரல் கிடைக்கவில்லை</translation> <translation id="8597182159515967513">தலைப்பு</translation> <translation id="2653659639078652383">சமர்ப்பி</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> செருகுநிரல் தேவை</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_te.xtb b/webkit/glue/resources/webkit_strings_te.xtb index 37e3265..3c1e875 100644 --- a/webkit/glue/resources/webkit_strings_te.xtb +++ b/webkit/glue/resources/webkit_strings_te.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="te"> -<translation id="4420062214988137980">ప్లగ్ ఇన్ ఇన్స్టాలేషన్ విఫలమయ్యింది</translation> +<translation id="4519964825805946997"><ph name="URL"/> నుండి ప్లగ్-ఇన్ను వ్యవస్థాపించడానికి విఫలమైంది</translation> <translation id="1235745349614807883">ఇటీవల శోధనలను క్లియర్ చెయ్యి</translation> -<translation id="3825324228893189080">అదనపు ప్లగ్ఇన్ అవసరం</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> ప్లగ్ఇన్ ఇన్స్టాల్ అవ్వలేదు</translation> <translation id="5048533449481078685">జాబితా మార్కర్</translation> +<translation id="372362261556059955">అదనపు ప్లగ్-ఇన్ అవసరం</translation> <translation id="4202807286478387388">వెళ్ళు</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">దయచేసి <ph name="PLUGIN"/> ప్లగ్ఇన్ను ఇన్స్టాల్ చెయ్యాలనుకుంటునట్లు నిర్ధారించండి. మీరు నమ్మే ప్లగ్ఇన్లను మాత్రమే మీరు ఇన్స్టాల్ చెయ్యాలి.</translation> <translation id="7658239707568436148">రద్దు చెయ్యి</translation> <translation id="795667975304826397">ఫైల్ ఏదీ ఎంచుకోలేదు</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> ప్లగ్ఇన్ అవసరం</translation> -<translation id="8662565117025751661">ప్లగిన్ను డౌన్లోడ్ చేస్తోంది...</translation> +<translation id="1416462845279468967">ప్లగ్-ఇన్ వ్యవస్థాపన విఫలమైంది</translation> <translation id="8141602879876242471">ఇది ఒక శోధించగల సూచిక. శోధన కీవర్డ్లను ఎంటర్ చెయ్యండి:</translation> +<translation id="5650795167354946011">ప్లగ్-ఇన్ను వ్యవస్థాపించిన తర్వాత, రిఫ్రెష్ చెయ్యడానికి ఇక్కడ క్లిక్ చెయ్యండి.</translation> <translation id="6845533974506654842">నొక్కండి</translation> <translation id="8244226242650769279">చిత్రం మాప్</translation> -<translation id="1383141426028388991"><ph name="URL"/> నుండి ప్లగ్ఇన్ను ఇన్స్టాల్ చెయ్యడంలో విఫలమైంది</translation> <translation id="2548326553472216322">ఇటీవల శోధనలు లేవు</translation> <translation id="5944544982112848342">2048 (ఉత్తమ గ్రేడ్)</translation> <translation id="3040011195152428237">లింక్</translation> -<translation id="8281246460978372009">ప్లగ్ఇన్ను ఇన్స్టాల్ చేసిన తర్వాత, రిఫ్రెష్ చెయ్యడానికి ఇక్కడ క్లిక్ చెయ్యండి.</translation> +<translation id="2745343197843472802">ప్లగ్-ఇన్ను పొందండి</translation> +<translation id="5776402066334188252">దయచేసి మీరు ఈ ప్లగ్-ఇన్ను వ్యవస్థాపించాలని అనుకుంటున్నట్లు నిర్ధారించండి. మీరు నమ్మేటటువంటి ప్లగ్-ఇన్లను మాత్రమే మీరు వ్యవస్థాపించాలి.</translation> +<translation id="4003986561708175844">అవసరమైన ప్లగ్-ఇన్ వ్యవస్థాపించబడలేదు</translation> +<translation id="3018094406922859308">ప్లగ్-ఇన్ను డౌన్లోడ్ చేస్తోంది...</translation> <translation id="7364796246159120393">ఫైల్ను ఎంచుకోండి</translation> <translation id="8964020114565522021">ఫైల్ను ఇక్కడకు లాగండి</translation> <translation id="838869780401515933">తనిఖీ చెయ్యి</translation> <translation id="2846343701378493991">1024 (మధ్యస్థ గ్రేడ్)</translation> <translation id="5476505524087279545">ఎంపిక చెయ్యబడలేదు</translation> -<translation id="679352192834563463">ఈ కంటెంట్ను ప్రదర్శించడానికి ఏ ప్లగ్ఇన్ అందుబాటులో లేదు</translation> <translation id="3789841737615482174">ఇన్స్టాల్ చెయ్యి</translation> +<translation id="5253117816378681419">దయచేసి మీరు <ph name="PLUGIN"/> ప్లగ్-ఇన్ను వ్యవస్థాపించాలనుకుంటున్నారని నిర్థారించండి. మీరు విశ్వసించే ప్లగ్-ఇన్లను మాత్రమే వ్యవస్థాపించాలి.</translation> <translation id="6663448176199120256">ఇటీవల శోధనలు</translation> -<translation id="3600343118165084788">ప్లగ్ఇన్ను దిగుమతి చెయ్యడానికి ఇక్కడ క్లిక్ చెయ్యండి</translation> +<translation id="2597378329261239068">ఈ పత్రం అనుమతి పదంచే రక్షించబడింది. దయచేసి అనుమతి పదాన్ని నమోదు చేయండి.</translation> <translation id="6807599807928161586">వెబ్ ప్రాంతం</translation> <translation id="5939518447894949180">తిరిగి అమర్చండి</translation> -<translation id="3771786644471114952">ప్లగ్ఇన్ను పొందండి</translation> <translation id="1842960171412779397">ఎంచుకోండి</translation> +<translation id="7638452146404718955">ప్లగ్-ఇన్ను డౌన్లోడ్ చేయడానికి ఇక్కడ క్లిక్ చేయండి</translation> <translation id="6119846243427417423">ఆక్టివేట్ చెయ్యి</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ఫైళ్ళు</translation> -<translation id="3926627843712816530">దయచేసి ఈ ప్లగ్ ఇన్ను ఇన్స్టాల్ చెయ్యాలనుకుంటునట్లు నిర్ధారించండి. మీరు నమ్మే ప్లగ్ఇన్లను మాత్రమే మీరు ఇన్స్టాల్ చెయ్యాలి.</translation> -<translation id="4838490908464673667">అవసరమైన ప్లగిన్ ఇన్స్టాల్ చెయ్యబడలేదు</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> ప్లగ్-ఇన్ వ్యవస్థాపించబడలేదు</translation> +<translation id="6765711848403622008">ఈ కంటెంట్ను ప్రదర్శించడానికి ఏ ప్లగ్-ఇన్ అందుబాటులో లేదు</translation> <translation id="8597182159515967513">శీర్షిక</translation> <translation id="2653659639078652383">సమర్పించు</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> ప్లగ్-ఇన్ అవసరం</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_th.xtb b/webkit/glue/resources/webkit_strings_th.xtb index a6c8b4b..80dd787 100644 --- a/webkit/glue/resources/webkit_strings_th.xtb +++ b/webkit/glue/resources/webkit_strings_th.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="th"> -<translation id="4420062214988137980">การติดตั้งปลั๊กอินล้มเหลว</translation> +<translation id="4519964825805946997">การติดตั้งปลั๊กอินจาก <ph name="URL"/> ล้มเหลว</translation> <translation id="1235745349614807883">ลบการค้นหาล่าสุด</translation> -<translation id="3825324228893189080">ต้องการปลั๊กอินเพิ่มเติม</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> ไม่ได้ติดตั้งปลั๊กอิน</translation> <translation id="5048533449481078685">ผู้สร้างรายการ</translation> +<translation id="372362261556059955">ต้องการปลั๊กอินเพิ่มเติม</translation> <translation id="4202807286478387388">ข้าม</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">โปรดยืนยันว่าคุณต้องการที่จะติดตั้ง <ph name="PLUGIN"/> ปลั๊กอิน คุณควรติดตั้งปลั๊กอินที่คุณเชื่อถือเท่านั้น</translation> <translation id="7658239707568436148">ยกเลิก</translation> <translation id="795667975304826397">ไม่ได้เลือกไฟล์ใด</translation> -<translation id="1275511093094545429">ต้องใช้ปลั๊กอิน <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">กำลังดาวน์โหลดปลั๊กอิน...</translation> +<translation id="1416462845279468967">การติดตั้งปลั๊กอินล้มเหลว</translation> <translation id="8141602879876242471">นี่คือดัชนีที่สามารถค้นหาได้ ป้อนคำหลักในการค้นหา:</translation> +<translation id="5650795167354946011">หลังจากติดตั้งปลั๊กอิน ให้คลิกที่นี่เพื่อรีเฟรช</translation> <translation id="6845533974506654842">กด</translation> <translation id="8244226242650769279">แผนที่รูปภาพ</translation> -<translation id="1383141426028388991">การติดตั้งปลั๊กอินจาก <ph name="URL"/> ล้มเหลว</translation> <translation id="2548326553472216322">ไม่พบการค้นหาล่าสุด</translation> <translation id="5944544982112848342">2048 (เกรดสูง)</translation> <translation id="3040011195152428237">ลิงก์</translation> -<translation id="8281246460978372009">หลังจากติดตั้งปลั๊กอิน คลิกที่นี่เพื่อรีเฟรซ</translation> +<translation id="2745343197843472802">รับปลั๊กอิน</translation> +<translation id="5776402066334188252">โปรดยืนยันว่าคุณต้องการติดตั้งปลั๊กอินนี้ คุณควรติดตั้งเฉพาะปลั๊กอินที่คุณไว้ใจเท่านั้น </translation> +<translation id="4003986561708175844">ไม่ได้ติดตั้งปลั๊กอินที่จำเป็น</translation> +<translation id="3018094406922859308">กำลังดาวน์โหลดปลั๊กอิน...</translation> <translation id="7364796246159120393">เลือกไฟล์</translation> <translation id="8964020114565522021">ลากไฟล์มาที่นี่</translation> <translation id="838869780401515933">ทำเครื่องหมาย</translation> <translation id="2846343701378493991">1024 (เกรดปานกลาง)</translation> <translation id="5476505524087279545">ยกเลิกการทำเครื่องหมาย</translation> -<translation id="679352192834563463">ไม่มีปลั๊กอินที่จะแสดงเนื้อหานี้</translation> <translation id="3789841737615482174">ติดตั้ง</translation> +<translation id="5253117816378681419">โปรดยืนยันว่าคุณต้องการติดตั้งปลั๊กอิน <ph name="PLUGIN"/> คุณควรติดตั้งเฉพาะปลั๊กอินที่คุณไว้ใจเท่านั้น</translation> <translation id="6663448176199120256">การค้นหาล่าสุด</translation> -<translation id="3600343118165084788">คลิกที่นี่เพื่อดาวน์โหลดปลั๊กอิน</translation> +<translation id="2597378329261239068">เอกสารนี้ได้รับการป้องกันด้วยรหัสผ่าน โปรดป้อนรหัสผ่าน</translation> <translation id="6807599807928161586">พื้นที่เว็บ</translation> <translation id="5939518447894949180">ตั้งค่าใหม่</translation> -<translation id="3771786644471114952">ติดตั้งปลั๊กอิน</translation> <translation id="1842960171412779397">เลือก</translation> +<translation id="7638452146404718955">คลิกที่นี่เพื่อดาวน์โหลดปลั๊กอิน</translation> <translation id="6119846243427417423">เปิดใช้งาน</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> ไฟล์</translation> -<translation id="3926627843712816530">โปรดยืนยันว่าคุณต้องการติดตั้งปลั๊กอินนี้ คุณควรติดตั้งปลั๊กอินที่คุณเชื่อถือเท่านั้น</translation> -<translation id="4838490908464673667">ไม่ได้ติดตั้งปลั๊กอินที่จำเป็น</translation> +<translation id="4470547978413275879">ไม่ได้ติดตั้งปลั๊กอิน <ph name="PLUGIN"/></translation> +<translation id="6765711848403622008">ไม่มีปลั๊กอินที่จะแสดงเนื้อหานี้</translation> <translation id="8597182159515967513">ส่วนหัว</translation> <translation id="2653659639078652383">ส่ง</translation> +<translation id="8475551193147984329">ต้องการปลั๊กอิน <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_tr.xtb b/webkit/glue/resources/webkit_strings_tr.xtb index 1f5571a..a4d880d 100644 --- a/webkit/glue/resources/webkit_strings_tr.xtb +++ b/webkit/glue/resources/webkit_strings_tr.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="tr"> -<translation id="4420062214988137980">Eklenti kurulumu başarısız oldu</translation> +<translation id="4519964825805946997">Eklenti, <ph name="URL"/> kaynağından yüklenemedi</translation> <translation id="1235745349614807883">Son Aramaları Temizle</translation> -<translation id="3825324228893189080">Ek eklenti gerekiyor</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> eklentisi yüklü değil</translation> <translation id="5048533449481078685">liste işaretçisi</translation> +<translation id="372362261556059955">Başka eklenti gerekiyor</translation> <translation id="4202807286478387388">git</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Lütfen <ph name="PLUGIN"/> eklentisini yüklemek istediğinizi onaylayın. Yalnızca güvendiğiniz eklentileri yüklemelisiniz.</translation> <translation id="7658239707568436148">İptal</translation> <translation id="795667975304826397">Dosya seçilmedi</translation> -<translation id="1275511093094545429"><ph name="PLUGIN"/> eklentisi gerekiyor</translation> -<translation id="8662565117025751661">Eklenti indiriliyor...</translation> +<translation id="1416462845279468967">Eklenti yüklenemedi</translation> <translation id="8141602879876242471">Bu dizinde arama yapılabilir. Arama anahtar kelimeleri girin:</translation> +<translation id="5650795167354946011">Eklentiyi yükledikten sonra yenilemek için burayı tıklayın</translation> <translation id="6845533974506654842">bas</translation> <translation id="8244226242650769279">resim haritası</translation> -<translation id="1383141426028388991">Eklenti, <ph name="URL"/> kaynağından yüklenemedi</translation> <translation id="2548326553472216322">Yeni arama yok</translation> <translation id="5944544982112848342">2048 (Yüksek Düzey)</translation> <translation id="3040011195152428237">bağlantı</translation> -<translation id="8281246460978372009">Eklentiyi yükledikten sonra yenilemek için burayı tıklayın</translation> +<translation id="2745343197843472802">Eklentiyi edinin</translation> +<translation id="5776402066334188252">Lütfen bu eklentiyi yüklemek istediğinizi onaylayın. Yalnızca güvendiğiniz eklentileri yüklemelisiniz.</translation> +<translation id="4003986561708175844">Gereken eklenti yüklü değil</translation> +<translation id="3018094406922859308">Eklenti indiriliyor...</translation> <translation id="7364796246159120393">Dosya Seç</translation> <translation id="8964020114565522021">Dosyayı buraya sürükleyin</translation> <translation id="838869780401515933">işaretle</translation> <translation id="2846343701378493991">1024 (Orta Düzey)</translation> <translation id="5476505524087279545">işareti kaldır</translation> -<translation id="679352192834563463">Bu içeriği görüntüleyecek eklenti yok</translation> <translation id="3789841737615482174">Yükle</translation> +<translation id="5253117816378681419">Lütfen <ph name="PLUGIN"/> eklentisini yüklemek istediğinizi onaylayın. Yalnızca güvendiğiniz eklentileri yüklemelisiniz.</translation> <translation id="6663448176199120256">Son Aramalar</translation> -<translation id="3600343118165084788">Eklentiyi indirmek için burayı tıklayın</translation> +<translation id="2597378329261239068">Doküman şifre korumalı. Lütfen şifreyi girin.</translation> <translation id="6807599807928161586">web alanı</translation> <translation id="5939518447894949180">Sıfırla</translation> -<translation id="3771786644471114952">Eklenti Al</translation> <translation id="1842960171412779397">seç</translation> +<translation id="7638452146404718955">Eklentiyi indirmek için burayı tıklayın</translation> <translation id="6119846243427417423">etkinleştir</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> dosya</translation> -<translation id="3926627843712816530">Lütfen bu eklentiyi yüklemek istediğinizi onaylayın. Yalnızca güvendiğiniz eklentileri yüklemelisiniz.</translation> -<translation id="4838490908464673667">Gereken eklenti yüklü değil</translation> +<translation id="4470547978413275879"><ph name="PLUGIN"/> eklentisi yüklü değil</translation> +<translation id="6765711848403622008">Bu içeriği görüntüleyecek hiçbir eklenti yok</translation> <translation id="8597182159515967513">başlık</translation> <translation id="2653659639078652383">Gönder</translation> +<translation id="8475551193147984329"><ph name="PLUGIN"/> eklentisi gerekiyor</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_uk.xtb b/webkit/glue/resources/webkit_strings_uk.xtb index ae193fe..a125fe2 100644 --- a/webkit/glue/resources/webkit_strings_uk.xtb +++ b/webkit/glue/resources/webkit_strings_uk.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="uk"> -<translation id="4420062214988137980">Не вдалось інсталювати модуль</translation> +<translation id="4519964825805946997">Не вдалося встановити плагін із <ph name="URL"/></translation> <translation id="1235745349614807883">Очистити останні пошуки</translation> -<translation id="3825324228893189080">Потрібен додатковий модуль.</translation> -<translation id="2965480764085142436">Модуль <ph name="PLUGIN"/> не інстальовано</translation> <translation id="5048533449481078685">маркер списку</translation> +<translation id="372362261556059955">Потрібен додатковий плагін.</translation> <translation id="4202807286478387388">перейти</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Підтвердьте інсталяцію модуля <ph name="PLUGIN"/>. Слід інсталювати лише модулі, які вважаєте надійними.</translation> <translation id="7658239707568436148">Скасувати</translation> <translation id="795667975304826397">Файл не вибрано</translation> -<translation id="1275511093094545429">Потрібен модуль <ph name="PLUGIN"/></translation> -<translation id="8662565117025751661">Завантаження модуля...</translation> +<translation id="1416462845279468967">Помилка встановлення плагіна</translation> <translation id="8141602879876242471">Цей доступний для пошуку індекс. Введіть ключові слова пошуку:</translation> +<translation id="5650795167354946011">Після встановлення плагіна натисніть тут, щоб оновити</translation> <translation id="6845533974506654842">натиснути</translation> <translation id="8244226242650769279">мапа зображення</translation> -<translation id="1383141426028388991">Не вдалося встановити модуль із <ph name="URL"/></translation> <translation id="2548326553472216322">Немає останніх пошуків</translation> <translation id="5944544982112848342">2048 (Високий рівень)</translation> <translation id="3040011195152428237">посилання</translation> -<translation id="8281246460978372009">Після інсталяції модуля натисніть тут, щоб оновити</translation> +<translation id="2745343197843472802">Отримати плагін</translation> +<translation id="5776402066334188252">Підтвердьте встановлення цього плагіна. Слід установлювати лише плагіни, яким ви довіряєте.</translation> +<translation id="4003986561708175844">Потрібний плагін не встановлено</translation> +<translation id="3018094406922859308">Завантаження плагіна...</translation> <translation id="7364796246159120393">Вибрати файл</translation> <translation id="8964020114565522021">Перетягніть файл сюди</translation> <translation id="838869780401515933">установити прапорець</translation> <translation id="2846343701378493991">1024 (Середній рівень)</translation> <translation id="5476505524087279545">зняти прапорець</translation> -<translation id="679352192834563463">Немає доступного модуля для відображення цього вмісту</translation> <translation id="3789841737615482174">Інсталювати</translation> +<translation id="5253117816378681419">Підтвердьте встановлення плагіна <ph name="PLUGIN"/>. Слід установлювати лише плагіни, яким ви довіряєте.</translation> <translation id="6663448176199120256">Останні пошуки</translation> -<translation id="3600343118165084788">Натисніть тут, щоб завантажити модуль</translation> +<translation id="2597378329261239068">Цей документ захищено паролем. Введіть пароль.</translation> <translation id="6807599807928161586">область Інтернету</translation> <translation id="5939518447894949180">Скинути</translation> -<translation id="3771786644471114952">Отримати модуль</translation> <translation id="1842960171412779397">вибрати</translation> +<translation id="7638452146404718955">Натисніть тут, щоб завантажити плагін</translation> <translation id="6119846243427417423">активувати</translation> <translation id="8444882422881193423">файлів: <ph name="NUMBER_OF_FILES"/></translation> -<translation id="3926627843712816530">Підтвердьте інсталяцію цього модуля. Слід інсталювати лише модулі, які вважаєте надійними.</translation> -<translation id="4838490908464673667">Потрібний модуль не інстальовано</translation> +<translation id="4470547978413275879">Плагін <ph name="PLUGIN"/> не встановлено</translation> +<translation id="6765711848403622008">Немає доступного плагіна для відображення цього вмісту</translation> <translation id="8597182159515967513">заголовок</translation> <translation id="2653659639078652383">Надіслати</translation> +<translation id="8475551193147984329">Потрібен плагін <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_vi.xtb b/webkit/glue/resources/webkit_strings_vi.xtb index 9e3f498..84668c5 100644 --- a/webkit/glue/resources/webkit_strings_vi.xtb +++ b/webkit/glue/resources/webkit_strings_vi.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="vi"> -<translation id="4420062214988137980">Không cài đặt plugin được</translation> +<translation id="4519964825805946997">Cài đặt trình cắm từ <ph name="URL"/> không thành công</translation> <translation id="1235745349614807883">Xoá Tìm kiếm Gần đây</translation> -<translation id="3825324228893189080">Cần plugin bổ sung</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> plgin không được cài đặt</translation> <translation id="5048533449481078685">đánh dấu danh sách</translation> +<translation id="372362261556059955">Cần trình cắm bổ sung</translation> <translation id="4202807286478387388">chuyển</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">Vui lòng xác nhận rằng bạn muốn cài đặt plugin <ph name="PLUGIN"/>. Bạn chỉ nên cài đặt plugin mà mình tin cậy.</translation> <translation id="7658239707568436148">Huỷ</translation> <translation id="795667975304826397">Không có tệp nào được chọn</translation> -<translation id="1275511093094545429">Cần <ph name="PLUGIN"/> plugin</translation> -<translation id="8662565117025751661">Đang tải xuống plugin...</translation> +<translation id="1416462845279468967">Cài đặt trình cắm không thành công</translation> <translation id="8141602879876242471">Đây là chỉ mục có thể tìm kiếm. Nhập từ khoá tìm kiếm vào:</translation> +<translation id="5650795167354946011">Sau khi cài đặt trình cắm, hãy nhấp vào đây để làm mới</translation> <translation id="6845533974506654842">nhấn</translation> <translation id="8244226242650769279">bản đồ hình ảnh</translation> -<translation id="1383141426028388991">Không cài đặt được plugin từ <ph name="URL"/></translation> <translation id="2548326553472216322">Không có tìm kiếm nào gần đây</translation> <translation id="5944544982112848342">2048 (Cấp độ cao)</translation> <translation id="3040011195152428237">liên kết</translation> -<translation id="8281246460978372009">Sau khi cài đặt plugin, nhấp vào đây để làm mới</translation> +<translation id="2745343197843472802">Tải Trình cắm</translation> +<translation id="5776402066334188252">Vui lòng xác nhận rằng bạn muốn cài đặt trình cắm này. Bạn chỉ nên cài đặt trình cắm mà bạn tin tưởng.</translation> +<translation id="4003986561708175844">Trình cắm được yêu cầu chưa được cài đặt</translation> +<translation id="3018094406922859308">Đang tải xuống trình cắm...</translation> <translation id="7364796246159120393">Chọn Tệp tin</translation> <translation id="8964020114565522021">Kéo tệp tại đây</translation> <translation id="838869780401515933">chọn</translation> <translation id="2846343701378493991">1024 (Loại Trung bình)</translation> <translation id="5476505524087279545">bỏ chọn</translation> -<translation id="679352192834563463">Không plugin nào có sẵn để hiển thị nội dung này</translation> <translation id="3789841737615482174">Cài đặt</translation> +<translation id="5253117816378681419">Vui lòng xác nhận rằng bạn muốn cài đặt trình cắm <ph name="PLUGIN"/>. Bạn chỉ nên cài đặt những trình cắm mà bạn tin tưởng.</translation> <translation id="6663448176199120256">Tìm kiếm Gần đây</translation> -<translation id="3600343118165084788">Nhấp vào đây để tải plugin xuống</translation> +<translation id="2597378329261239068">Tài liệu này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu.</translation> <translation id="6807599807928161586">khu vực web</translation> <translation id="5939518447894949180">Đặt lại</translation> -<translation id="3771786644471114952">Tải Plugin</translation> <translation id="1842960171412779397">chọn</translation> +<translation id="7638452146404718955">Nhấp vào đây để tải xuống trình cắm</translation> <translation id="6119846243427417423">kích hoạt</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> tệp</translation> -<translation id="3926627843712816530">Hãy xác nhận rằng bạn muốn cài đặt plugin này. Bạn chỉ nên cài đặt plugin mà mình tin cậy.</translation> -<translation id="4838490908464673667">Plugin yêu cầu không được cài đặt</translation> +<translation id="4470547978413275879">Trình cắm <ph name="PLUGIN"/> chưa được cài đặt</translation> +<translation id="6765711848403622008">Không có trình cắm nào để hiển thị nội dung này</translation> <translation id="8597182159515967513">đầu đề</translation> <translation id="2653659639078652383">Gửi</translation> +<translation id="8475551193147984329">Cần trình cắm <ph name="PLUGIN"/></translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_zh-CN.xtb b/webkit/glue/resources/webkit_strings_zh-CN.xtb index c2d8176..f5c0644 100644 --- a/webkit/glue/resources/webkit_strings_zh-CN.xtb +++ b/webkit/glue/resources/webkit_strings_zh-CN.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="zh-CN"> -<translation id="4420062214988137980">安装插件失败</translation> +<translation id="4519964825805946997">无法从 <ph name="URL"/> 安装插件</translation> <translation id="1235745349614807883">清除最近的搜索</translation> -<translation id="3825324228893189080">需要使用其他插件</translation> -<translation id="2965480764085142436">未安装 <ph name="PLUGIN"/> 插件</translation> <translation id="5048533449481078685">列表标记</translation> +<translation id="372362261556059955">需要其他插件</translation> <translation id="4202807286478387388">略过</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">请确认您要安装 <ph name="PLUGIN"/> 插件。您只能安装自己信任的插件。</translation> <translation id="7658239707568436148">取消</translation> <translation id="795667975304826397">未选择文件</translation> -<translation id="1275511093094545429">需要使用 <ph name="PLUGIN"/> 插件</translation> -<translation id="8662565117025751661">正在下载插件...</translation> +<translation id="1416462845279468967">插件安装失败</translation> <translation id="8141602879876242471">这是一个可搜索的索引。请输入搜索关键字:</translation> +<translation id="5650795167354946011">安装插件后,点击此处可刷新</translation> <translation id="6845533974506654842">按</translation> <translation id="8244226242650769279">图片映射</translation> -<translation id="1383141426028388991">无法从 <ph name="URL"/> 安装插件</translation> <translation id="2548326553472216322">最近未执行搜索</translation> <translation id="5944544982112848342">2048(高强度)</translation> <translation id="3040011195152428237">链接</translation> -<translation id="8281246460978372009">安装插件后,点击此处可刷新</translation> +<translation id="2745343197843472802">获取插件</translation> +<translation id="5776402066334188252">请确认您要安装此插件。您应该只安装自己信任的插件。</translation> +<translation id="4003986561708175844">未安装所需插件</translation> +<translation id="3018094406922859308">正在下载插件...</translation> <translation id="7364796246159120393">选择文件</translation> <translation id="8964020114565522021">将文件拖到此处</translation> <translation id="838869780401515933">选中</translation> <translation id="2846343701378493991">1024(中等强度)</translation> <translation id="5476505524087279545">取消选中</translation> -<translation id="679352192834563463">没有用于显示这种内容的插件</translation> <translation id="3789841737615482174">安装</translation> +<translation id="5253117816378681419">请确认您要安装 <ph name="PLUGIN"/> 插件。您应该只安装自己信任的插件。</translation> <translation id="6663448176199120256">近期搜索</translation> -<translation id="3600343118165084788">点击此处可下载插件</translation> +<translation id="2597378329261239068">本文档设置了密码保护,请输入密码。</translation> <translation id="6807599807928161586">网络区域</translation> <translation id="5939518447894949180">重置</translation> -<translation id="3771786644471114952">获取插件</translation> <translation id="1842960171412779397">选中</translation> +<translation id="7638452146404718955">点击此处可下载插件</translation> <translation id="6119846243427417423">激活</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> 个文件</translation> -<translation id="3926627843712816530">请确认您要安装此插件。您只能安装自己信任的插件。</translation> -<translation id="4838490908464673667">未安装所需插件</translation> +<translation id="4470547978413275879">未安装 <ph name="PLUGIN"/> 插件</translation> +<translation id="6765711848403622008">没有用于显示此内容的插件</translation> <translation id="8597182159515967513">标题</translation> <translation id="2653659639078652383">提交</translation> +<translation id="8475551193147984329">需要 <ph name="PLUGIN"/> 插件</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/resources/webkit_strings_zh-TW.xtb b/webkit/glue/resources/webkit_strings_zh-TW.xtb index 999207a..7d7eda3 100644 --- a/webkit/glue/resources/webkit_strings_zh-TW.xtb +++ b/webkit/glue/resources/webkit_strings_zh-TW.xtb @@ -1,43 +1,44 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="zh-TW"> -<translation id="4420062214988137980">外掛程式安裝失敗</translation> +<translation id="4519964825805946997">無法從 <ph name="URL"/> 安裝外掛程式</translation> <translation id="1235745349614807883">清除最近的搜尋記錄</translation> -<translation id="3825324228893189080">需要額外的外掛程式</translation> -<translation id="2965480764085142436"><ph name="PLUGIN"/> 外掛程式尚未安裝</translation> <translation id="5048533449481078685">清單標記</translation> +<translation id="372362261556059955">需要其他外掛程式</translation> <translation id="4202807286478387388">跳至另一頁</translation> <translation id="4611115858363067980"><ph name="FILENAME"/><ph name="WIDTH"/>×<ph name="HEIGHT"/></translation> -<translation id="4317653869502688143">請確定您想要安裝 <ph name="PLUGIN"/> 外掛程式。建議您僅安裝可靠的外掛程式。</translation> <translation id="7658239707568436148">取消</translation> <translation id="795667975304826397">未選擇檔案</translation> -<translation id="1275511093094545429">需要 <ph name="PLUGIN"/> 外掛程式</translation> -<translation id="8662565117025751661">正在下載外掛程式...</translation> +<translation id="1416462845279468967">外掛程式安裝不成功</translation> <translation id="8141602879876242471">這是可搜尋的索引,輸入搜尋關鍵字:</translation> +<translation id="5650795167354946011">安裝外掛程式後,請按一下這裡重新整理</translation> <translation id="6845533974506654842">按下</translation> <translation id="8244226242650769279">影像地圖</translation> -<translation id="1383141426028388991">無法從 <ph name="URL"/> 安裝外掛程式</translation> <translation id="2548326553472216322">沒有近期的搜尋</translation> <translation id="5944544982112848342">2048 (高級)</translation> <translation id="3040011195152428237">連結</translation> -<translation id="8281246460978372009">安裝外掛程式後,請按一下這裡更新</translation> +<translation id="2745343197843472802">取得外掛程式</translation> +<translation id="5776402066334188252">請確認您要安裝此外掛程式,建議您僅安裝您所信任的外掛程式。</translation> +<translation id="4003986561708175844">未安裝必要的外掛程式</translation> +<translation id="3018094406922859308">正在下載外掛程式...</translation> <translation id="7364796246159120393">選擇檔案</translation> <translation id="8964020114565522021">拖曳檔案至此</translation> <translation id="838869780401515933">選取</translation> <translation id="2846343701378493991">1024 (中等)</translation> <translation id="5476505524087279545">取消選取</translation> -<translation id="679352192834563463">沒有外掛程式可供顯示目前內容</translation> <translation id="3789841737615482174">安裝</translation> +<translation id="5253117816378681419">請確認您要安裝 <ph name="PLUGIN"/> 外掛程式,建議您僅安裝您所信任的外掛程式。</translation> <translation id="6663448176199120256">最近的搜尋</translation> -<translation id="3600343118165084788">按一下這裡以下載掛程式</translation> +<translation id="2597378329261239068">此文件受到密碼保護,請輸入密碼。</translation> <translation id="6807599807928161586">網頁範圍</translation> <translation id="5939518447894949180">重設</translation> -<translation id="3771786644471114952">取得外掛程式</translation> <translation id="1842960171412779397">選取</translation> +<translation id="7638452146404718955">按一下這裡下載外掛程式</translation> <translation id="6119846243427417423">啟動</translation> <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> 個檔案</translation> -<translation id="3926627843712816530">請確定您想要安裝此外掛程式。建議您僅安裝可靠的外掛程式。</translation> -<translation id="4838490908464673667">未安裝要求的外掛程式</translation> +<translation id="4470547978413275879">未安裝 <ph name="PLUGIN"/> 外掛程式</translation> +<translation id="6765711848403622008">沒有可以顯示此內容的外掛程式</translation> <translation id="8597182159515967513">標題</translation> <translation id="2653659639078652383">提交</translation> +<translation id="8475551193147984329">需要 <ph name="PLUGIN"/> 外掛程式</translation> </translationbundle>
\ No newline at end of file diff --git a/webkit/glue/simple_webmimeregistry_impl.cc b/webkit/glue/simple_webmimeregistry_impl.cc index 5dd227f..d878867 100644 --- a/webkit/glue/simple_webmimeregistry_impl.cc +++ b/webkit/glue/simple_webmimeregistry_impl.cc @@ -6,6 +6,7 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" +#include "base/utf_string_conversions.h" #include "net/base/mime_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" #include "webkit/glue/webkit_glue.h" diff --git a/webkit/glue/unittest_test_server.h b/webkit/glue/unittest_test_server.h index 0b3c7d2..575f0f9 100644 --- a/webkit/glue/unittest_test_server.h +++ b/webkit/glue/unittest_test_server.h @@ -5,61 +5,17 @@ #ifndef WEBKIT_GLUE_UNITTEST_TEST_SERVER_H__ #define WEBKIT_GLUE_UNITTEST_TEST_SERVER_H__ -#include "webkit/appcache/appcache_interfaces.h" -#include "webkit/glue/resource_loader_bridge.h" #include "net/base/load_flags.h" -#include "net/url_request/url_request_unittest.h" - -using webkit_glue::ResourceLoaderBridge; - -// We need to use ResourceLoaderBridge to communicate with the testserver -// instead of using URLRequest directly because URLRequests need to be run on -// the test_shell's IO thread. -class UnittestTestServer : public HTTPTestServer { - protected: - UnittestTestServer() { - } +#include "net/test/test_server.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/appcache/appcache_interfaces.h" +class UnittestTestServer : public net::TestServer { public: - static UnittestTestServer* CreateServer() { - UnittestTestServer* test_server = new UnittestTestServer(); - FilePath no_cert; - FilePath docroot(FILE_PATH_LITERAL("webkit/data")); - if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, - "localhost", 1337, docroot, no_cert, std::wstring())) { - delete test_server; - return NULL; - } - return test_server; + UnittestTestServer() + : net::TestServer(net::TestServer::TYPE_HTTP, + FilePath(FILE_PATH_LITERAL("webkit/data"))) { } - - virtual bool MakeGETRequest(const std::string& page_name) { - GURL url(TestServerPage(page_name)); - webkit_glue::ResourceLoaderBridge::RequestInfo request_info; - request_info.method = "GET"; - request_info.url = url; - request_info.first_party_for_cookies = url; - request_info.referrer = GURL(); // No referrer. - request_info.frame_origin = "null"; - request_info.main_frame_origin = "null"; - request_info.headers = std::string(); // No extra headers. - request_info.load_flags = net::LOAD_NORMAL; - request_info.requestor_pid = 0; - request_info.request_type = ResourceType::SUB_RESOURCE; - request_info.request_context = 0; - request_info.appcache_host_id = appcache::kNoHostId; - request_info.routing_id = 0; - scoped_ptr<ResourceLoaderBridge> loader( - ResourceLoaderBridge::Create(request_info)); - EXPECT_TRUE(loader.get()); - - ResourceLoaderBridge::SyncLoadResponse resp; - loader->SyncLoad(&resp); - return resp.status.is_success(); - } - - private: - virtual ~UnittestTestServer() {} }; #endif // WEBKIT_GLUE_UNITTEST_TEST_SERVER_H__ diff --git a/webkit/glue/user_agent.cc b/webkit/glue/user_agent.cc new file mode 100644 index 0000000..2babb49 --- /dev/null +++ b/webkit/glue/user_agent.cc @@ -0,0 +1,121 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/user_agent.h" + +#if defined(OS_POSIX) && !defined(OS_MACOSX) +#include <sys/utsname.h> +#endif + +#include "base/string_util.h" +#include "base/stringprintf.h" +#include "base/sys_info.h" + +// Generated +#include "webkit_version.h" // NOLINT + +namespace webkit_glue { + +// Forward declare GetProductVersionInfo. This is implemented in +// renderer_glue.cc as part of the renderer lib. +std::string GetProductVersion(); + +std::string GetWebKitVersion() { + return base::StringPrintf("%d.%d", WEBKIT_VERSION_MAJOR, + WEBKIT_VERSION_MINOR); +} + +std::string BuildOSCpuInfo() { + std::string os_cpu; + +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) + int32 os_major_version = 0; + int32 os_minor_version = 0; + int32 os_bugfix_version = 0; + base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, + &os_minor_version, + &os_bugfix_version); +#endif +#if defined(OS_POSIX) && !defined(OS_MACOSX) + // Should work on any Posix system. + struct utsname unixinfo; + uname(&unixinfo); + + std::string cputype; + // special case for biarch systems + if (strcmp(unixinfo.machine, "x86_64") == 0 && + sizeof(void*) == sizeof(int32)) { // NOLINT + cputype.assign("i686 (x86_64)"); + } else { + cputype.assign(unixinfo.machine); + } +#endif + + StringAppendF( + &os_cpu, +#if defined(OS_WIN) + "Windows NT %d.%d", + os_major_version, + os_minor_version +#elif defined(OS_MACOSX) + "Intel Mac OS X %d_%d_%d", + os_major_version, + os_minor_version, + os_bugfix_version +#elif defined(OS_CHROMEOS) + "CrOS %s %d.%d.%d", + cputype.c_str(), // e.g. i686 + os_major_version, + os_minor_version, + os_bugfix_version +#else + "%s %s", + unixinfo.sysname, // e.g. Linux + cputype.c_str() // e.g. i686 +#endif + ); // NOLINT + + return os_cpu; +} + +void BuildUserAgent(bool mimic_windows, std::string* result) { + const char kUserAgentPlatform[] = +#if defined(OS_WIN) + "Windows"; +#elif defined(OS_MACOSX) + "Macintosh"; +#elif defined(USE_X11) + "X11"; // strange, but that's what Firefox uses +#else + "?"; +#endif + + const char kUserAgentSecurity = 'U'; // "US" strength encryption + + // TODO(port): figure out correct locale + const char kUserAgentLocale[] = "en-US"; + + // Get the product name and version, and replace Safari's Version/X string + // with it. This is done to expose our product name in a manner that is + // maximally compatible with Safari, we hope!! + std::string product = GetProductVersion(); + + // Derived from Safari's UA string. + StringAppendF( + result, + "Mozilla/5.0 (%s; %c; %s; %s) AppleWebKit/%d.%d" + " (KHTML, like Gecko) %s Safari/%d.%d", + mimic_windows ? "Windows" : kUserAgentPlatform, + kUserAgentSecurity, + ((mimic_windows ? "Windows " : "") + BuildOSCpuInfo()).c_str(), + kUserAgentLocale, + WEBKIT_VERSION_MAJOR, + WEBKIT_VERSION_MINOR, + product.c_str(), + WEBKIT_VERSION_MAJOR, + WEBKIT_VERSION_MINOR); +} + +} // namespace webkit_glue + diff --git a/webkit/glue/user_agent.h b/webkit/glue/user_agent.h new file mode 100644 index 0000000..3d1f788 --- /dev/null +++ b/webkit/glue/user_agent.h @@ -0,0 +1,28 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_GLUE_USER_AGENT_H_ +#define WEBKIT_GLUE_USER_AGENT_H_ + +#include <string> + +#include "base/basictypes.h" + +namespace webkit_glue { + +// Construct the User-Agent header, filling in |result|. +// The other parameters are workarounds for broken websites: +// - If mimic_windows is true, produce a fake Windows Chrome string. +void BuildUserAgent(bool mimic_windows, std::string* result); + +// Builds a User-agent compatible string that describes the OS and CPU type. +std::string BuildOSCpuInfo(); + +// Returns the WebKit version (major.minor). +std::string GetWebKitVersion(); + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_USER_AGENT_H_ + diff --git a/webkit/glue/webaccessibility.cc b/webkit/glue/webaccessibility.cc index b6e0d5e..0d96685 100644 --- a/webkit/glue/webaccessibility.cc +++ b/webkit/glue/webaccessibility.cc @@ -4,9 +4,17 @@ #include "webkit/glue/webaccessibility.h" +#include "base/string_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" +#include "third_party/WebKit/WebKit/chromium/public/WebAttribute.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocumentType.h" +#include "third_party/WebKit/WebKit/chromium/public/WebElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebNamedNodeMap.h" +#include "third_party/WebKit/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebAccessibilityCache; @@ -219,19 +227,32 @@ uint32 ConvertState(const WebAccessibilityObject& o) { if (o.isChecked()) state |= (1 << WebAccessibility::STATE_CHECKED); + if (o.isCollapsed()) + state |= (1 << WebAccessibility::STATE_COLLAPSED); + if (o.canSetFocusAttribute()) state |= (1 << WebAccessibility::STATE_FOCUSABLE); if (o.isFocused()) state |= (1 << WebAccessibility::STATE_FOCUSED); + if (o.roleValue() == WebKit::WebAccessibilityRolePopUpButton) { + state |= (1 << WebAccessibility::STATE_HASPOPUP); + + if (!o.isCollapsed()) + state |= (1 << WebAccessibility::STATE_EXPANDED); + } + if (o.isHovered()) state |= (1 << WebAccessibility::STATE_HOTTRACKED); if (o.isIndeterminate()) state |= (1 << WebAccessibility::STATE_INDETERMINATE); - if (o.isAnchor()) + if (!o.isVisible()) + state |= (1 << WebAccessibility::STATE_INVISIBLE); + + if (o.isLinked()) state |= (1 << WebAccessibility::STATE_LINKED); if (o.isMultiSelectable()) @@ -249,6 +270,12 @@ uint32 ConvertState(const WebAccessibilityObject& o) { if (o.isReadOnly()) state |= (1 << WebAccessibility::STATE_READONLY); + if (o.canSetSelectedAttribute()) + state |= (1 << WebAccessibility::STATE_SELECTABLE); + + if (o.isSelected()) + state |= (1 << WebAccessibility::STATE_SELECTED); + if (o.isVisited()) state |= (1 << WebAccessibility::STATE_TRAVERSED); @@ -269,6 +296,9 @@ WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, Init(src, cache); } +WebAccessibility::~WebAccessibility() { +} + void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, WebKit::WebAccessibilityCache* cache) { name = src.title(); @@ -285,15 +315,56 @@ void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, attributes[ATTR_HELP] = src.helpText(); if (src.keyboardShortcut().length()) attributes[ATTR_SHORTCUT] = src.keyboardShortcut(); + if (src.hasComputedStyle()) + attributes[ATTR_DISPLAY] = src.computedStyleDisplay(); + + WebKit::WebNode node = src.node(); + + if (!node.isNull() && node.isElementNode()) { + WebKit::WebElement element = node.to<WebKit::WebElement>(); + // TODO(ctguil): The tagName in WebKit is lower cased but + // HTMLElement::nodeName calls localNameUpper. Consider adding + // a WebElement method that returns the original lower cased tagName. + attributes[ATTR_HTML_TAG] = StringToLowerASCII(string16(element.tagName())); + for (unsigned i = 0; i < element.attributes().length(); i++) { + html_attributes.push_back( + std::pair<string16, string16>( + element.attributes().attributeItem(i).localName(), + element.attributes().attributeItem(i).value())); + } + } + + if (role == WebAccessibility::ROLE_DOCUMENT || + role == WebAccessibility::ROLE_WEB_AREA) { + WebKit::WebDocument document = src.document(); + if (name.empty()) + name = document.title(); + attributes[ATTR_DOC_TITLE] = document.title(); + attributes[ATTR_DOC_URL] = document.frame()->url().spec().utf16(); + if (document.isXHTMLDocument()) + attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/xhtml"); + else + attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/html"); + + WebKit::WebDocumentType doctype = document.doctype(); + if (!doctype.isNull()) + attributes[ATTR_DOC_DOCTYPE] = doctype.name(); + } // Add the source object to the cache and store its id. id = cache->addOrGetId(src); // Recursively create children. int child_count = src.childCount(); - children.resize(child_count); for (int i = 0; i < child_count; i++) { - children[i].Init(src.childAt(i), cache); + WebAccessibilityObject child = src.childAt(i); + + // The child may be invalid due to issues in webkit accessibility code. + // Don't add children are invalid thus preventing a crash. + // https://bugs.webkit.org/show_bug.cgi?id=44149 + // TODO(ctguil): We may want to remove this check as webkit stabilizes. + if (child.isValid()) + children.push_back(WebAccessibility(child, cache)); } } diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index 305bc0c..09a9473 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -9,12 +9,11 @@ #include <vector> #include "base/string16.h" -#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" -#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" namespace WebKit { class WebAccessibilityCache; +class WebAccessibilityObject; } namespace webkit_glue { @@ -133,23 +132,41 @@ struct WebAccessibility { // int mask = (1 << STATE_CHECKED) | (1 << STATE_FOCUSED); enum State { STATE_CHECKED, + STATE_COLLAPSED, + STATE_EXPANDED, STATE_FOCUSABLE, STATE_FOCUSED, + STATE_HASPOPUP, STATE_HOTTRACKED, STATE_INDETERMINATE, + STATE_INVISIBLE, STATE_LINKED, STATE_MULTISELECTABLE, STATE_OFFSCREEN, STATE_PRESSED, STATE_PROTECTED, STATE_READONLY, + STATE_SELECTABLE, + STATE_SELECTED, STATE_TRAVERSED, + STATE_BUSY, STATE_UNAVAILABLE }; + // Additional optional attributes that can be optionally attached to + // a node. enum Attribute { + // Doc attributes: only make sense when applied to the top-level + // Document node. + ATTR_DOC_URL, + ATTR_DOC_TITLE, + ATTR_DOC_MIMETYPE, + ATTR_DOC_DOCTYPE, + + // Attributes that could apply to any node. ATTR_ACTION, ATTR_DESCRIPTION, + ATTR_DISPLAY, ATTR_HELP, ATTR_HTML_TAG, ATTR_LINK_TARGET, @@ -166,6 +183,8 @@ struct WebAccessibility { WebAccessibility(const WebKit::WebAccessibilityObject& src, WebKit::WebAccessibilityCache* cache); + ~WebAccessibility(); + // Initialize an already-created struct, same as the constructor a void Init(const WebKit::WebAccessibilityObject& src, WebKit::WebAccessibilityCache* cache); @@ -180,6 +199,7 @@ struct WebAccessibility { WebKit::WebRect location; std::map<int32, string16> attributes; std::vector<WebAccessibility> children; + std::vector<std::pair<string16, string16> > html_attributes; }; } // namespace webkit_glue diff --git a/webkit/glue/webclipboard_impl.cc b/webkit/glue/webclipboard_impl.cc index 11bc96d..8e3f87b 100644 --- a/webkit/glue/webclipboard_impl.cc +++ b/webkit/glue/webclipboard_impl.cc @@ -58,6 +58,9 @@ std::string WebClipboardImpl::URLToImageMarkup(const WebURL& url, return markup; } +WebClipboardImpl::~WebClipboardImpl() { +} + bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) { Clipboard::FormatType format_type; Clipboard::Buffer buffer_type; diff --git a/webkit/glue/webclipboard_impl.h b/webkit/glue/webclipboard_impl.h index 92c4a5e..6a83a6d 100644 --- a/webkit/glue/webclipboard_impl.h +++ b/webkit/glue/webclipboard_impl.h @@ -19,7 +19,7 @@ class WebClipboardImpl : public WebKit::WebClipboard { static std::string URLToImageMarkup(const WebKit::WebURL& url, const WebKit::WebString& title); - virtual ~WebClipboardImpl() {} + virtual ~WebClipboardImpl(); // WebClipboard methods: virtual bool isFormatAvailable(Format, Buffer); diff --git a/webkit/glue/webcookie.cc b/webkit/glue/webcookie.cc new file mode 100644 index 0000000..cb255bd --- /dev/null +++ b/webkit/glue/webcookie.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/webcookie.h" + +namespace webkit_glue { + +WebCookie::WebCookie() + : expires(0), + http_only(false), + secure(false), + session(false) { +} + +WebCookie::WebCookie(const net::CookieMonster::CanonicalCookie& c) + : name(c.Name()), + value(c.Value()), + domain(c.Domain()), + path(c.Path()), + expires(c.ExpiryDate().ToDoubleT() * 1000), + http_only(c.IsHttpOnly()), + secure(c.IsSecure()), + session(!c.IsPersistent()) { +} + +WebCookie::WebCookie(const std::string& name, const std::string& value, + const std::string& domain, const std::string& path, + double expires, bool http_only, bool secure, bool session) + : name(name), + value(value), + domain(domain), + path(path), + expires(expires), + http_only(http_only), + secure(secure), + session(session) { +} + +WebCookie::~WebCookie() { +} + +} // namespace webkit_glue diff --git a/webkit/glue/webcookie.h b/webkit/glue/webcookie.h index e2f11e2..11411d8 100644 --- a/webkit/glue/webcookie.h +++ b/webkit/glue/webcookie.h @@ -14,38 +14,12 @@ namespace webkit_glue { struct WebCookie { - + WebCookie(); + explicit WebCookie(const net::CookieMonster::CanonicalCookie& c); WebCookie(const std::string& name, const std::string& value, const std::string& domain, const std::string& path, double expires, - bool http_only, bool secure, bool session) - : name(name), - value(value), - domain(domain), - path(path), - expires(expires), - http_only(http_only), - secure(secure), - session(session) { - } - - explicit WebCookie(const net::CookieMonster::CanonicalCookie& c) - : name(c.Name()), - value(c.Value()), - domain(c.Domain()), - path(c.Path()), - expires(c.ExpiryDate().ToDoubleT() * 1000), - http_only(c.IsHttpOnly()), - secure(c.IsSecure()), - session(!c.IsPersistent()) { - } - - // For default constructions. - WebCookie() - : expires(0), - http_only(false), - secure(false), - session(false) { - } + bool http_only, bool secure, bool session); + ~WebCookie(); // Cookie name. std::string name; diff --git a/webkit/glue/webcursor.cc b/webkit/glue/webcursor.cc index f09372c..8f76ef9 100644 --- a/webkit/glue/webcursor.cc +++ b/webkit/glue/webcursor.cc @@ -57,6 +57,7 @@ void WebCursor::InitFromCursorInfo(const WebCursorInfo& cursor_info) { hotspot_ = cursor_info.hotSpot; if (IsCustom()) SetCustomData(cursor_info.customImage); + ClampHotspot(); } void WebCursor::GetCursorInfo(WebCursorInfo* cursor_info) const { @@ -100,6 +101,7 @@ bool WebCursor::Deserialize(const Pickle* pickle, void** iter) { hotspot_.set_y(hotspot_y); custom_size_.set_width(size_x); custom_size_.set_height(size_y); + ClampHotspot(); custom_data_.clear(); if (data_len > 0) { @@ -192,3 +194,14 @@ void WebCursor::ImageFromCustomData(WebImage* image) const { image->assign(bitmap); } #endif + +void WebCursor::ClampHotspot() { + if (!IsCustom()) + return; + + // Clamp the hotspot to the custom image's dimensions. + hotspot_.set_x(std::max(0, + std::min(custom_size_.width() - 1, hotspot_.x()))); + hotspot_.set_y(std::max(0, + std::min(custom_size_.height() - 1, hotspot_.y()))); +} diff --git a/webkit/glue/webcursor.h b/webkit/glue/webcursor.h index 293bd74..35eb001 100644 --- a/webkit/glue/webcursor.h +++ b/webkit/glue/webcursor.h @@ -127,6 +127,9 @@ class WebCursor { void SetCustomData(const WebKit::WebImage& image); void ImageFromCustomData(WebKit::WebImage* image) const; + // Clamp the hotspot to the custom image's bounds, if this is a custom cursor. + void ClampHotspot(); + // WebCore::PlatformCursor type. int type_; diff --git a/webkit/glue/webcursor_gtk.cc b/webkit/glue/webcursor_gtk.cc index 70c0f46..54c8837 100644 --- a/webkit/glue/webcursor_gtk.cc +++ b/webkit/glue/webcursor_gtk.cc @@ -8,6 +8,7 @@ #include <gtk/gtk.h> #include "base/logging.h" +#include "gfx/gtk_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" using WebKit::WebCursorInfo; @@ -171,18 +172,13 @@ GdkCursor* WebCursor::GetCustomCursor() const { return NULL; } - const guchar* data = reinterpret_cast<const guchar*>(&custom_data_[0]); - GdkPixbuf* pixbuf = - gdk_pixbuf_new_from_data(data, - GDK_COLORSPACE_RGB, - TRUE, // has_alpha - 8, // bits_per_sample - custom_size_.width(), // width - custom_size_.height(), // height - custom_size_.width() * 4, // row stride - NULL, // data destroy function - NULL); // data destroy function extra data + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, + custom_size_.width(), custom_size_.height()); + bitmap.allocPixels(); + memcpy(bitmap.getAddr32(0, 0), custom_data_.data(), custom_data_.size()); + GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap); GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, hotspot_.x(), diff --git a/webkit/glue/webcursor_unittest.cc b/webkit/glue/webcursor_unittest.cc index 5c1ddfe..6e7701d 100644 --- a/webkit/glue/webcursor_unittest.cc +++ b/webkit/glue/webcursor_unittest.cc @@ -4,9 +4,12 @@ #include "base/pickle.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" #include "webkit/glue/webcursor.h" #include "webkit/tools/test_shell/test_shell_test.h" +using WebKit::WebCursorInfo; + TEST(WebCursorTest, CursorSerialization) { WebCursor custom_cursor; // This is a valid custom cursor. @@ -80,3 +83,36 @@ TEST(WebCursorTest, CursorSerialization) { EXPECT_FALSE(custom_cursor.Deserialize(&neg_custom_pickle, &iter)); } +TEST(WebCursorTest, ClampHotspot) { + WebCursor custom_cursor; + // This is a valid custom cursor. + Pickle ok_custom_pickle; + // Type and hotspots. + ok_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); + // Hotspot is invalid --- outside the bounds of the image. + ok_custom_pickle.WriteInt(5); + ok_custom_pickle.WriteInt(5); + // X & Y + ok_custom_pickle.WriteInt(2); + ok_custom_pickle.WriteInt(2); + // Data len including enough data for a 2x2 image. + ok_custom_pickle.WriteInt(4 * 4); + for (size_t i = 0; i < 4; i++) + ok_custom_pickle.WriteUInt32(0); + // Custom Windows message. + ok_custom_pickle.WriteUInt32(0); + void* iter = NULL; + ASSERT_TRUE(custom_cursor.Deserialize(&ok_custom_pickle, &iter)); + + // Convert to WebCursorInfo, make sure the hotspot got clamped. + WebCursorInfo info; + custom_cursor.GetCursorInfo(&info); + EXPECT_EQ(gfx::Point(1, 1), gfx::Point(info.hotSpot)); + + // Set hotspot to an invalid point again, pipe back through WebCursor, + // and make sure the hotspot got clamped again. + info.hotSpot = gfx::Point(-1, -1); + custom_cursor.InitFromCursorInfo(info); + custom_cursor.GetCursorInfo(&info); + EXPECT_EQ(gfx::Point(0, 0), gfx::Point(info.hotSpot)); +} diff --git a/webkit/glue/webdropdata.cc b/webkit/glue/webdropdata.cc index d46987a..ea9e6c6 100644 --- a/webkit/glue/webdropdata.cc +++ b/webkit/glue/webdropdata.cc @@ -15,6 +15,10 @@ using WebKit::WebDragData; using WebKit::WebString; using WebKit::WebVector; +WebDropData::WebDropData(int32 drag_identity) + : identity(drag_identity) { +} + WebDropData::WebDropData(const WebDragData& drag_data) : identity(0), url(drag_data.url()), @@ -36,6 +40,13 @@ WebDropData::WebDropData(const WebDragData& drag_data) file_contents.assign(contents.data(), contents.size()); } +WebDropData::WebDropData() + : identity(0) { +} + +WebDropData::~WebDropData() { +} + WebDragData WebDropData::ToDragData() const { WebDragData result; result.initialize(); diff --git a/webkit/glue/webdropdata.h b/webkit/glue/webdropdata.h index 8149d8e..d129b06 100644 --- a/webkit/glue/webdropdata.h +++ b/webkit/glue/webdropdata.h @@ -24,13 +24,15 @@ class WebDragData; struct WebDropData { // Construct with a given drag identity. Note: identity is an int32 because // it is passed over the renderer NPAPI interface to gears. - explicit WebDropData(int32 drag_identity) : identity(drag_identity) {} + explicit WebDropData(int32 drag_identity); // Construct from a WebDragData object. explicit WebDropData(const WebKit::WebDragData&); // For default constructions, use drag |identity| 0. - WebDropData() : identity(0) {} + WebDropData(); + + ~WebDropData(); int32 identity; diff --git a/webkit/glue/webfilesystem_impl.cc b/webkit/glue/webfileutilities_impl.cc index 585287b..a77184d 100644 --- a/webkit/glue/webfilesystem_impl.cc +++ b/webkit/glue/webfileutilities_impl.cc @@ -2,7 +2,7 @@ // source code is governed by a BSD-style license that can be found in the // LICENSE file. -#include "webkit/glue/webfilesystem_impl.h" +#include "webkit/glue/webfileutilities_impl.h" #include "base/file_path.h" #include "base/file_util.h" @@ -17,26 +17,30 @@ using WebKit::WebString; namespace webkit_glue { -WebFileSystemImpl::WebFileSystemImpl() +WebFileUtilitiesImpl::WebFileUtilitiesImpl() : sandbox_enabled_(true) { } -bool WebFileSystemImpl::fileExists(const WebString& path) { +WebFileUtilitiesImpl::~WebFileUtilitiesImpl() { +} + +bool WebFileUtilitiesImpl::fileExists(const WebString& path) { FilePath::StringType file_path = WebStringToFilePathString(path); return file_util::PathExists(FilePath(file_path)); } -bool WebFileSystemImpl::deleteFile(const WebString& path) { +bool WebFileUtilitiesImpl::deleteFile(const WebString& path) { NOTREACHED(); return false; } -bool WebFileSystemImpl::deleteEmptyDirectory(const WebString& path) { +bool WebFileUtilitiesImpl::deleteEmptyDirectory(const WebString& path) { NOTREACHED(); return false; } -bool WebFileSystemImpl::getFileSize(const WebString& path, long long& result) { +bool WebFileUtilitiesImpl::getFileSize(const WebString& path, + long long& result) { if (sandbox_enabled_) { NOTREACHED(); return false; @@ -45,25 +49,25 @@ bool WebFileSystemImpl::getFileSize(const WebString& path, long long& result) { reinterpret_cast<int64*>(&result)); } -bool WebFileSystemImpl::getFileModificationTime(const WebString& path, - double& result) { +bool WebFileUtilitiesImpl::getFileModificationTime(const WebString& path, + double& result) { if (sandbox_enabled_) { NOTREACHED(); return false; } - file_util::FileInfo info; + base::PlatformFileInfo info; if (!file_util::GetFileInfo(WebStringToFilePath(path), &info)) return false; result = info.last_modified.ToDoubleT(); return true; } -WebString WebFileSystemImpl::directoryName(const WebString& path) { +WebString WebFileUtilitiesImpl::directoryName(const WebString& path) { FilePath file_path(WebStringToFilePathString(path)); return FilePathToWebString(file_path.DirName()); } -WebString WebFileSystemImpl::pathByAppendingComponent( +WebString WebFileUtilitiesImpl::pathByAppendingComponent( const WebString& webkit_path, const WebString& webkit_component) { FilePath path(WebStringToFilePathString(webkit_path)); @@ -72,29 +76,29 @@ WebString WebFileSystemImpl::pathByAppendingComponent( return FilePathStringToWebString(combined_path.value()); } -bool WebFileSystemImpl::makeAllDirectories(const WebString& path) { +bool WebFileUtilitiesImpl::makeAllDirectories(const WebString& path) { DCHECK(!sandbox_enabled_); FilePath::StringType file_path = WebStringToFilePathString(path); return file_util::CreateDirectory(FilePath(file_path)); } -WebString WebFileSystemImpl::getAbsolutePath(const WebString& path) { +WebString WebFileUtilitiesImpl::getAbsolutePath(const WebString& path) { FilePath file_path(WebStringToFilePathString(path)); file_util::AbsolutePath(&file_path); return FilePathStringToWebString(file_path.value()); } -bool WebFileSystemImpl::isDirectory(const WebString& path) { +bool WebFileUtilitiesImpl::isDirectory(const WebString& path) { FilePath file_path(WebStringToFilePathString(path)); return file_util::DirectoryExists(file_path); } -WebKit::WebURL WebFileSystemImpl::filePathToURL(const WebString& path) { +WebKit::WebURL WebFileUtilitiesImpl::filePathToURL(const WebString& path) { return net::FilePathToFileURL(WebStringToFilePath(path)); } -base::PlatformFile WebFileSystemImpl::openFile(const WebString& path, - int mode) { +base::PlatformFile WebFileUtilitiesImpl::openFile(const WebString& path, + int mode) { if (sandbox_enabled_) { NOTREACHED(); return base::kInvalidPlatformFileValue; @@ -103,37 +107,37 @@ base::PlatformFile WebFileSystemImpl::openFile(const WebString& path, WebStringToFilePath(path), (mode == 0) ? (base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ) : (base::PLATFORM_FILE_CREATE_ALWAYS | - base::PLATFORM_FILE_WRITE), - NULL); + base::PLATFORM_FILE_WRITE), + NULL, NULL); } -void WebFileSystemImpl::closeFile(base::PlatformFile& handle) { +void WebFileUtilitiesImpl::closeFile(base::PlatformFile& handle) { if (handle == base::kInvalidPlatformFileValue) return; if (base::ClosePlatformFile(handle)) handle = base::kInvalidPlatformFileValue; } -long long WebFileSystemImpl::seekFile(base::PlatformFile handle, - long long offset, - int origin) { +long long WebFileUtilitiesImpl::seekFile(base::PlatformFile handle, + long long offset, + int origin) { if (handle == base::kInvalidPlatformFileValue) return -1; net::FileStream file_stream(handle, 0); return file_stream.Seek(static_cast<net::Whence>(origin), offset); } -bool WebFileSystemImpl::truncateFile(base::PlatformFile handle, - long long offset) { +bool WebFileUtilitiesImpl::truncateFile(base::PlatformFile handle, + long long offset) { if (handle == base::kInvalidPlatformFileValue || offset < 0) return false; net::FileStream file_stream(handle, base::PLATFORM_FILE_WRITE); return file_stream.Truncate(offset) >= 0; } -int WebFileSystemImpl::readFromFile(base::PlatformFile handle, - char* data, - int length) { +int WebFileUtilitiesImpl::readFromFile(base::PlatformFile handle, + char* data, + int length) { if (handle == base::kInvalidPlatformFileValue || !data || length <= 0) return -1; std::string buffer; @@ -142,9 +146,9 @@ int WebFileSystemImpl::readFromFile(base::PlatformFile handle, return file_stream.Read(data, length, NULL); } -int WebFileSystemImpl::writeToFile(base::PlatformFile handle, - const char* data, - int length) { +int WebFileUtilitiesImpl::writeToFile(base::PlatformFile handle, + const char* data, + int length) { if (handle == base::kInvalidPlatformFileValue || !data || length <= 0) return -1; net::FileStream file_stream(handle, base::PLATFORM_FILE_WRITE); diff --git a/webkit/glue/webfilesystem_impl.h b/webkit/glue/webfileutilities_impl.h index 875a13b..5867396 100644 --- a/webkit/glue/webfilesystem_impl.h +++ b/webkit/glue/webfileutilities_impl.h @@ -2,20 +2,20 @@ // source code is governed by a BSD-style license that can be found in the // LICENSE file. -#ifndef WEBFILESYSTEM_IMPL_H_ -#define WEBFILESYSTEM_IMPL_H_ +#ifndef WEBFILEUTILITIES_IMPL_H_ +#define WEBFILEUTILITIES_IMPL_H_ #include "base/platform_file.h" -#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileUtilities.h" namespace webkit_glue { -class WebFileSystemImpl : public WebKit::WebFileSystem { +class WebFileUtilitiesImpl : public WebKit::WebFileUtilities { public: - WebFileSystemImpl(); - virtual ~WebFileSystemImpl() { } + WebFileUtilitiesImpl(); + virtual ~WebFileUtilitiesImpl(); - // WebFileSystem methods: + // WebFileUtilities methods: virtual bool fileExists(const WebKit::WebString& path); virtual bool deleteFile(const WebKit::WebString& path); virtual bool deleteEmptyDirectory(const WebKit::WebString& path); @@ -51,4 +51,4 @@ class WebFileSystemImpl : public WebKit::WebFileSystem { } // namespace webkit_glue -#endif // WEBFILESYSTEM_IMPL_H_ +#endif // WEBFILEUTILITIES_IMPL_H_ diff --git a/webkit/glue/webkit_glue.cc b/webkit/glue/webkit_glue.cc index e6b0f75..661b87b 100644 --- a/webkit/glue/webkit_glue.cc +++ b/webkit/glue/webkit_glue.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,6 +16,7 @@ #include "base/singleton.h" #include "base/string_piece.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "base/sys_info.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" @@ -41,10 +42,9 @@ #include "third_party/WebKit/WebKit/chromium/public/win/WebInputEventFactory.h" #endif #include "webkit/glue/glue_serialize.h" +#include "webkit/glue/user_agent.h" #include "v8/include/v8.h" -#include "webkit_version.h" // Generated - using WebKit::WebCanvas; using WebKit::WebData; using WebKit::WebElement; @@ -74,11 +74,9 @@ namespace webkit_glue { // Global variable used by the plugin quirk "die after unload". bool g_forcefully_terminate_plugin_process = false; -void SetJavaScriptFlags(const std::wstring& str) { +void SetJavaScriptFlags(const std::string& str) { #if WEBKIT_USING_V8 - std::string utf8_str = WideToUTF8(str); - v8::V8::SetFlagsFromString( - utf8_str.data(), static_cast<int>(utf8_str.size())); + v8::V8::SetFlagsFromString(str.data(), static_cast<int>(str.size())); #endif } @@ -257,8 +255,9 @@ void ResetBeforeTestRun(WebView* view) { #ifndef NDEBUG // The log macro was having problems due to collisions with WTF, so we just // code here what that would have inlined. -void DumpLeakedObject(const char* file, int line, const char* object, int count) { - std::string msg = StringPrintf("%s LEAKED %d TIMES", object, count); +void DumpLeakedObject(const char* file, int line, const char* object, + int count) { + std::string msg = base::StringPrintf("%s LEAKED %d TIMES", object, count); AppendToLog(file, line, msg.c_str()); } #endif @@ -314,8 +313,24 @@ WebString FilePathToWebString(const FilePath& file_path) { return FilePathStringToWebString(file_path.value()); } -std::string GetWebKitVersion() { - return StringPrintf("%d.%d", WEBKIT_VERSION_MAJOR, WEBKIT_VERSION_MINOR); +WebKit::WebFileError PlatformFileErrorToWebFileError( + base::PlatformFileError error_code) { + switch (error_code) { + case base::PLATFORM_FILE_ERROR_NOT_FOUND: + return WebKit::WebFileErrorNotFound; + case base::PLATFORM_FILE_ERROR_INVALID_OPERATION: + case base::PLATFORM_FILE_ERROR_EXISTS: + case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY: + return WebKit::WebFileErrorInvalidModification; + case base::PLATFORM_FILE_ERROR_ACCESS_DENIED: + return WebKit::WebFileErrorNoModificationAllowed; + case base::PLATFORM_FILE_ERROR_FAILED: + return WebKit::WebFileErrorInvalidState; + case base::PLATFORM_FILE_ERROR_ABORT: + return WebKit::WebFileErrorAbort; + default: + return WebKit::WebFileErrorInvalidModification; + } } namespace { @@ -337,101 +352,6 @@ struct UserAgentState { Singleton<UserAgentState> g_user_agent; -std::string BuildOSCpuInfo() { - std::string os_cpu; - -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) - int32 os_major_version = 0; - int32 os_minor_version = 0; - int32 os_bugfix_version = 0; - base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, - &os_minor_version, - &os_bugfix_version); -#endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) - // Should work on any Posix system. - struct utsname unixinfo; - uname(&unixinfo); - - std::string cputype; - // special case for biarch systems - if (strcmp(unixinfo.machine, "x86_64") == 0 && - sizeof(void*) == sizeof(int32)) { - cputype.assign("i686 (x86_64)"); - } else { - cputype.assign(unixinfo.machine); - } -#endif - - StringAppendF( - &os_cpu, -#if defined(OS_WIN) - "Windows NT %d.%d", - os_major_version, - os_minor_version -#elif defined(OS_MACOSX) - "Intel Mac OS X %d_%d_%d", - os_major_version, - os_minor_version, - os_bugfix_version -#elif defined(OS_CHROMEOS) - "CrOS %s %d.%d.%d", - cputype.c_str(), // e.g. i686 - os_major_version, - os_minor_version, - os_bugfix_version -#else - "%s %s", - unixinfo.sysname, // e.g. Linux - cputype.c_str() // e.g. i686 -#endif - ); - - return os_cpu; -} - -// Construct the User-Agent header, filling in |result|. -// The other parameters are workarounds for broken websites: -// - If mimic_windows is true, produce a fake Windows Chrome string. -void BuildUserAgent(bool mimic_windows, std::string* result) { - const char kUserAgentPlatform[] = -#if defined(OS_WIN) - "Windows"; -#elif defined(OS_MACOSX) - "Macintosh"; -#elif defined(USE_X11) - "X11"; // strange, but that's what Firefox uses -#else - "?"; -#endif - - const char kUserAgentSecurity = 'U'; // "US" strength encryption - - // TODO(port): figure out correct locale - const char kUserAgentLocale[] = "en-US"; - - // Get the product name and version, and replace Safari's Version/X string - // with it. This is done to expose our product name in a manner that is - // maximally compatible with Safari, we hope!! - std::string product = GetProductVersion(); - - // Derived from Safari's UA string. - StringAppendF( - result, - "Mozilla/5.0 (%s; %c; %s; %s) AppleWebKit/%d.%d" - " (KHTML, like Gecko) %s Safari/%d.%d", - mimic_windows ? "Windows" : kUserAgentPlatform, - kUserAgentSecurity, - ((mimic_windows ? "Windows " : "") + BuildOSCpuInfo()).c_str(), - kUserAgentLocale, - WEBKIT_VERSION_MAJOR, - WEBKIT_VERSION_MINOR, - product.c_str(), - WEBKIT_VERSION_MAJOR, - WEBKIT_VERSION_MINOR - ); -} - void SetUserAgentToDefault() { BuildUserAgent(false, &g_user_agent->user_agent); } @@ -455,7 +375,7 @@ const std::string& GetUserAgent(const GURL& url) { if (!g_user_agent->user_agent_is_overridden) { // Workarounds for sites that use misguided UA sniffing. #if defined(OS_POSIX) && !defined(OS_MACOSX) - if (MatchPatternASCII(url.host(), "*.mail.yahoo.com")) { + if (MatchPattern(url.host(), "*.mail.yahoo.com")) { // mail.yahoo.com is ok with Windows Chrome but not Linux Chrome. // http://bugs.chromium.org/11136 // TODO(evanm): remove this if Yahoo fixes their sniffing. diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 49320fc..f5d03c4 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -105,21 +105,12 @@ ], }, { - 'target_name': 'glue', + 'target_name': 'webkit_user_agent', 'type': '<(library)', - 'msvs_guid': 'C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09', + 'msvs_guid': 'DB162DE1-7D56-4C4A-8A9F-80D396CD7AA8', 'dependencies': [ '<(DEPTH)/app/app.gyp:app_base', '<(DEPTH)/base/base.gyp:base_i18n', - '<(DEPTH)/net/net.gyp:net', - '<(DEPTH)/printing/printing.gyp:printing', - '<(DEPTH)/skia/skia.gyp:skia', - '<(DEPTH)/third_party/icu/icu.gyp:icui18n', - '<(DEPTH)/third_party/icu/icu.gyp:icuuc', - '<(DEPTH)/third_party/npapi/npapi.gyp:npapi', - '<(DEPTH)/third_party/ppapi/ppapi.gyp:ppapi_c', - 'webkit_resources', - 'webkit_strings', ], 'actions': [ { @@ -136,14 +127,46 @@ ], 'include_dirs': [ '<(INTERMEDIATE_DIR)', + ], + 'sources': [ + 'user_agent.cc', + 'user_agent.h', + ], + # Dependents may rely on files generated by this target or one of its + # own hard dependencies. + 'hard_dependency': 1, + 'conditions': [ + ], + }, + { + 'target_name': 'glue', + 'type': '<(library)', + 'msvs_guid': 'C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09', + 'dependencies': [ + '<(DEPTH)/app/app.gyp:app_base', + '<(DEPTH)/base/base.gyp:base_i18n', + '<(DEPTH)/gpu/gpu.gyp:gles2_implementation', + '<(DEPTH)/net/net.gyp:net', + '<(DEPTH)/printing/printing.gyp:printing', + '<(DEPTH)/skia/skia.gyp:skia', + '<(DEPTH)/third_party/icu/icu.gyp:icui18n', + '<(DEPTH)/third_party/icu/icu.gyp:icuuc', + '<(DEPTH)/third_party/npapi/npapi.gyp:npapi', + '<(DEPTH)/third_party/ppapi/ppapi.gyp:ppapi_c', + 'webkit_resources', + 'webkit_strings', + 'webkit_user_agent', + ], + 'actions': [ + ], + 'include_dirs': [ + '<(INTERMEDIATE_DIR)', '<(SHARED_INTERMEDIATE_DIR)/webkit', ], 'sources': [ # This list contains all .h, .cc, and .mm files in glue except for # those in the test subdirectory and those with unittest in in their # names. - 'devtools_message_data.cc', - 'devtools_message_data.h', 'media/buffered_data_source.cc', 'media/buffered_data_source.h', 'media/media_resource_loader_bridge_factory.cc', @@ -164,12 +187,18 @@ 'plugins/gtk_plugin_container_manager.cc', 'plugins/npapi_extension_thunk.cc', 'plugins/npapi_extension_thunk.h', + 'plugins/pepper_audio.cc', + 'plugins/pepper_audio.h', 'plugins/pepper_buffer.cc', 'plugins/pepper_buffer.h', - 'plugins/pepper_device_context_2d.cc', - 'plugins/pepper_device_context_2d.h', + 'plugins/pepper_char_set.cc', + 'plugins/pepper_char_set.h', + 'plugins/pepper_cursor_control.cc', + 'plugins/pepper_cursor_control.h', 'plugins/pepper_directory_reader.cc', 'plugins/pepper_directory_reader.h', + 'plugins/pepper_error_util.cc', + 'plugins/pepper_error_util.h', 'plugins/pepper_event_conversion.cc', 'plugins/pepper_event_conversion.h', 'plugins/pepper_file_chooser.cc', @@ -182,6 +211,8 @@ 'plugins/pepper_file_system.h', 'plugins/pepper_font.cc', 'plugins/pepper_font.h', + 'plugins/pepper_graphics_2d.cc', + 'plugins/pepper_graphics_2d.h', 'plugins/pepper_image_data.cc', 'plugins/pepper_image_data.h', 'plugins/pepper_plugin_delegate.h', @@ -189,22 +220,32 @@ 'plugins/pepper_plugin_instance.h', 'plugins/pepper_plugin_module.cc', 'plugins/pepper_plugin_module.h', + 'plugins/pepper_plugin_object.cc', + 'plugins/pepper_plugin_object.h', 'plugins/pepper_private.cc', 'plugins/pepper_private.h', + 'plugins/pepper_private2.cc', + 'plugins/pepper_private2.h', 'plugins/pepper_resource_tracker.cc', 'plugins/pepper_resource_tracker.h', 'plugins/pepper_resource.cc', 'plugins/pepper_resource.h', 'plugins/pepper_scrollbar.cc', 'plugins/pepper_scrollbar.h', + 'plugins/pepper_transport.cc', + 'plugins/pepper_transport.h', 'plugins/pepper_url_loader.cc', 'plugins/pepper_url_loader.h', 'plugins/pepper_url_request_info.cc', 'plugins/pepper_url_request_info.h', 'plugins/pepper_url_response_info.cc', 'plugins/pepper_url_response_info.h', + 'plugins/pepper_url_util.cc', + 'plugins/pepper_url_util.h', 'plugins/pepper_var.cc', 'plugins/pepper_var.h', + 'plugins/pepper_video_decoder.cc', + 'plugins/pepper_video_decoder.h', 'plugins/pepper_webplugin_impl.cc', 'plugins/pepper_webplugin_impl.h', 'plugins/pepper_widget.cc', @@ -258,6 +299,7 @@ 'plugins/webplugininfo.h', 'alt_error_page_resource_fetcher.cc', 'alt_error_page_resource_fetcher.h', + 'context_menu.cc', 'context_menu.h', 'cpp_binding_example.cc', 'cpp_binding_example.h', @@ -267,6 +309,7 @@ 'cpp_variant.h', 'dom_operations.cc', 'dom_operations.h', + 'form_data.cc', 'form_data.h', 'form_field.cc', 'form_field.h', @@ -274,6 +317,8 @@ 'ftp_directory_listing_response_delegate.h', 'glue_serialize.cc', 'glue_serialize.h', + 'idb_bindings.cc', + 'idb_bindings.h', 'image_decoder.cc', 'image_decoder.h', 'image_resource_fetcher.cc', @@ -282,6 +327,7 @@ 'multipart_response_delegate.h', 'npruntime_util.cc', 'npruntime_util.h', + 'password_form.cc', 'password_form.h', 'password_form_dom_manager.cc', 'password_form_dom_manager.h', @@ -299,6 +345,7 @@ 'webaccessibility.h', 'webclipboard_impl.cc', 'webclipboard_impl.h', + 'webcookie.cc', 'webcookie.h', 'webcursor.cc', 'webcursor.h', @@ -309,8 +356,8 @@ 'webdropdata.cc', 'webdropdata_win.cc', 'webdropdata.h', - 'webfilesystem_impl.cc', - 'webfilesystem_impl.h', + 'webfileutilities_impl.cc', + 'webfileutilities_impl.h', 'webkit_glue.cc', 'webkit_glue.h', 'webkitclient_impl.cc', @@ -331,6 +378,8 @@ 'webthemeengine_impl_win.cc', 'weburlloader_impl.cc', 'weburlloader_impl.h', + 'webvideoframe_impl.cc', + 'webvideoframe_impl.h', 'window_open_disposition.h', 'window_open_disposition.cc', @@ -344,8 +393,6 @@ '../extensions/v8/gears_extension.h', '../extensions/v8/heap_profiler_extension.cc', '../extensions/v8/heap_profiler_extension.h', - '../extensions/v8/interval_extension.cc', - '../extensions/v8/interval_extension.h', '../extensions/v8/playback_extension.cc', '../extensions/v8/playback_extension.h', '../extensions/v8/profiler_extension.cc', @@ -375,11 +422,16 @@ 'sources/': [['exclude', 'plugin_(lib|list)_posix\\.cc$']], 'link_settings': { 'libraries': [ - '$(SDKROOT)/QuartzCore.framework', + '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework', ], }, }], ['enable_gpu==1 and inside_chromium_build==1', { + 'sources': [ + 'plugins/pepper_graphics_3d_gl.cc', + 'plugins/pepper_graphics_3d.cc', + 'plugins/pepper_graphics_3d.h', + ], 'dependencies': [ '<(DEPTH)/gpu/gpu.gyp:gpu_plugin', ], diff --git a/webkit/glue/webkit_glue.h b/webkit/glue/webkit_glue.h index 541836b..380bf36 100644 --- a/webkit/glue/webkit_glue.h +++ b/webkit/glue/webkit_glue.h @@ -16,8 +16,10 @@ #include "app/clipboard/clipboard.h" #include "base/file_path.h" +#include "base/platform_file.h" #include "base/string16.h" #include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h" class GURL; class SkBitmap; @@ -42,7 +44,7 @@ namespace webkit_glue { //---- BEGIN FUNCTIONS IMPLEMENTED BY WEBKIT/GLUE ----------------------------- -void SetJavaScriptFlags(const std::wstring& flags); +void SetJavaScriptFlags(const std::string& flags); // Turn on the logging for notImplemented() calls from WebCore. void EnableWebCoreNotImplementedLogging(); @@ -132,6 +134,10 @@ WebKit::WebString FilePathStringToWebString(const FilePath::StringType& str); FilePath WebStringToFilePath(const WebKit::WebString& str); WebKit::WebString FilePathToWebString(const FilePath& file_path); +// File error conversion +WebKit::WebFileError PlatformFileErrorToWebFileError( + base::PlatformFileError error_code); + // Returns a WebCanvas pointer associated with the given Skia canvas. WebKit::WebCanvas* ToWebCanvas(skia::PlatformCanvas*); @@ -248,7 +254,7 @@ bool FindProxyForUrl(const GURL& url, std::string* proxy_list); // Returns the locale that this instance of webkit is running as. This is of // the form language-country (e.g., en-US or pt-BR). -std::wstring GetWebKitLocale(); +std::string GetWebKitLocale(); // Close current connections. Used for debugging. void CloseCurrentConnections(); @@ -265,6 +271,9 @@ std::string GetProductVersion(); // Returns true if the embedder is running in single process mode. bool IsSingleProcess(); +// Enables/Disables Spdy for requests afterwards. Used for benchmarking. +void EnableSpdy(bool enable); + #if defined(OS_LINUX) // Return a read-only file descriptor to the font which best matches the given // properties or -1 on failure. diff --git a/webkit/glue/webkit_resources.grd b/webkit/glue/webkit_resources.grd index a2146fd..94d4286 100644 --- a/webkit/glue/webkit_resources.grd +++ b/webkit/glue/webkit_resources.grd @@ -14,6 +14,9 @@ <include name="IDC_CELL" file="resources\cell.cur" type="CURSOR" /> <include name="IDC_COLRESIZE" file="resources\col_resize.cur" type="CURSOR" /> <include name="IDC_COPYCUR" file="resources\copy.cur" type="CURSOR" /> + <include name="IDR_INPUT_SPEECH" file="resources\input_speech.png" type="BINDATA" /> + <include name="IDR_INPUT_SPEECH_RECORDING" file="resources\input_speech_recording.png" type="BINDATA" /> + <include name="IDR_INPUT_SPEECH_WAITING" file="resources\input_speech_waiting.png" type="BINDATA" /> <include name="IDR_MEDIA_PAUSE_BUTTON" file="resources\media_pause.png" type="BINDATA" /> <include name="IDR_MEDIA_PLAY_BUTTON" file="resources\media_play.png" type="BINDATA" /> <include name="IDR_MEDIA_PLAY_BUTTON_DISABLED" file="resources\media_play_disabled.png" type="BINDATA" /> @@ -42,6 +45,37 @@ <include name="IDC_VERTICALTEXT" file="resources\vertical_text.cur" type="CURSOR" /> <include name="IDC_ZOOMIN" file="resources\zoom_in.cur" type="CURSOR" /> <include name="IDC_ZOOMOUT" file="resources\zoom_out.cur" type="CURSOR" /> + <include name="IDR_AUTOFILL_CC_AMEX" file="resources\amex.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_DINERS" file="resources\diners.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_DISCOVER" file="resources\discover.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_GENERIC" file="resources\cc-generic.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_JCB" file="resources\jcb.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_MASTERCARD" file="resources\mastercard.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_SOLO" file="resources\solo.png" type="BINDATA" /> + <include name="IDR_AUTOFILL_CC_VISA" file="resources\visa.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_FTH" file="resources\pdf_button_fth.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_FTH_HOVER" file="resources\pdf_button_fth_hover.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_FTH_PRESSED" file="resources\pdf_button_fth_pressed.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_FTW" file="resources\pdf_button_ftw.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_FTW_HOVER" file="resources\pdf_button_ftw_hover.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_FTW_PRESSED" file="resources\pdf_button_ftw_pressed.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_ZOOMIN" file="resources\pdf_button_zoomin.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_ZOOMIN_HOVER" file="resources\pdf_button_zoomin_hover.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_ZOOMIN_PRESSED" file="resources\pdf_button_zoomin_pressed.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_ZOOMOUT" file="resources\pdf_button_zoomout.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_ZOOMOUT_HOVER" file="resources\pdf_button_zoomout_hover.png" type="BINDATA" /> + <include name="IDR_PDF_BUTTON_ZOOMOUT_PRESSED" file="resources\pdf_button_zoomout_pressed.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_0" file="resources\pdf_thumbnail_0.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_1" file="resources\pdf_thumbnail_1.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_2" file="resources\pdf_thumbnail_2.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_3" file="resources\pdf_thumbnail_3.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_4" file="resources\pdf_thumbnail_4.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_5" file="resources\pdf_thumbnail_5.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_6" file="resources\pdf_thumbnail_6.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_7" file="resources\pdf_thumbnail_7.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_8" file="resources\pdf_thumbnail_8.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_9" file="resources\pdf_thumbnail_9.png" type="BINDATA" /> + <include name="IDR_PDF_THUMBNAIL_NUM_BACKGROUND" file="resources\pdf_thumbnail_num_background.png" type="BINDATA" /> <if expr="os == 'linux2' or os.find('bsd') != -1 or os == 'sunos5'"> <include name="IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE" file="resources\linux-checkbox-disabled-indeterminate.png" type="BINDATA" /> diff --git a/webkit/glue/webkit_strings.grd b/webkit/glue/webkit_strings.grd index cbb1c7f..3cc2a98 100644 --- a/webkit/glue/webkit_strings.grd +++ b/webkit/glue/webkit_strings.grd @@ -59,6 +59,7 @@ below: <output filename="webkit_strings_es.rc" type="rc_all" lang="es" /> <output filename="webkit_strings_es-419.rc" type="rc_all" lang="es-419" /> <output filename="webkit_strings_et.rc" type="rc_all" lang="et" /> + <output filename="webkit_strings_fa.rc" type="rc_all" lang="fa" /> <output filename="webkit_strings_fi.rc" type="rc_all" lang="fi" /> <output filename="webkit_strings_fil.rc" type="rc_all" lang="fil" /> <output filename="webkit_strings_fr.rc" type="rc_all" lang="fr" /> @@ -113,6 +114,7 @@ below: <output filename="webkit_strings_es.pak" type="data_package" lang="es" /> <output filename="webkit_strings_es-419.pak" type="data_package" lang="es-419" /> <output filename="webkit_strings_et.pak" type="data_package" lang="et" /> + <output filename="webkit_strings_fa.pak" type="data_package" lang="fa" /> <output filename="webkit_strings_fi.pak" type="data_package" lang="fi" /> <output filename="webkit_strings_fil.pak" type="data_package" lang="fil" /> <output filename="webkit_strings_fr.pak" type="data_package" lang="fr" /> @@ -167,6 +169,7 @@ below: <file path="resources/webkit_strings_es.xtb" lang="es" /> <file path="resources/webkit_strings_es-419.xtb" lang="es-419" /> <file path="resources/webkit_strings_et.xtb" lang="et" /> + <file path="resources/webkit_strings_fa.xtb" lang="fa" /> <file path="resources/webkit_strings_fi.xtb" lang="fi" /> <file path="resources/webkit_strings_fil.xtb" lang="fil" /> <file path="resources/webkit_strings_fr.xtb" lang="fr" /> @@ -253,7 +256,7 @@ below: </message> <message name="IDS_AX_ROLE_WEB_AREA" desc="accessibility role description for web area"> - web area + HTML content </message> <message name="IDS_AX_ROLE_LINK" desc="accessibility role description for link"> link @@ -359,6 +362,14 @@ below: <message name="IDS_PDF_NEED_PASSWORD" desc="A message asking the user for a password to open a PDF file."> This document is password protected. Please enter a password. </message> + + <message name="IDS_PDF_PAGE_LOADING" desc="A message displayed on the PDF page while page is loading."> + Loading... + </message> + + <message name="IDS_PDF_LOADING_PROGRESS" desc="A message displayed on the PDF control to indicate loading progress."> + Loading document: <ph name="PAGE_NUMBER">%d<ex>3</ex></ph>/<ph name="NUMBER_OF_PAGES">%d<ex>15</ex></ph> pages... + </message> </messages> </release> </grit> diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index b05e7d9..c65d176 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -18,6 +18,8 @@ #include "base/platform_file.h" #include "base/singleton.h" #include "base/stats_counters.h" +#include "base/string_number_conversions.h" +#include "base/string_util.h" #include "base/time.h" #include "base/utf_string_conversions.h" #include "base/trace_event.h" @@ -165,6 +167,9 @@ WebKitClientImpl::WebKitClientImpl() shared_timer_suspended_(0) { } +WebKitClientImpl::~WebKitClientImpl() { +} + WebThemeEngine* WebKitClientImpl::themeEngine() { #if defined(OS_WIN) return &theme_engine_; @@ -250,6 +255,17 @@ WebData WebKitClientImpl::loadResource(const char* name) { { "searchMagnifierResults", IDR_SEARCH_MAGNIFIER_RESULTS }, { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER }, { "tickmarkDash", IDR_TICKMARK_DASH }, + { "inputSpeech", IDR_INPUT_SPEECH }, + { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING }, + { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING }, + { "americanExpressCC", IDR_AUTOFILL_CC_AMEX }, + { "dinersCC", IDR_AUTOFILL_CC_DINERS }, + { "discoverCC", IDR_AUTOFILL_CC_DISCOVER }, + { "genericCC", IDR_AUTOFILL_CC_GENERIC }, + { "jcbCC", IDR_AUTOFILL_CC_JCB }, + { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD }, + { "soloCC", IDR_AUTOFILL_CC_SOLO }, + { "visaCC", IDR_AUTOFILL_CC_VISA }, #if defined(OS_POSIX) && !defined(OS_MACOSX) // TODO(port): rename these to "skia" instead of "Linux". { "linuxCheckboxDisabledIndeterminate", @@ -275,7 +291,9 @@ WebData WebKitClientImpl::loadResource(const char* name) { return WebData(resource.data(), resource.size()); } } - NOTREACHED() << "Unknown image resource " << name; + // TODO(jhawkins): Restore this NOTREACHED once WK stops sending in empty + // strings. http://crbug.com/50675. + //NOTREACHED() << "Unknown image resource " << name; return WebData(); } @@ -293,7 +311,7 @@ WebString WebKitClientImpl::queryLocalizedString( if (message_id < 0) return WebString(); return ReplaceStringPlaceholders(GetLocalizedString(message_id), - IntToString16(numeric_value), + base::IntToString16(numeric_value), NULL); } @@ -406,10 +424,11 @@ static size_t memoryUsageMBGeneric() { } #endif -size_t WebKitClientImpl::memoryUsageMB() { +static size_t getMemoryUsageMB(bool bypass_cache) { size_t current_mem_usage = 0; MemoryUsageCache* mem_usage_cache_singleton = MemoryUsageCache::Get(); - if (mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage)) + if (!bypass_cache && + mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage)) return current_mem_usage; current_mem_usage = @@ -424,6 +443,14 @@ size_t WebKitClientImpl::memoryUsageMB() { return current_mem_usage; } +size_t WebKitClientImpl::memoryUsageMB() { + return getMemoryUsageMB(false); +} + +size_t WebKitClientImpl::actualMemoryUsageMB() { + return getMemoryUsageMB(true); +} + void WebKitClientImpl::SuspendSharedTimer() { ++shared_timer_suspended_; } diff --git a/webkit/glue/webkitclient_impl.h b/webkit/glue/webkitclient_impl.h index bec7a79..607677f 100644 --- a/webkit/glue/webkitclient_impl.h +++ b/webkit/glue/webkitclient_impl.h @@ -19,7 +19,7 @@ namespace webkit_glue { class WebKitClientImpl : public WebKit::WebKitClient { public: WebKitClientImpl(); - virtual ~WebKitClientImpl() {} + virtual ~WebKitClientImpl(); // WebKitClient methods (partial implementation): virtual WebKit::WebThemeEngine* themeEngine(); @@ -35,6 +35,7 @@ class WebKitClientImpl : public WebKit::WebKitClient { unsigned key_size_index, const WebKit::WebString& challenge, const WebKit::WebURL& url); virtual size_t memoryUsageMB(); + virtual size_t actualMemoryUsageMB(); virtual WebKit::WebURLLoader* createURLLoader(); virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle(); virtual WebKit::WebString userAgent(const WebKit::WebURL& url); diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index 51d67ab..d5c667d 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -4,11 +4,14 @@ #include "webkit/glue/webmediaplayer_impl.h" +#include <limits> + #include "base/callback.h" #include "base/command_line.h" #include "media/base/limits.h" #include "media/base/media_format.h" #include "media/base/media_switches.h" +#include "media/base/video_frame.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer.h" #include "media/filters/ffmpeg_video_decoder.h" @@ -17,8 +20,10 @@ #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" +#include "third_party/WebKit/WebKit/chromium/public/WebVideoFrame.h" #include "webkit/glue/media/video_renderer_impl.h" #include "webkit/glue/media/web_video_renderer.h" +#include "webkit/glue/webvideoframe_impl.h" using WebKit::WebCanvas; using WebKit::WebRect; @@ -178,6 +183,18 @@ void WebMediaPlayerImpl::Proxy::NetworkEventTask() { } } +void WebMediaPlayerImpl::Proxy::GetCurrentFrame( + scoped_refptr<media::VideoFrame>* frame_out) { + if (video_renderer_) + video_renderer_->GetCurrentFrame(frame_out); +} + +void WebMediaPlayerImpl::Proxy::PutCurrentFrame( + scoped_refptr<media::VideoFrame> frame) { + if (video_renderer_) + video_renderer_->PutCurrentFrame(frame); +} + ///////////////////////////////////////////////////////////////////////////// // WebMediaPlayerImpl implementation @@ -417,7 +434,10 @@ bool WebMediaPlayerImpl::seeking() const { float WebMediaPlayerImpl::duration() const { DCHECK(MessageLoop::current() == main_loop_); - return static_cast<float>(pipeline_->GetMediaDuration().InSecondsF()); + base::TimeDelta duration = pipeline_->GetMediaDuration(); + if (duration.InMicroseconds() == media::Limits::kMaxTimeInMicroseconds) + return std::numeric_limits<float>::infinity(); + return static_cast<float>(duration.InSecondsF()); } float WebMediaPlayerImpl::currentTime() const { @@ -562,6 +582,24 @@ WebKit::WebMediaPlayer::MovieLoadType return WebKit::WebMediaPlayer::Unknown; } +WebKit::WebVideoFrame* WebMediaPlayerImpl::getCurrentFrame() { + scoped_refptr<media::VideoFrame> video_frame; + proxy_->GetCurrentFrame(&video_frame); + if (video_frame.get()) + return new WebVideoFrameImpl(video_frame); + return NULL; +} + +void WebMediaPlayerImpl::putCurrentFrame( + WebKit::WebVideoFrame* web_video_frame) { + if (web_video_frame) { + scoped_refptr<media::VideoFrame> video_frame = + WebVideoFrameImpl::toVideoFrame(web_video_frame); + proxy_->PutCurrentFrame(video_frame); + delete web_video_frame; + } +} + void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { Destroy(); main_loop_ = NULL; @@ -657,10 +695,16 @@ void WebMediaPlayerImpl::OnPipelineError() { void WebMediaPlayerImpl::OnNetworkEvent() { DCHECK(MessageLoop::current() == main_loop_); if (pipeline_->GetError() == media::PIPELINE_OK) { - if (pipeline_->IsNetworkActive()) + if (pipeline_->IsNetworkActive()) { SetNetworkState(WebKit::WebMediaPlayer::Loading); - else + } else { + // If we are inactive because we just finished receiving all the data, + // do one final repaint to show final progress. + if (bytesLoaded() == totalBytes() && + network_state_ != WebKit::WebMediaPlayer::Idle) + Repaint(); SetNetworkState(WebKit::WebMediaPlayer::Idle); + } } } diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h index e8794dc..eefe1a9 100644 --- a/webkit/glue/webmediaplayer_impl.h +++ b/webkit/glue/webmediaplayer_impl.h @@ -53,8 +53,6 @@ #ifndef WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_ #define WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_ -#include <vector> - #include "base/lock.h" #include "base/message_loop.h" #include "base/ref_counted.h" @@ -103,6 +101,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect); void SetSize(const gfx::Rect& rect); void Detach(); + void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out); + void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame); // Public methods called from the pipeline via callback issued by // WebMediaPlayerImpl. @@ -230,6 +230,9 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, virtual bool hasSingleSecurityOrigin() const; virtual WebKit::WebMediaPlayer::MovieLoadType movieLoadType() const; + virtual WebKit::WebVideoFrame* getCurrentFrame(); + virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame); + // As we are closing the tab or even the browser, |main_loop_| is destroyed // even before this object gets destructed, so we need to know when // |main_loop_| is being destroyed and we can stop posting repaint task diff --git a/webkit/glue/webmenurunner_mac.mm b/webkit/glue/webmenurunner_mac.mm index e4c8a4b..b7e48ba 100644 --- a/webkit/glue/webmenurunner_mac.mm +++ b/webkit/glue/webmenurunner_mac.mm @@ -131,11 +131,19 @@ BOOL gNewNSMenuAPI; [button selectItemAtIndex:index]; [button setFont:[NSFont menuFontOfSize:fontSize_]]; + // Create a dummy view to associate the popup with, since the OS will use + // that view for positioning the menu. + NSView* dummyView = [[[NSView alloc] initWithFrame:bounds] autorelease]; + [view addSubview:dummyView]; + NSRect dummyBounds = [dummyView convertRect:bounds fromView:view]; + // Display the menu, and set a flag if a menu item was chosen. - [button performClickWithFrame:bounds inView:view]; + [button performClickWithFrame:dummyBounds inView:dummyView]; if ([self menuItemWasChosen]) index_ = [button indexOfSelectedItem]; + + [dummyView removeFromSuperview]; } } diff --git a/webkit/glue/webpasswordautocompletelistener_impl.cc b/webkit/glue/webpasswordautocompletelistener_impl.cc index 6f6e754..fc15af0 100644 --- a/webkit/glue/webpasswordautocompletelistener_impl.cc +++ b/webkit/glue/webpasswordautocompletelistener_impl.cc @@ -59,15 +59,18 @@ void WebInputElementDelegate::RefreshAutofillPopup( if (webview) { std::vector<string16> names; std::vector<string16> labels; + std::vector<string16> icons; std::vector<int> unique_ids; for (size_t i = 0; i < suggestions.size(); ++i) { names.push_back(suggestions[i]); labels.push_back(string16()); + icons.push_back(string16()); unique_ids.push_back(0); } - webview->applyAutoFillSuggestions(element_, names, labels, unique_ids, -1); + webview->applyAutoFillSuggestions( + element_, names, labels, icons, unique_ids, -1); } } @@ -80,6 +83,9 @@ WebPasswordAutocompleteListenerImpl::WebPasswordAutocompleteListenerImpl( data_(data) { } +WebPasswordAutocompleteListenerImpl::~WebPasswordAutocompleteListenerImpl() { +} + void WebPasswordAutocompleteListenerImpl::didBlurInputElement( const WebString& user_input) { // If this listener exists, its because the password manager had more than diff --git a/webkit/glue/webpasswordautocompletelistener_impl.h b/webkit/glue/webpasswordautocompletelistener_impl.h index 4fea455..8180a47 100644 --- a/webkit/glue/webpasswordautocompletelistener_impl.h +++ b/webkit/glue/webpasswordautocompletelistener_impl.h @@ -49,8 +49,7 @@ class WebPasswordAutocompleteListenerImpl : WebInputElementDelegate* username_element, WebInputElementDelegate* password_element, const PasswordFormFillData& data); - ~WebPasswordAutocompleteListenerImpl() { - } + virtual ~WebPasswordAutocompleteListenerImpl(); // WebKit::PasswordAutocompleteListener methods: virtual void didBlurInputElement(const WebString& user_input); diff --git a/webkit/glue/webpasswordautocompletelistener_unittest.cc b/webkit/glue/webpasswordautocompletelistener_unittest.cc index 5a05d46..0ce2916 100644 --- a/webkit/glue/webpasswordautocompletelistener_unittest.cc +++ b/webkit/glue/webpasswordautocompletelistener_unittest.cc @@ -9,6 +9,7 @@ #include <string> #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" #include "webkit/glue/form_field.h" #include "webkit/glue/webpasswordautocompletelistener_impl.h" diff --git a/webkit/glue/webpreferences.cc b/webkit/glue/webpreferences.cc index 987cef4..ddf4ddb 100644 --- a/webkit/glue/webpreferences.cc +++ b/webkit/glue/webpreferences.cc @@ -59,7 +59,8 @@ void WebPreferences::Apply(WebView* web_view) const { WebRuntimeFeatures::enableDatabase( WebRuntimeFeatures::isDatabaseEnabled() || databases_enabled); settings->setOfflineWebApplicationCacheEnabled(application_cache_enabled); - settings->setHTML5ParserEnabled(enable_html5_parser); + settings->setCaretBrowsingEnabled(caret_browsing_enabled); + settings->setHyperlinkAuditingEnabled(hyperlink_auditing_enabled); // This setting affects the behavior of links in an editable region: // clicking the link should select it rather than navigate to it. @@ -87,7 +88,8 @@ void WebPreferences::Apply(WebView* web_view) const { // Enable experimental WebGL support if requested on command line // and support is compiled in. - settings->setExperimentalWebGLEnabled(experimental_webgl_enabled); + settings->setExperimentalWebGLEnabled( + WebRuntimeFeatures::isWebGLEnabled() || experimental_webgl_enabled); // Display colored borders around composited render layers if requested // on command line. @@ -96,6 +98,9 @@ void WebPreferences::Apply(WebView* web_view) const { // Enable gpu-accelerated compositing if requested on the command line. settings->setAcceleratedCompositingEnabled(accelerated_compositing_enabled); + // Enable gpu-accelerated 2d canvas if requested on the command line. + settings->setAccelerated2dCanvasEnabled(accelerated_2d_canvas_enabled); + // Enable memory info reporting to page if requested on the command line. settings->setMemoryInfoEnabled(memory_info_enabled); diff --git a/webkit/glue/webpreferences.h b/webkit/glue/webpreferences.h index 3e4f926..bc6d477 100644 --- a/webkit/glue/webpreferences.h +++ b/webkit/glue/webpreferences.h @@ -55,6 +55,8 @@ struct WebPreferences { bool databases_enabled; bool application_cache_enabled; bool tabs_to_links; + bool caret_browsing_enabled; + bool hyperlink_auditing_enabled; bool user_style_sheet_enabled; GURL user_style_sheet_location; @@ -64,7 +66,7 @@ struct WebPreferences { bool experimental_webgl_enabled; bool show_composited_layer_borders; bool accelerated_compositing_enabled; - bool enable_html5_parser; + bool accelerated_2d_canvas_enabled; bool memory_info_enabled; // We try to keep the default values the same as the default values in @@ -103,6 +105,8 @@ struct WebPreferences { databases_enabled(false), application_cache_enabled(false), tabs_to_links(true), + caret_browsing_enabled(false), + hyperlink_auditing_enabled(false), user_style_sheet_enabled(false), author_and_user_styles_enabled(true), allow_universal_access_from_file_urls(false), @@ -110,7 +114,7 @@ struct WebPreferences { experimental_webgl_enabled(false), show_composited_layer_borders(false), accelerated_compositing_enabled(false), - enable_html5_parser(true), + accelerated_2d_canvas_enabled(false), memory_info_enabled(false) { } diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc index f235734..aa63fc2 100644 --- a/webkit/glue/weburlloader_impl.cc +++ b/webkit/glue/weburlloader_impl.cc @@ -132,6 +132,8 @@ ResourceType::Type FromTargetType(WebURLRequest::TargetType type) { return ResourceType::WORKER; case WebURLRequest::TargetIsSharedWorker: return ResourceType::SHARED_WORKER; + case WebURLRequest::TargetIsPrefetch: + return ResourceType::PREFETCH; default: NOTREACHED(); return ResourceType::SUB_RESOURCE; @@ -182,6 +184,7 @@ void PopulateURLResponse( response->setWasFetchedViaProxy(info.was_fetched_via_proxy); response->setConnectionID(info.connection_id); response->setConnectionReused(info.connection_reused); + response->setDownloadFilePath(FilePathToWebString(info.download_file_path)); WebURLLoadTiming timing; timing.initialize(); @@ -213,7 +216,7 @@ void PopulateURLResponse( // pass it to GetSuggestedFilename. std::string value; if (headers->EnumerateHeader(NULL, "content-disposition", &value)) { - response->setSuggestedFileName(webkit_glue::FilePathToWebString( + response->setSuggestedFileName(FilePathToWebString( net::GetSuggestedFilename(url, value, "", FilePath()))); } @@ -260,10 +263,13 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, GURL* new_first_party_for_cookies); virtual void OnReceivedResponse( const ResourceLoaderBridge::ResponseInfo& info, bool content_filtered); + virtual void OnDownloadedData(int len); virtual void OnReceivedData(const char* data, int len); virtual void OnReceivedCachedMetadata(const char* data, int len); virtual void OnCompletedRequest( - const URLRequestStatus& status, const std::string& security_info); + const URLRequestStatus& status, + const std::string& security_info, + const base::Time& completion_time); virtual GURL GetURLForDebugging() const; private: @@ -278,6 +284,7 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, scoped_ptr<ResourceLoaderBridge> bridge_; scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; scoped_ptr<MultipartResponseDelegate> multipart_delegate_; + scoped_ptr<ResourceLoaderBridge> completed_bridge_; // TODO(japhet): Storing this is a temporary hack for site isolation logging. WebURL response_url_; @@ -384,7 +391,7 @@ void WebURLLoaderImpl::Context::Start( // TODO(brettw) this should take parameter encoding into account when // creating the GURLs. - webkit_glue::ResourceLoaderBridge::RequestInfo request_info; + ResourceLoaderBridge::RequestInfo request_info; request_info.method = method; request_info.url = url; request_info.first_party_for_cookies = request.firstPartyForCookies(); @@ -397,6 +404,7 @@ void WebURLLoaderImpl::Context::Start( request_info.request_type = FromTargetType(request.targetType()); request_info.appcache_host_id = request.appCacheHostID(); request_info.routing_id = request.requestorID(); + request_info.download_to_file = request.downloadToFile(); bridge_.reset(ResourceLoaderBridge::Create(request_info)); if (!request.httpBody().isNull()) { @@ -424,9 +432,12 @@ void WebURLLoaderImpl::Context::Start( WebStringToFilePath(element.filePath), static_cast<uint64>(element.fileStart), static_cast<uint64>(element.fileLength), - base::Time::FromDoubleT(element.fileInfo.modificationTime)); + base::Time::FromDoubleT(element.modificationTime)); } break; + case WebHTTPBody::Element::TypeBlob: + bridge_->AppendBlobToUpload(GURL(element.blobURL)); + break; default: NOTREACHED(); } @@ -545,6 +556,11 @@ void WebURLLoaderImpl::Context::OnReceivedResponse( response_url_ = response.url(); } +void WebURLLoaderImpl::Context::OnDownloadedData(int len) { + if (client_) + client_->didDownloadData(loader_, len); +} + void WebURLLoaderImpl::Context::OnReceivedData(const char* data, int len) { if (!client_) return; @@ -573,7 +589,8 @@ void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( void WebURLLoaderImpl::Context::OnCompletedRequest( const URLRequestStatus& status, - const std::string& security_info) { + const std::string& security_info, + const base::Time& completion_time) { if (ftp_listing_delegate_.get()) { ftp_listing_delegate_->OnCompletedRequest(); ftp_listing_delegate_.reset(NULL); @@ -582,8 +599,10 @@ void WebURLLoaderImpl::Context::OnCompletedRequest( multipart_delegate_.reset(NULL); } - // Prevent any further IPC to the browser now that we're complete. - bridge_.reset(); + // Prevent any further IPC to the browser now that we're complete, but + // don't delete it to keep any downloaded temp files alive. + DCHECK(!completed_bridge_.get()); + completed_bridge_.swap(bridge_); if (client_) { if (status.status() != URLRequestStatus::SUCCESS) { @@ -601,7 +620,7 @@ void WebURLLoaderImpl::Context::OnCompletedRequest( error.unreachableURL = request_.url(); client_->didFail(loader_, error); } else { - client_->didFinishLoading(loader_); + client_->didFinishLoading(loader_, completion_time.ToDoubleT()); } } @@ -629,7 +648,7 @@ void WebURLLoaderImpl::Context::HandleDataURL() { OnReceivedData(data.data(), data.size()); } - OnCompletedRequest(status, info.security_info); + OnCompletedRequest(status, info.security_info, base::Time::Now()); } // WebURLLoaderImpl ----------------------------------------------------------- diff --git a/webkit/glue/webvideoframe_impl.cc b/webkit/glue/webvideoframe_impl.cc new file mode 100644 index 0000000..f50eded --- /dev/null +++ b/webkit/glue/webvideoframe_impl.cc @@ -0,0 +1,96 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/webvideoframe_impl.h" + +#include "media/base/video_frame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebVideoFrame.h" + +using namespace WebKit; + +namespace webkit_glue { + +media::VideoFrame* WebVideoFrameImpl::toVideoFrame( + WebVideoFrame* web_video_frame) { + WebVideoFrameImpl* wrapped_frame = + static_cast<WebVideoFrameImpl*>(web_video_frame); + if (wrapped_frame) + return wrapped_frame->video_frame_.get(); + return NULL; +} + +WebVideoFrameImpl::WebVideoFrameImpl( + scoped_refptr<media::VideoFrame> video_frame) + : video_frame_(video_frame) { +} + +#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \ + COMPILE_ASSERT(int(WebKit::WebVideoFrame::webkit_name) == \ + int(media::VideoFrame::chromium_name), \ + mismatching_enums) +COMPILE_ASSERT_MATCHING_ENUM(FormatInvalid, INVALID); +COMPILE_ASSERT_MATCHING_ENUM(FormatRGB555, RGB555); +COMPILE_ASSERT_MATCHING_ENUM(FormatRGB565, RGB565); +COMPILE_ASSERT_MATCHING_ENUM(FormatRGB24, RGB24); +COMPILE_ASSERT_MATCHING_ENUM(FormatRGB32, RGB32); +COMPILE_ASSERT_MATCHING_ENUM(FormatRGBA, RGBA); +COMPILE_ASSERT_MATCHING_ENUM(FormatYV12, YV12); +COMPILE_ASSERT_MATCHING_ENUM(FormatYV16, YV16); +COMPILE_ASSERT_MATCHING_ENUM(FormatNV12, NV12); +COMPILE_ASSERT_MATCHING_ENUM(FormatEmpty, EMPTY); +COMPILE_ASSERT_MATCHING_ENUM(FormatASCII, ASCII); + +COMPILE_ASSERT_MATCHING_ENUM(SurfaceTypeSystemMemory, TYPE_SYSTEM_MEMORY); +// TODO(hclam): Add checks for newly added surface types like GL texture and +// D3D texture. + +WebVideoFrame::SurfaceType WebVideoFrameImpl::surfaceType() const { + if (video_frame_.get()) + return static_cast<WebVideoFrame::SurfaceType>(video_frame_->type()); + return WebVideoFrame::SurfaceTypeSystemMemory; +} + +WebVideoFrame::Format WebVideoFrameImpl::format() const { + if (video_frame_.get()) + return static_cast<WebVideoFrame::Format>(video_frame_->format()); + return WebVideoFrame::FormatInvalid; +} + +unsigned WebVideoFrameImpl::width() const { + if (video_frame_.get()) + return video_frame_->width(); + return 0; +} + +unsigned WebVideoFrameImpl::height() const { + if (video_frame_.get()) + return video_frame_->height(); + return 0; +} + +unsigned WebVideoFrameImpl::planes() const { + if (video_frame_.get()) + return video_frame_->planes(); + return 0; +} + +int WebVideoFrameImpl::stride(unsigned plane) const { + if (video_frame_.get()) + return static_cast<int>(video_frame_->stride(plane)); + return 0; +} + +const void* WebVideoFrameImpl::data(unsigned plane) const { + if (video_frame_.get()) + return static_cast<const void*>(video_frame_->data(plane)); + return NULL; +} + +unsigned WebVideoFrameImpl::texture(unsigned plane) const { + if (video_frame_.get()) + return video_frame_->gl_texture(plane); + return NULL; +} + +} // namespace webkit_glue diff --git a/webkit/glue/webvideoframe_impl.h b/webkit/glue/webvideoframe_impl.h new file mode 100644 index 0000000..dfaac03 --- /dev/null +++ b/webkit/glue/webvideoframe_impl.h @@ -0,0 +1,37 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_GLUE_WEBVIDEOFRAME_IMPL_H_ +#define WEBKIT_GLUE_WEBVIDEOFRAME_IMPL_H_ + +#include "media/base/video_frame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebVideoFrame.h" + +using namespace WebKit; + +namespace webkit_glue { + +class WebVideoFrameImpl : public WebVideoFrame { + public: + // This converts a WebKit::WebVideoFrame to a media::VideoFrame. + static media::VideoFrame* toVideoFrame(WebVideoFrame* web_video_frame); + + WebVideoFrameImpl(scoped_refptr<media::VideoFrame> video_frame); + virtual WebVideoFrame::SurfaceType surfaceType() const; + virtual WebVideoFrame::Format format() const; + virtual unsigned width() const; + virtual unsigned height() const; + virtual unsigned planes() const; + virtual int stride(unsigned plane) const; + virtual const void* data(unsigned plane) const; + virtual unsigned texture(unsigned plane) const; + + private: + scoped_refptr<media::VideoFrame> video_frame_; + DISALLOW_COPY_AND_ASSIGN(WebVideoFrameImpl); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBVIDEOFRAME_IMPL_H_ |