diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/WebProcess/Plugins | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebKit2/WebProcess/Plugins')
40 files changed, 3268 insertions, 1004 deletions
diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp index d816cdce8..aeda99ddb 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,7 +43,7 @@ namespace WebKit { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSNPMethod); -const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPMethod) }; +const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(JSNPMethod) }; JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIdentifier npIdentifier) : InternalFunction(globalObject->vm(), structure) @@ -54,17 +54,20 @@ JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIde void JSNPMethod::finishCreation(VM& vm, const String& name) { Base::finishCreation(vm, name); - ASSERT(inherits(info())); + ASSERT(inherits(vm, info())); } static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) { - JSNPMethod* jsNPMethod = jsCast<JSNPMethod*>(exec->callee()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); - JSValue thisValue = exec->hostThisValue(); + JSNPMethod* jsNPMethod = jsCast<JSNPMethod*>(exec->jsCallee()); + + JSValue thisValue = exec->thisValue(); // Check if we're calling a method on the plug-in script object. - if (thisValue.inherits(JSHTMLElement::info())) { + if (thisValue.inherits(vm, JSHTMLElement::info())) { JSHTMLElement* element = jsCast<JSHTMLElement*>(asObject(thisValue)); // Try to get the script object from the element @@ -72,19 +75,19 @@ static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) thisValue = scriptObject; } - if (thisValue.inherits(JSNPObject::info())) { + if (thisValue.inherits(vm, JSNPObject::info())) { JSNPObject* jsNPObject = jsCast<JSNPObject*>(asObject(thisValue)); return JSValue::encode(jsNPObject->callMethod(exec, jsNPMethod->npIdentifier())); } - return throwVMTypeError(exec); + return throwVMTypeError(exec, scope); } CallType JSNPMethod::getCallData(JSCell*, CallData& callData) { callData.native.function = callMethod; - return CallTypeHost; + return CallType::Host; } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp index 9674ca3e9..d68974d0b 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,10 +32,13 @@ #include "NPJSObject.h" #include "NPRuntimeObjectMap.h" #include "NPRuntimeUtilities.h" +#include <JavaScriptCore/AuxiliaryBarrierInlines.h> #include <JavaScriptCore/Error.h> +#include <JavaScriptCore/IdentifierInlines.h> #include <JavaScriptCore/JSGlobalObject.h> #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/ObjectPrototype.h> +#include <WebCore/CommonVM.h> #include <WebCore/IdentifierRep.h> #include <WebCore/JSDOMWindowBase.h> #include <wtf/Assertions.h> @@ -49,12 +52,13 @@ namespace WebKit { static NPIdentifier npIdentifierFromIdentifier(PropertyName propertyName) { String name(propertyName.publicName()); + // If the propertyName is Symbol. if (name.isNull()) - return 0; + return nullptr; return static_cast<NPIdentifier>(IdentifierRep::get(name.utf8().data())); } -const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) }; +const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSNPObject) }; JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRuntimeObjectMap* objectMap, NPObject* npObject) : JSDestructibleObject(globalObject->vm(), structure) @@ -66,8 +70,9 @@ JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRun void JSNPObject::finishCreation(JSGlobalObject* globalObject) { - Base::finishCreation(globalObject->vm()); - ASSERT(inherits(info())); + VM& vm = globalObject->vm(); + Base::finishCreation(vm); + ASSERT(inherits(vm, info())); // We should never have an NPJSObject inside a JSNPObject. ASSERT(!NPJSObject::isNPJSObject(m_npObject)); @@ -89,7 +94,6 @@ void JSNPObject::destroy(JSCell* cell) void JSNPObject::invalidate() { ASSERT(m_npObject); - ASSERT_GC_OBJECT_INHERITS(this, info()); releaseNPObject(m_npObject); m_npObject = 0; @@ -106,9 +110,16 @@ NPObject* JSNPObject::leakNPObject() JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); if (!m_npObject) - return throwInvalidAccessError(exec); + return throwInvalidAccessError(exec, scope); + + // If the propertyName is symbol. + if (!methodName) + return jsUndefined(); size_t argumentCount = exec->argumentCount(); Vector<NPVariant, 8> arguments(argumentCount); @@ -127,17 +138,17 @@ JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) VOID_TO_NPVARIANT(result); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); returnValue = m_npObject->_class->invoke(m_npObject, methodName, arguments.data(), argumentCount, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } - // Release all arguments; + // Release all arguments. for (size_t i = 0; i < argumentCount; ++i) releaseNPVariantValue(&arguments[i]); if (!returnValue) - exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject.")); + throwException(exec, scope, createError(exec, "Error calling method on NPObject.")); JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); releaseNPVariantValue(&result); @@ -146,9 +157,12 @@ JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); if (!m_npObject) - return throwInvalidAccessError(exec); + return throwInvalidAccessError(exec, scope); size_t argumentCount = exec->argumentCount(); Vector<NPVariant, 8> arguments(argumentCount); @@ -167,7 +181,7 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) VOID_TO_NPVARIANT(result); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), argumentCount, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } @@ -177,7 +191,7 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) releaseNPVariantValue(&arguments[i]); if (!returnValue) - exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject.")); + throwException(exec, scope, createError(exec, "Error calling method on NPObject.")); JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); releaseNPVariantValue(&result); @@ -186,9 +200,12 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) JSValue JSNPObject::callConstructor(ExecState* exec) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); if (!m_npObject) - return throwInvalidAccessError(exec); + return throwInvalidAccessError(exec, scope); size_t argumentCount = exec->argumentCount(); Vector<NPVariant, 8> arguments(argumentCount); @@ -207,13 +224,13 @@ JSValue JSNPObject::callConstructor(ExecState* exec) VOID_TO_NPVARIANT(result); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), argumentCount, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } if (!returnValue) - exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject.")); + throwException(exec, scope, createError(exec, "Error calling method on NPObject.")); JSValue value = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); releaseNPVariantValue(&result); @@ -222,8 +239,8 @@ JSValue JSNPObject::callConstructor(ExecState* exec) static EncodedJSValue JSC_HOST_CALL callNPJSObject(ExecState* exec) { - JSObject* object = exec->callee(); - ASSERT(object->inherits(JSNPObject::info())); + JSObject* object = exec->jsCallee(); + ASSERT(object->inherits(exec->vm(), JSNPObject::info())); return JSValue::encode(jsCast<JSNPObject*>(object)->callObject(exec)); } @@ -233,16 +250,16 @@ JSC::CallType JSNPObject::getCallData(JSC::JSCell* cell, JSC::CallData& callData JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject || !thisObject->m_npObject->_class->invokeDefault) - return CallTypeNone; + return CallType::None; callData.native.function = callNPJSObject; - return CallTypeHost; + return CallType::Host; } static EncodedJSValue JSC_HOST_CALL constructWithConstructor(ExecState* exec) { - JSObject* constructor = exec->callee(); - ASSERT(constructor->inherits(JSNPObject::info())); + JSObject* constructor = exec->jsCallee(); + ASSERT(constructor->inherits(exec->vm(), JSNPObject::info())); return JSValue::encode(jsCast<JSNPObject*>(constructor)->callConstructor(exec)); } @@ -252,22 +269,28 @@ ConstructType JSNPObject::getConstructData(JSCell* cell, ConstructData& construc JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject || !thisObject->m_npObject->_class->construct) - return ConstructTypeNone; + return ConstructType::None; constructData.native.function = constructWithConstructor; - return ConstructTypeHost; + return ConstructType::Host; } bool JSNPObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(object); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject) { - throwInvalidAccessError(exec); + throwInvalidAccessError(exec, scope); return false; } NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return false; // Calling NPClass::invoke will call into plug-in code, and there's no telling what the plug-in can do. // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until @@ -289,24 +312,30 @@ bool JSNPObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyN return false; } -void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot&) +bool JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot&) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject) { - throwInvalidAccessError(exec); - return; + throwInvalidAccessError(exec, scope); + return false; } NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return false; if (!thisObject->m_npObject->_class->hasProperty || !thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) { // FIXME: Should we throw an exception here? - return; + return false; } if (!thisObject->m_npObject->_class->setProperty) - return; + return false; NPVariant variant; thisObject->m_objectMap->convertJSValueToNPVariant(exec, value, variant); @@ -316,9 +345,10 @@ void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J // the call has finished. NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap); + bool result = false; { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); - thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant); + JSLock::DropAllLocks dropAllLocks(commonVM()); + result = thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); @@ -326,6 +356,7 @@ void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J } releaseNPVariantValue(&variant); + return result; } bool JSNPObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) @@ -340,9 +371,17 @@ bool JSNPObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned p bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); + + // If the propertyName is symbol. + if (!propertyName) + return false; + if (!m_npObject) { - throwInvalidAccessError(exec); + throwInvalidAccessError(exec, scope); return false; } @@ -357,7 +396,7 @@ bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) NPRuntimeObjectMap::PluginProtector protector(m_objectMap); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); // FIXME: Should we throw an exception if removeProperty returns false? if (!m_npObject->_class->removeProperty(m_npObject, propertyName)) @@ -371,10 +410,13 @@ bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNameArray, EnumerationMode) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSNPObject* thisObject = jsCast<JSNPObject*>(object); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject) { - throwInvalidAccessError(exec); + throwInvalidAccessError(exec, scope); return; } @@ -390,7 +432,7 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); // FIXME: Should we throw an exception if enumerate returns false? if (!thisObject->m_npObject->_class->enumerate(thisObject->m_npObject, &identifiers, &identifierCount)) @@ -407,7 +449,7 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property const char* string = identifierRep->string(); int length = strlen(string); - identifier = Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl()); + identifier = Identifier::fromString(exec, String::fromUTF8WithLatin1Fallback(string, length)); } else identifier = Identifier::from(exec, identifierRep->number()); @@ -417,13 +459,16 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property npnMemFree(identifiers); } -EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, PropertyName propertyName) +EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName) { - JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(slotBase)); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(thisValue)); ASSERT_GC_OBJECT_INHERITS(thisObj, info()); if (!thisObj->m_npObject) - return JSValue::encode(throwInvalidAccessError(exec)); + return JSValue::encode(throwInvalidAccessError(exec, scope)); if (!thisObj->m_npObject->_class->getProperty) return JSValue::encode(jsUndefined()); @@ -438,8 +483,12 @@ EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue slotBa bool returnValue; { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return JSValue::encode(jsUndefined()); + returnValue = thisObj->m_npObject->_class->getProperty(thisObj->m_npObject, npIdentifier, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); @@ -453,21 +502,28 @@ EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue slotBa return JSValue::encode(propertyValue); } -EncodedJSValue JSNPObject::methodGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, PropertyName propertyName) +EncodedJSValue JSNPObject::methodGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName) { - JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(slotBase)); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(thisValue)); ASSERT_GC_OBJECT_INHERITS(thisObj, info()); if (!thisObj->m_npObject) - return JSValue::encode(throwInvalidAccessError(exec)); + return JSValue::encode(throwInvalidAccessError(exec, scope)); NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return JSValue::encode(throwInvalidAccessError(exec, scope)); + return JSValue::encode(JSNPMethod::create(exec, thisObj->globalObject(), propertyName.publicName(), npIdentifier)); } -JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec) +JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec, ThrowScope& scope) { - return exec->vm().throwException(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); + return throwException(exec, scope, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h index 250d26b0f..b09e90f9b 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h @@ -44,6 +44,7 @@ class NPRuntimeObjectMap; class JSNPObject : public JSC::JSDestructibleObject { public: typedef JSC::JSDestructibleObject Base; + static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSC::TypeOfShouldCallGetCallData; static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject) { @@ -74,8 +75,6 @@ protected: private: JSNPObject(JSC::JSGlobalObject*, JSC::Structure*, NPRuntimeObjectMap*, NPObject*); - - static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) { @@ -86,7 +85,7 @@ private: static JSC::ConstructType getConstructData(JSC::JSCell*, JSC::ConstructData&); static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&); - static void put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&); + static bool put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&); static bool deleteProperty(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName); static bool deletePropertyByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName); @@ -95,9 +94,9 @@ private: static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode); - static JSC::EncodedJSValue propertyGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::PropertyName); - static JSC::EncodedJSValue methodGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::PropertyName); - static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*); + static JSC::EncodedJSValue propertyGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); + static JSC::EncodedJSValue methodGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); + static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*, JSC::ThrowScope&); NPRuntimeObjectMap* m_objectMap; NPObject* m_npObject; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp index f33574018..aa75a920d 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp @@ -31,12 +31,11 @@ #include "JSNPObject.h" #include "NPRuntimeObjectMap.h" #include "NPRuntimeUtilities.h" -#include <JavaScriptCore/JSCJSValueInlines.h> +#include <JavaScriptCore/JSCInlines.h> #include <JavaScriptCore/JSCellInlines.h> #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/JSObject.h> #include <JavaScriptCore/StrongInlines.h> -#include <JavaScriptCore/StructureInlines.h> #include <WebCore/Frame.h> #include <WebCore/IdentifierRep.h> #include <wtf/text/WTFString.h> @@ -49,7 +48,7 @@ namespace WebKit { NPJSObject* NPJSObject::create(VM& vm, NPRuntimeObjectMap* objectMap, JSObject* jsObject) { // We should never have a JSNPObject inside an NPJSObject. - ASSERT(!jsObject->inherits(JSNPObject::info())); + ASSERT(!jsObject->inherits(vm, JSNPObject::info())); NPJSObject* npJSObject = toNPJSObject(createNPObject(0, npClass())); npJSObject->initialize(vm, objectMap, jsObject); @@ -88,7 +87,7 @@ static Identifier identifierFromIdentifierRep(ExecState* exec, IdentifierRep* id const char* string = identifierRep->string(); int length = strlen(string); - return Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl()); + return Identifier::fromString(exec, String::fromUTF8WithLatin1Fallback(string, length)); } bool NPJSObject::hasMethod(NPIdentifier methodName) @@ -102,13 +101,15 @@ bool NPJSObject::hasMethod(NPIdentifier methodName) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); JSValue value = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); - exec->clearException(); + scope.clearException(); CallData callData; - return getCallData(value, callData) != CallTypeNone; + return getCallData(value, callData) != CallType::None; } bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) @@ -148,7 +149,9 @@ bool NPJSObject::hasProperty(NPIdentifier identifier) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); bool result; if (identifierRep->isString()) @@ -156,7 +159,7 @@ bool NPJSObject::hasProperty(NPIdentifier identifier) else result = m_jsObject->hasProperty(exec, identifierRep->number()); - exec->clearException(); + scope.clearException(); return result; } @@ -168,7 +171,10 @@ bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + JSValue jsResult; if (identifierRep->isString()) jsResult = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); @@ -176,7 +182,7 @@ bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result) jsResult = m_jsObject->get(exec, identifierRep->number()); m_objectMap->convertJSValueToNPVariant(exec, jsResult, *result); - exec->clearException(); + scope.clearException(); return true; } @@ -188,7 +194,9 @@ bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); JSValue jsValue = m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), *value); if (identifierRep->isString()) { @@ -196,7 +204,7 @@ bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value) m_jsObject->methodTable()->put(m_jsObject.get(), exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot); } else m_jsObject->methodTable()->putByIndex(m_jsObject.get(), exec, identifierRep->number(), jsValue, false); - exec->clearException(); + scope.clearException(); return true; } @@ -209,26 +217,29 @@ bool NPJSObject::removeProperty(NPIdentifier propertyName) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + if (identifierRep->isString()) { Identifier identifier = identifierFromIdentifierRep(exec, identifierRep); if (!m_jsObject->hasProperty(exec, identifier)) { - exec->clearException(); + scope.clearException(); return false; } m_jsObject->methodTable()->deleteProperty(m_jsObject.get(), exec, identifier); } else { if (!m_jsObject->hasProperty(exec, identifierRep->number())) { - exec->clearException(); + scope.clearException(); return false; } m_jsObject->methodTable()->deletePropertyByIndex(m_jsObject.get(), exec, identifierRep->number()); } - exec->clearException(); + scope.clearException(); return true; } @@ -240,8 +251,8 @@ bool NPJSObject::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount JSLockHolder lock(exec); - PropertyNameArray propertyNames(exec); - m_jsObject->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, ExcludeDontEnumProperties); + PropertyNameArray propertyNames(exec, PropertyNameMode::Strings); + m_jsObject->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, EnumerationMode()); NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(propertyNames.size()); @@ -260,11 +271,13 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); ConstructData constructData; ConstructType constructType = getConstructData(m_jsObject.get(), constructData); - if (constructType == ConstructTypeNone) + if (constructType == ConstructType::None) return false; // Convert the passed in arguments. @@ -276,16 +289,19 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N // Convert and return the new object. m_objectMap->convertJSValueToNPVariant(exec, value, *result); - exec->clearException(); + scope.clearException(); return true; } bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { + VM& vm = exec->vm(); + auto scope = DECLARE_CATCH_SCOPE(vm); + CallData callData; CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) + if (callType == CallType::None) return false; // Convert the passed in arguments. @@ -295,9 +311,18 @@ bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue f JSValue value = JSC::call(exec, function, callType, callData, m_jsObject.get(), argumentList); + if (UNLIKELY(scope.exception())) { + scope.clearException(); + return false; + } + // Convert and return the result of the function call. m_objectMap->convertJSValueToNPVariant(exec, value, *result); - exec->clearException(); + + if (UNLIKELY(scope.exception())) { + scope.clearException(); + return false; + } return true; } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp index 8b16ca528..2db8bb446 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,8 +41,6 @@ #include <JavaScriptCore/StrongInlines.h> #include <WebCore/DOMWrapperWorld.h> #include <WebCore/Frame.h> -#include <WebCore/Page.h> -#include <WebCore/PageThrottler.h> #include <WebCore/ScriptController.h> #include <wtf/NeverDestroyed.h> @@ -72,7 +70,7 @@ NPRuntimeObjectMap::PluginProtector::~PluginProtector() NPObject* NPRuntimeObjectMap::getOrCreateNPObject(VM& vm, JSObject* jsObject) { // If this is a JSNPObject, we can just get its underlying NPObject. - if (jsObject->classInfo() == JSNPObject::info()) { + if (jsObject->classInfo(vm) == JSNPObject::info()) { JSNPObject* jsNPObject = jsCast<JSNPObject*>(jsObject); NPObject* npObject = jsNPObject->npObject(); @@ -189,17 +187,12 @@ bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String& scriptString if (!globalObject) return false; - if (m_pluginView && !m_pluginView->isBeingDestroyed()) { - if (Page* page = m_pluginView->frame()->page()) - page->pageThrottler().reportInterestingEvent(); - } - ExecState* exec = globalObject->globalExec(); JSLockHolder lock(exec); JSValue thisValue = getOrCreateJSObject(globalObject.get(), npObject); - JSValue resultValue = JSC::evaluate(exec, makeSource(scriptString), thisValue); + JSValue resultValue = JSC::evaluate(exec, makeSource(scriptString, { }), thisValue); convertJSValueToNPVariant(exec, resultValue, *result); return true; @@ -270,12 +263,15 @@ void NPRuntimeObjectMap::setGlobalException(const String& exceptionString) void NPRuntimeObjectMap::moveGlobalExceptionToExecState(ExecState* exec) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + if (globalExceptionString().isNull()) return; { - JSLockHolder lock(exec); - exec->vm().throwException(exec, createError(exec, globalExceptionString())); + JSLockHolder lock(vm); + throwException(exec, scope, createError(exec, globalExceptionString())); } globalExceptionString() = String(); @@ -303,7 +299,7 @@ void NPRuntimeObjectMap::addToInvalidationQueue(NPObject* npObject) void NPRuntimeObjectMap::finalize(JSC::Handle<JSC::Unknown> handle, void* context) { - JSNPObject* object = jsCast<JSNPObject*>(handle.get().asCell()); + JSNPObject* object = static_cast<JSNPObject*>(handle.get().asCell()); weakRemove(m_jsNPObjects, static_cast<NPObject*>(context), object); addToInvalidationQueue(object->leakNPObject()); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h index fade41df5..85509ab49 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h @@ -90,7 +90,7 @@ public: private: // WeakHandleOwner - virtual void finalize(JSC::Handle<JSC::Unknown>, void* context); + void finalize(JSC::Handle<JSC::Unknown>, void* context) override; void addToInvalidationQueue(NPObject*); void invalidateQueuedObjects(); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp index f1f3d1878..00bd6cd83 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp @@ -32,13 +32,23 @@ #include "NetscapePlugin.h" #include "PluginController.h" #include <WebCore/HTTPHeaderMap.h> +#include <WebCore/HTTPHeaderNames.h> #include <WebCore/IdentifierRep.h> #include <WebCore/NotImplemented.h> #include <WebCore/ProtectionSpace.h> #include <WebCore/SharedBuffer.h> +#include <memory> #include <utility> #include <wtf/text/StringBuilder.h> +#if PLATFORM(COCOA) +#include <WebCore/MachSendRight.h> +#endif + +#if PLUGIN_ARCHITECTURE(X11) +#include <WebCore/PlatformDisplayX11.h> +#endif + using namespace WebCore; namespace WebKit { @@ -49,11 +59,11 @@ public: explicit PluginDestructionProtector(NetscapePlugin* plugin) { if (plugin) - m_protector = adoptPtr(new PluginController::PluginDestructionProtector(static_cast<Plugin*>(plugin)->controller())); + m_protector = std::make_unique<PluginController::PluginDestructionProtector>(static_cast<Plugin*>(plugin)->controller()); } private: - OwnPtr<PluginController::PluginDestructionProtector> m_protector; + std::unique_ptr<PluginController::PluginDestructionProtector> m_protector; }; static bool startsWithBlankLine(const char* bytes, unsigned length) @@ -121,25 +131,13 @@ static String capitalizeRFC822HeaderFieldName(const String& name) { bool capitalizeCharacter = true; StringBuilder result; - for (unsigned i = 0; i < name.length(); i++) { - UChar c; - - if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z') - c = toASCIIUpper(name[i]); - else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z') - c = toASCIILower(name[i]); - else - c = name[i]; - + result.append(capitalizeCharacter ? toASCIIUpper(name[i]) : toASCIILower(name[i])); if (name[i] == '-') capitalizeCharacter = true; else capitalizeCharacter = false; - - result.append(c); } - return result.toString(); } @@ -195,7 +193,7 @@ static HTTPHeaderMap parseRFC822HeaderFields(const char* bytes, unsigned length) break; } if (colon == endOfLine) - value = ""; + value = emptyString(); else value = String(colon, endOfLine - colon); @@ -244,15 +242,14 @@ static NPError parsePostBuffer(bool isFile, const char *buffer, uint32_t length, // Sometimes plugins like to set Content-Length themselves when they post, // but WebFoundation does not like that. So we will remove the header // and instead truncate the data to the requested length. - String contentLength = headerFields.get("Content-Length"); + String contentLength = headerFields.get(HTTPHeaderName::ContentLength); if (!contentLength.isNull()) dataLength = std::min(contentLength.toInt(), (int)dataLength); - headerFields.remove("Content-Length"); + headerFields.remove(HTTPHeaderName::ContentLength); postBuffer += location; postBufferSize = dataLength; - } } } @@ -298,7 +295,7 @@ static NPError NPN_PostURL(NPP npp, const char* url, const char* target, uint32_ return error; RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, false, 0); + plugin->loadURL("POST", makeURLString(url), target, WTFMove(headerFields), postData, false, 0); return NPERR_NO_ERROR; } @@ -331,7 +328,7 @@ static void NPN_Status(NPP npp, const char* message) { String statusbarText; if (!message) - statusbarText = ""; + statusbarText = emptyString(); else statusbarText = String::fromUTF8WithLatin1Fallback(message, strlen(message)); @@ -400,7 +397,7 @@ static NPError NPN_PostURLNotify(NPP npp, const char* url, const char* target, u return NPERR_NO_ERROR; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // Whether the browser supports compositing of Core Animation plug-ins. static const unsigned WKNVSupportsCompositingCoreAnimationPluginsBool = 74656; @@ -409,8 +406,6 @@ static const unsigned WKNVExpectsNonretainedLayer = 74657; // 74658 and 74659 are no longer implemented. -static const unsigned WKNVPlugInContainer = 74660; - #endif static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) @@ -441,7 +436,13 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) *(NPBool*)value = plugin->isPrivateBrowsingEnabled(); break; } -#if PLATFORM(MAC) + + case NPNVmuteAudioBool: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + *(NPBool*)value = plugin->isMuted(); + break; + } +#if PLATFORM(COCOA) case NPNVsupportsCoreGraphicsBool: // Always claim to support the Core Graphics drawing model. *(NPBool*)value = true; @@ -482,7 +483,7 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) case WKNVCALayerRenderServerPort: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - *(mach_port_t*)value = plugin->compositingRenderServerPort(); + *(mach_port_t*)value = plugin->compositingRenderServerPort().sendRight(); break; } @@ -495,12 +496,6 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) break; } - case WKNVPlugInContainer: { - RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - *reinterpret_cast<void**>(value) = plugin->plugInContainer(); - break; - } - #ifndef NP_NO_QUICKDRAW case NPNVsupportsQuickDrawBool: // We don't support the QuickDraw drawing model. @@ -513,18 +508,21 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) break; #endif #elif PLUGIN_ARCHITECTURE(X11) - case NPNVxDisplay: { - if (!npp) - return NPERR_GENERIC_ERROR; - *reinterpret_cast<Display**>(value) = NetscapePlugin::x11HostDisplay(); - break; - } - case NPNVSupportsXEmbedBool: - *static_cast<NPBool*>(value) = true; - break; - case NPNVSupportsWindowless: - *static_cast<NPBool*>(value) = true; - break; + case NPNVxDisplay: { + if (!npp) + return NPERR_GENERIC_ERROR; + auto& display = PlatformDisplay::sharedDisplay(); + if (display.type() != PlatformDisplay::Type::X11) + return NPERR_GENERIC_ERROR; + *reinterpret_cast<Display**>(value) = downcast<PlatformDisplayX11>(display).native(); + break; + } + case NPNVSupportsXEmbedBool: + *static_cast<NPBool*>(value) = PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11; + break; + case NPNVSupportsWindowless: + *static_cast<NPBool*>(value) = true; + break; case NPNVToolkit: { // Gtk based plugins need to be assured about the toolkit version. @@ -546,7 +544,7 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value) { switch (variable) { -#if PLATFORM(MAC) +#if PLATFORM(COCOA) case NPPVpluginDrawingModel: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); @@ -574,6 +572,12 @@ static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value) return NPERR_NO_ERROR; } + case NPPVpluginIsPlayingAudio: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->setIsPlayingAudio(value); + return NPERR_NO_ERROR; + } + default: notImplemented(); return NPERR_GENERIC_ERROR; @@ -940,7 +944,7 @@ static void NPN_UnscheduleTimer(NPP npp, uint32_t timerID) plugin->unscheduleTimer(timerID); } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) static NPError NPN_PopUpContextMenu(NPP npp, NPMenu* menu) { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); @@ -966,6 +970,13 @@ static NPBool NPN_ConvertPoint(NPP npp, double sourceX, double sourceY, NPCoordi } #endif +static void NPN_URLRedirectResponse(NPP npp, void* notifyData, NPBool allow) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + plugin->urlRedirectResponse(notifyData, allow); +} + static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs) { netscapeFuncs.size = sizeof(NPNetscapeFuncs); @@ -1022,13 +1033,14 @@ static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs) netscapeFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo; netscapeFuncs.scheduletimer = NPN_ScheduleTimer; netscapeFuncs.unscheduletimer = NPN_UnscheduleTimer; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) netscapeFuncs.popupcontextmenu = NPN_PopUpContextMenu; netscapeFuncs.convertpoint = NPN_ConvertPoint; #else netscapeFuncs.popupcontextmenu = 0; netscapeFuncs.convertpoint = 0; #endif + netscapeFuncs.urlredirectresponse = NPN_URLRedirectResponse; } NPNetscapeFuncs* netscapeBrowserFuncs() diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h index 37e61daa3..07d421fb3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h @@ -32,8 +32,10 @@ namespace WebKit { +#if PLUGIN_ARCHITECTURE(MAC) // The Core Animation render server port. static const unsigned WKNVCALayerRenderServerPort = 71879; +#endif NPNetscapeFuncs* netscapeBrowserFuncs(); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp index 5d894e754..5c9a91824 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -42,6 +42,10 @@ #include <utility> #include <wtf/text/CString.h> +#if PLUGIN_ARCHITECTURE(X11) +#include "NetscapePluginUnix.h" +#endif + using namespace WebCore; namespace WebKit { @@ -49,20 +53,21 @@ namespace WebKit { // The plug-in that we're currently calling NPP_New for. static NetscapePlugin* currentNPPNewPlugin; -PassRefPtr<NetscapePlugin> NetscapePlugin::create(PassRefPtr<NetscapePluginModule> pluginModule) +RefPtr<NetscapePlugin> NetscapePlugin::create(PassRefPtr<NetscapePluginModule> pluginModule) { if (!pluginModule) - return 0; + return nullptr; - return adoptRef(new NetscapePlugin(pluginModule)); + return adoptRef(*new NetscapePlugin(pluginModule)); } NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) - : m_nextRequestID(0) + : Plugin(NetscapePluginType) + , m_nextRequestID(0) , m_pluginModule(pluginModule) , m_npWindow() , m_isStarted(false) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) , m_isWindowed(false) #else , m_isWindowed(true) @@ -73,11 +78,11 @@ NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) , m_hasCalledSetWindow(false) , m_isVisible(false) , m_nextTimerID(0) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) , m_drawingModel(static_cast<NPDrawingModel>(-1)) , m_eventModel(static_cast<NPEventModel>(-1)) , m_pluginReturnsNonretainedLayer(!m_pluginModule->pluginQuirks().contains(PluginQuirks::ReturnsRetainedCoreAnimationLayer)) - , m_layerHostingMode(LayerHostingModeDefault) + , m_layerHostingMode(LayerHostingMode::InProcess) , m_currentMouseEvent(0) , m_pluginHasFocus(false) , m_windowHasFocus(false) @@ -89,12 +94,6 @@ NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) , m_nullEventTimer(RunLoop::main(), this, &NetscapePlugin::nullEventTimerFired) , m_npCGContext() #endif -#elif PLUGIN_ARCHITECTURE(X11) - , m_drawable(0) - , m_pluginDisplay(0) -#if PLATFORM(GTK) - , m_platformPluginWidget(0) -#endif #endif { m_npp.ndata = this; @@ -111,10 +110,10 @@ NetscapePlugin::~NetscapePlugin() m_pluginModule->decrementLoadCount(); } -PassRefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp) +RefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp) { if (!npp) - return 0; + return nullptr; return static_cast<NetscapePlugin*>(npp->ndata); } @@ -147,13 +146,6 @@ const char* NetscapePlugin::userAgent(NPP npp) const char* NetscapePlugin::userAgent() { -#if PLUGIN_ARCHITECTURE(WIN) - static const char* MozillaUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0"; - - if (quirks().contains(PluginQuirks::WantsMozillaUserAgent)) - return MozillaUserAgent; -#endif - if (m_userAgent.isNull()) { String userAgent = controller()->userAgent(); ASSERT(!userAgent.isNull()); @@ -177,10 +169,10 @@ void NetscapePlugin::loadURL(const String& method, const String& urlString, cons if (target.isNull()) { // The browser is going to send the data in a stream, create a plug-in stream. - RefPtr<NetscapePluginStream> pluginStream = NetscapePluginStream::create(this, requestID, urlString, sendNotification, notificationData); + auto pluginStream = NetscapePluginStream::create(this, requestID, urlString, sendNotification, notificationData); ASSERT(!m_streams.contains(requestID)); - m_streams.set(requestID, pluginStream.release()); + m_streams.set(requestID, WTFMove(pluginStream)); return; } @@ -254,6 +246,11 @@ bool NetscapePlugin::isPrivateBrowsingEnabled() return controller()->isPrivateBrowsingEnabled(); } +bool NetscapePlugin::isMuted() const +{ + return controller()->isMuted(); +} + NPObject* NetscapePlugin::windowScriptNPObject() { return controller()->windowScriptNPObject(); @@ -278,7 +275,7 @@ void NetscapePlugin::cancelStreamLoad(NetscapePluginStream* pluginStream) void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream) { if (pluginStream == m_manualStream) { - m_manualStream = 0; + m_manualStream = nullptr; return; } @@ -288,11 +285,7 @@ void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream) bool NetscapePlugin::isAcceleratedCompositingEnabled() { -#if USE(ACCELERATED_COMPOSITING) return controller()->isAcceleratedCompositingEnabled(); -#else - return false; -#endif } void NetscapePlugin::pushPopupsEnabledState(bool state) @@ -309,15 +302,12 @@ void NetscapePlugin::popPopupsEnabledState() void NetscapePlugin::pluginThreadAsyncCall(void (*function)(void*), void* userData) { - RunLoop::main()->dispatch(WTF::bind(&NetscapePlugin::handlePluginThreadAsyncCall, this, function, userData)); -} - -void NetscapePlugin::handlePluginThreadAsyncCall(void (*function)(void*), void* userData) -{ - if (!m_isStarted) - return; + RunLoop::main().dispatch([protectedThis = makeRef(*this), function, userData] { + if (!protectedThis->m_isStarted) + return; - function(userData); + function(userData); + }); } NetscapePlugin::Timer::Timer(NetscapePlugin* netscapePlugin, unsigned timerID, unsigned interval, bool repeat, TimerFunc timerFunc) @@ -369,7 +359,7 @@ uint32_t NetscapePlugin::scheduleTimer(unsigned interval, bool repeat, void (*ti // FIXME: Based on the plug-in visibility, figure out if we should throttle the timer, or if we should start it at all. timer->start(); - m_timers.set(timerID, std::move(timer)); + m_timers.set(timerID, WTFMove(timer)); return timerID; } @@ -403,7 +393,41 @@ void NetscapePlugin::setCookiesForURL(const String& urlString, const String& coo bool NetscapePlugin::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password) { return controller()->getAuthenticationInfo(protectionSpace, username, password); -} +} + +void NetscapePlugin::registerRedirect(NetscapePluginStream* stream, const URL& requestURL, int redirectResponseStatus, void* notificationData) +{ + // NPP_URLRedirectNotify may synchronously request this stream back out, so set it first + m_redirects.set(notificationData, std::make_pair(stream, requestURL.string())); + if (!NPP_URLRedirectNotify(requestURL.string().utf8().data(), redirectResponseStatus, notificationData)) { + m_redirects.take(notificationData); + controller()->continueStreamLoad(stream->streamID()); + } +} + +void NetscapePlugin::urlRedirectResponse(void* notifyData, bool allow) +{ + if (!m_redirects.contains(notifyData)) + return; + + auto redirect = m_redirects.take(notifyData); + if (!redirect.first) + return; + + RefPtr<NetscapePluginStream> stream = redirect.first; + if (!allow) { + controller()->cancelStreamLoad(stream->streamID()); + stream->stop(NPRES_USER_BREAK); + } else { + stream->setURL(redirect.second); + controller()->continueStreamLoad(stream->streamID()); + } +} + +void NetscapePlugin::setIsPlayingAudio(bool isPlayingAudio) +{ + controller()->setPluginIsPlayingAudio(isPlayingAudio); +} NPError NetscapePlugin::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* savedData) { @@ -455,6 +479,15 @@ void NetscapePlugin::NPP_URLNotify(const char* url, NPReason reason, void* notif m_pluginModule->pluginFuncs().urlnotify(&m_npp, url, reason, notifyData); } +bool NetscapePlugin::NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData) +{ + if (!m_pluginModule->pluginFuncs().urlredirectnotify) + return false; + + m_pluginModule->pluginFuncs().urlredirectnotify(&m_npp, url, status, notifyData); + return true; +} + NPError NetscapePlugin::NPP_GetValue(NPPVariable variable, void *value) { if (!m_pluginModule->pluginFuncs().getvalue) @@ -572,7 +605,7 @@ static bool isTransparentSilverlightBackgroundValue(const String& lowercaseBackg } } else if (lowercaseBackgroundValue.startsWith("sc#")) { Vector<String> components; - lowercaseBackgroundValue.substring(3).split(",", components); + lowercaseBackgroundValue.substring(3).split(',', components); // An ScRGB value with alpha transparency, in the form sc#A,R,G,B. if (components.size() == 4) { @@ -604,13 +637,31 @@ bool NetscapePlugin::initialize(const Parameters& parameters) #if PLUGIN_ARCHITECTURE(MAC) if (m_pluginModule->pluginQuirks().contains(PluginQuirks::WantsLowercaseParameterNames)) - parameterName = parameterName.lower(); + parameterName = parameterName.convertToASCIILowercase(); #endif paramNames.append(parameterName.utf8()); paramValues.append(parameters.values[i].utf8()); } +#if PLUGIN_ARCHITECTURE(X11) + if (equalLettersIgnoringASCIICase(parameters.mimeType, "application/x-shockwave-flash")) { + size_t wmodeIndex = parameters.names.find("wmode"); + if (wmodeIndex != notFound) { + // Transparent window mode is not supported by X11 backend. + if (equalLettersIgnoringASCIICase(parameters.values[wmodeIndex], "transparent") + || (m_pluginModule->pluginQuirks().contains(PluginQuirks::ForceFlashWindowlessMode) && equalLettersIgnoringASCIICase(parameters.values[wmodeIndex], "window"))) + paramValues[wmodeIndex] = "opaque"; + } else if (m_pluginModule->pluginQuirks().contains(PluginQuirks::ForceFlashWindowlessMode)) { + paramNames.append("wmode"); + paramValues.append("opaque"); + } + } else if (equalLettersIgnoringASCIICase(parameters.mimeType, "application/x-webkit-test-netscape")) { + paramNames.append("windowedPlugin"); + paramValues.append("false"); + } +#endif + // The strings that these pointers point to are kept alive by paramNames and paramValues. Vector<const char*> names; Vector<const char*> values; @@ -622,8 +673,8 @@ bool NetscapePlugin::initialize(const Parameters& parameters) #if PLUGIN_ARCHITECTURE(MAC) if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists)) { for (size_t i = 0; i < parameters.names.size(); ++i) { - if (equalIgnoringCase(parameters.names[i], "background")) { - setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].lower())); + if (equalLettersIgnoringASCIICase(parameters.names[i], "background")) { + setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].convertToASCIILowercase())); break; } } @@ -686,17 +737,17 @@ void NetscapePlugin::destroy() m_timers.clear(); } -void NetscapePlugin::paint(GraphicsContext* context, const IntRect& dirtyRect) +void NetscapePlugin::paint(GraphicsContext& context, const IntRect& dirtyRect) { ASSERT(m_isStarted); platformPaint(context, dirtyRect); } -PassRefPtr<ShareableBitmap> NetscapePlugin::snapshot() +RefPtr<ShareableBitmap> NetscapePlugin::snapshot() { if (!supportsSnapshotting() || m_pluginSize.isEmpty()) - return 0; + return nullptr; ASSERT(m_isStarted); @@ -708,11 +759,11 @@ PassRefPtr<ShareableBitmap> NetscapePlugin::snapshot() // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI // which we currently don't have initiated in the plug-in process. - context->scale(FloatSize(contentsScaleFactor(), contentsScaleFactor())); + context->scale(contentsScaleFactor()); - platformPaint(context.get(), IntRect(IntPoint(), m_pluginSize), true); + platformPaint(*context, IntRect(IntPoint(), m_pluginSize), true); - return bitmap.release(); + return bitmap; } bool NetscapePlugin::isTransparent() @@ -744,8 +795,10 @@ void NetscapePlugin::geometryDidChange(const IntSize& pluginSize, const IntRect& m_clipRect = clipRect; m_pluginToRootViewTransform = pluginToRootViewTransform; +#if PLUGIN_ARCHITECTURE(X11) IntPoint frameRectLocationInWindowCoordinates = m_pluginToRootViewTransform.mapPoint(IntPoint()); m_frameRectInWindowCoordinates = IntRect(frameRectLocationInWindowCoordinates, m_pluginSize); +#endif platformGeometryDidChange(); @@ -796,6 +849,14 @@ void NetscapePlugin::didEvaluateJavaScript(uint64_t requestID, const String& res pluginStream->sendJavaScriptStream(result); } +void NetscapePlugin::streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(streamID)) + pluginStream->willSendRequest(requestURL, redirectResponseURL, redirectResponseStatus); +} + void NetscapePlugin::streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& /* suggestedFileName */) { @@ -929,7 +990,7 @@ bool NetscapePlugin::shouldAllowNavigationFromDrags() return false; } -bool NetscapePlugin::handlesPageScaleFactor() +bool NetscapePlugin::handlesPageScaleFactor() const { return false; } @@ -1040,15 +1101,15 @@ Scrollbar* NetscapePlugin::verticalScrollbar() bool NetscapePlugin::supportsSnapshotting() const { -#if PLATFORM(MAC) +#if PLATFORM(COCOA) return m_pluginModule && m_pluginModule->pluginQuirks().contains(PluginQuirks::SupportsSnapshotting); #endif return false; } -PassRefPtr<WebCore::SharedBuffer> NetscapePlugin::liveResourceData() const +RefPtr<WebCore::SharedBuffer> NetscapePlugin::liveResourceData() const { - return 0; + return nullptr; } IntPoint NetscapePlugin::convertToRootView(const IntPoint& pointInPluginCoordinates) const @@ -1058,13 +1119,31 @@ IntPoint NetscapePlugin::convertToRootView(const IntPoint& pointInPluginCoordina bool NetscapePlugin::convertFromRootView(const IntPoint& pointInRootViewCoordinates, IntPoint& pointInPluginCoordinates) { - if (!m_pluginToRootViewTransform.isInvertible()) - return false; + if (auto inverse = m_pluginToRootViewTransform.inverse()) { + pointInPluginCoordinates = inverse.value().mapPoint(pointInRootViewCoordinates); + return true; + } + return false; +} - pointInPluginCoordinates = m_pluginToRootViewTransform.inverse().mapPoint(pointInRootViewCoordinates); - return true; +void NetscapePlugin::mutedStateChanged(bool muted) +{ + NPBool value = muted; + NPP_SetValue(NPNVmuteAudioBool, &value); } +#if !PLATFORM(COCOA) + +void NetscapePlugin::windowFocusChanged(bool) +{ +} + +void NetscapePlugin::windowVisibilityChanged(bool) +{ +} + +#endif + } // namespace WebKit #endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h index 06d4c8ce2..bf569fe29 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,28 +39,28 @@ #include <wtf/text/StringHash.h> namespace WebCore { - class HTTPHeaderMap; - class ProtectionSpace; - class SharedBuffer; +class MachSendRight; +class HTTPHeaderMap; +class ProtectionSpace; +class SharedBuffer; } -OBJC_CLASS WKNPAPIPlugInContainer; - namespace WebKit { class NetscapePluginStream; - +class NetscapePluginUnix; + class NetscapePlugin : public Plugin { public: - static PassRefPtr<NetscapePlugin> create(PassRefPtr<NetscapePluginModule> pluginModule); + static RefPtr<NetscapePlugin> create(PassRefPtr<NetscapePluginModule>); virtual ~NetscapePlugin(); - static PassRefPtr<NetscapePlugin> fromNPP(NPP); + static RefPtr<NetscapePlugin> fromNPP(NPP); // In-process NetscapePlugins don't support asynchronous initialization. - virtual bool isBeingAsynchronouslyInitialized() const { return false; } + bool isBeingAsynchronouslyInitialized() const override { return false; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) NPError setDrawingModel(NPDrawingModel); NPError setEventModel(NPEventModel); NPBool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace); @@ -71,14 +71,11 @@ public: bool hasHandledAKeyDownEvent() const { return m_hasHandledAKeyDownEvent; } - mach_port_t compositingRenderServerPort(); - void openPluginPreferencePane(); + const WebCore::MachSendRight& compositingRenderServerPort(); // Computes an affine transform from the given coordinate space to the screen coordinate space. bool getScreenTransform(NPCoordinateSpace sourceSpace, WebCore::AffineTransform&); - WKNPAPIPlugInContainer* plugInContainer(); - #ifndef NP_NO_CARBON WindowRef windowRef() const; bool isWindowActive() const { return m_windowHasFocus; } @@ -90,6 +87,12 @@ public: #endif +#if PLUGIN_ARCHITECTURE(X11) + const WebCore::IntRect& frameRectInWindowCoordinates() const { return m_frameRectInWindowCoordinates; } +#endif + const WebCore::IntRect& clipRect() const { return m_clipRect; } + const WebCore::IntSize& size() const { return m_pluginSize; } + PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); } void invalidate(const NPRect*); @@ -103,6 +106,9 @@ public: static void setException(const String&); bool evaluate(NPObject*, const String&scriptString, NPVariant* result); bool isPrivateBrowsingEnabled(); + bool isMuted() const; + bool isWindowed() const { return m_isWindowed; } + bool isVisible() const { return m_isVisible; } static void setSetExceptionFunction(void (*)(const String&)); @@ -120,9 +126,6 @@ public: void pluginThreadAsyncCall(void (*function)(void*), void* userData); - // Called on the plug-in run loop (which is currently the main thread run loop). - void handlePluginThreadAsyncCall(void (*function)(void*), void* userData); - unsigned scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID)); void unscheduleTimer(unsigned timerID); @@ -132,6 +135,11 @@ public: void setCookiesForURL(const String& urlString, const String& cookieString); bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); + void setIsPlayingAudio(bool); + + void registerRedirect(NetscapePluginStream*, const WebCore::URL& requestURL, int redirectResponseStatus, void* notificationData); + void urlRedirectResponse(void* notifyData, bool allow); + // Member functions for calling into the plug-in. NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*); NPError NPP_Destroy(NPSavedData**); @@ -143,9 +151,13 @@ public: int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer); int16_t NPP_HandleEvent(void* event); void NPP_URLNotify(const char* url, NPReason, void* notifyData); + bool NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData); NPError NPP_GetValue(NPPVariable, void *value); NPError NPP_SetValue(NPNVariable, void *value); + // Convert the given point from plug-in coordinates to root view coordinates. + WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override; + private: NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule); @@ -164,7 +176,7 @@ private: bool platformInvalidate(const WebCore::IntRect&); void platformGeometryDidChange(); void platformVisibilityDidChange(); - void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect, bool isSnapshot = false); + void platformPaint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect, bool isSnapshot = false); bool platformHandleMouseEvent(const WebMouseEvent&); bool platformHandleWheelEvent(const WebWheelEvent&); @@ -176,60 +188,62 @@ private: static bool wantsPluginRelativeNPWindowCoordinates(); // Plugin - virtual bool initialize(const Parameters&); - virtual void destroy(); - virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); - virtual PassRefPtr<ShareableBitmap> snapshot(); -#if PLATFORM(MAC) - virtual PlatformLayer* pluginLayer(); + bool initialize(const Parameters&) override; + void destroy() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override; + RefPtr<ShareableBitmap> snapshot() override; +#if PLATFORM(COCOA) + PlatformLayer* pluginLayer() override; #endif - virtual bool isTransparent(); - virtual bool wantsWheelEvents() override; - virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform); - virtual void visibilityDidChange(bool isVisible); - virtual void frameDidFinishLoading(uint64_t requestID); - virtual void frameDidFail(uint64_t requestID, bool wasCancelled); - virtual void didEvaluateJavaScript(uint64_t requestID, const String& result); - virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, - uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName); - virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length); - virtual void streamDidFinishLoading(uint64_t streamID); - virtual void streamDidFail(uint64_t streamID, bool wasCancelled); - virtual void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, - uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName); - virtual void manualStreamDidReceiveData(const char* bytes, int length); - virtual void manualStreamDidFinishLoading(); - virtual void manualStreamDidFail(bool wasCancelled); + bool isTransparent() override; + bool wantsWheelEvents() override; + void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override; + void visibilityDidChange(bool isVisible) override; + void frameDidFinishLoading(uint64_t requestID) override; + void frameDidFail(uint64_t requestID, bool wasCancelled) override; + void didEvaluateJavaScript(uint64_t requestID, const String& result) override; + void streamWillSendRequest(uint64_t streamID, const WebCore::URL& requestURL, const WebCore::URL& responseURL, int responseStatus) override; + void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override; + void streamDidFinishLoading(uint64_t streamID) override; + void streamDidFail(uint64_t streamID, bool wasCancelled) override; + void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void manualStreamDidReceiveData(const char* bytes, int length) override; + void manualStreamDidFinishLoading() override; + void manualStreamDidFail(bool wasCancelled) override; - virtual bool handleMouseEvent(const WebMouseEvent&); - virtual bool handleWheelEvent(const WebWheelEvent&); - virtual bool handleMouseEnterEvent(const WebMouseEvent&); - virtual bool handleMouseLeaveEvent(const WebMouseEvent&); - virtual bool handleContextMenuEvent(const WebMouseEvent&); - virtual bool handleKeyboardEvent(const WebKeyboardEvent&); - virtual void setFocus(bool); - - virtual bool handleEditingCommand(const String& commandName, const String& argument) override; - virtual bool isEditingCommandEnabled(const String&) override; - - virtual bool shouldAllowScripting() override; - virtual bool shouldAllowNavigationFromDrags() override; + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override; + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleContextMenuEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override; + void setFocus(bool) override; + + bool handleEditingCommand(const String& commandName, const String& argument) override; + bool isEditingCommandEnabled(const String&) override; + + bool shouldAllowScripting() override; + bool shouldAllowNavigationFromDrags() override; - virtual bool handlesPageScaleFactor() override; + bool handlesPageScaleFactor() const override; - virtual NPObject* pluginScriptableNPObject(); + NPObject* pluginScriptableNPObject() override; - virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; - virtual bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; + unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; + bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; + + void windowFocusChanged(bool) override; + void windowVisibilityChanged(bool) override; -#if PLATFORM(MAC) - virtual void windowFocusChanged(bool); - virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); - virtual void windowVisibilityChanged(bool); +#if PLATFORM(COCOA) + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override; - virtual uint64_t pluginComplexTextInputIdentifier() const; - virtual void sendComplexTextInput(const String& textInput); - virtual void setLayerHostingMode(LayerHostingMode) override; + uint64_t pluginComplexTextInputIdentifier() const override; + void sendComplexTextInput(const String& textInput) override; + void setLayerHostingMode(LayerHostingMode) override; void pluginFocusOrWindowFocusChanged(); void setComplexTextInputEnabled(bool); @@ -237,40 +251,31 @@ private: void updatePluginLayer(); #endif - virtual void contentsScaleFactorChanged(float); - virtual void storageBlockingStateChanged(bool); - virtual void privateBrowsingStateChanged(bool); - virtual bool getFormValue(String& formValue); - virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); - virtual WebCore::Scrollbar* horizontalScrollbar(); - virtual WebCore::Scrollbar* verticalScrollbar(); + void contentsScaleFactorChanged(float) override; + void storageBlockingStateChanged(bool) override; + void privateBrowsingStateChanged(bool) override; + bool getFormValue(String& formValue) override; + bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override; + WebCore::Scrollbar* horizontalScrollbar() override; + WebCore::Scrollbar* verticalScrollbar() override; - virtual bool supportsSnapshotting() const; - - // Convert the given point from plug-in coordinates to root view coordinates. - virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override; + bool supportsSnapshotting() const override; // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be // converted (if the transformation matrix isn't invertible). bool convertFromRootView(const WebCore::IntPoint& pointInRootViewCoordinates, WebCore::IntPoint& pointInPluginCoordinates); - virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const override; - - virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; } + RefPtr<WebCore::SharedBuffer> liveResourceData() const override; - virtual String getSelectionString() const override { return String(); } + bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; } - void updateNPNPrivateMode(); + String getSelectionString() const override { return String(); } + String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override { return String(); } + bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override { return false; } -#if PLUGIN_ARCHITECTURE(WIN) - static BOOL WINAPI hookedTrackPopupMenu(HMENU, UINT uFlags, int x, int y, int nReserved, HWND, const RECT*); - void scheduleWindowedGeometryUpdate(); -#endif + void mutedStateChanged(bool) override; -#if PLUGIN_ARCHITECTURE(X11) - bool platformPostInitializeWindowed(bool needsXEmbed, uint64_t windowID); - bool platformPostInitializeWindowless(); -#endif + void updateNPNPrivateMode(); uint64_t m_nextRequestID; @@ -279,6 +284,7 @@ private: typedef HashMap<uint64_t, RefPtr<NetscapePluginStream>> StreamsMap; StreamsMap m_streams; + HashMap<void*, std::pair<RefPtr<NetscapePluginStream>, String>> m_redirects; RefPtr<NetscapePluginModule> m_pluginModule; NPP_t m_npp; @@ -292,8 +298,9 @@ private: // A transform that can be used to convert from root view coordinates to plug-in coordinates. WebCore::AffineTransform m_pluginToRootViewTransform; - // FIXME: Get rid of these. +#if PLUGIN_ARCHITECTURE(X11) WebCore::IntRect m_frameRectInWindowCoordinates; +#endif CString m_userAgent; @@ -365,14 +372,12 @@ private: // if we can tell the plug-in that we support the updated Cocoa text input specification. bool m_hasHandledAKeyDownEvent; - // The number of NPCocoaEventKeyUp events that should be ignored. + // The number of NPCocoaEventKeyUp events that should be ignored. unsigned m_ignoreNextKeyUpEventCounter; WebCore::IntRect m_windowFrameInScreenCoordinates; WebCore::IntRect m_viewFrameInWindowCoordinates; - RetainPtr<WKNPAPIPlugInContainer> m_plugInContainer; - #ifndef NP_NO_CARBON void nullEventTimerFired(); @@ -381,23 +386,15 @@ private: RunLoop::Timer<NetscapePlugin> m_nullEventTimer; NP_CGContext m_npCGContext; #endif -#elif PLUGIN_ARCHITECTURE(WIN) - HWND m_window; - HWND m_contextMenuOwnerWindow; #elif PLUGIN_ARCHITECTURE(X11) - Pixmap m_drawable; - Display* m_pluginDisplay; -#if PLATFORM(GTK) - GtkWidget* m_platformPluginWidget; -#endif - -public: // Need to call it in the NPN_GetValue browser callback. - static Display* x11HostDisplay(); + std::unique_ptr<NetscapePluginUnix> m_impl; #endif }; } // namespace WebKit +SPECIALIZE_TYPE_TRAITS_PLUGIN(NetscapePlugin, NetscapePluginType) + #endif // ENABLE(NETSCAPE_PLUGIN_API) #endif // NetscapePlugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp index 02cda26fa..0cd3688c3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp @@ -59,7 +59,7 @@ void NetscapePlugin::platformVisibilityDidChange() { } -void NetscapePlugin::platformPaint(GraphicsContext*, const IntRect&, bool) +void NetscapePlugin::platformPaint(GraphicsContext&, const IntRect&, bool) { } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp index b19c12b6a..7d54d88c7 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp @@ -30,7 +30,6 @@ #include "NetscapePlugin.h" #include <utility> -#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> using namespace WebCore; @@ -63,6 +62,14 @@ NetscapePluginStream::~NetscapePluginStream() ASSERT(m_fileHandle == invalidPlatformFileHandle); } +void NetscapePluginStream::willSendRequest(const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus) +{ + Ref<NetscapePluginStream> protect(*this); + + if (redirectResponseStatus >= 300 && redirectResponseStatus < 400) + m_plugin->registerRedirect(this, requestURL, redirectResponseStatus, m_notificationData); +} + void NetscapePluginStream::didReceiveResponse(const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers) { // Starting the stream could cause the plug-in stream to go away so we keep a reference to it here. @@ -187,7 +194,7 @@ void NetscapePluginStream::deliverData(const char* bytes, int length) if (m_transferMode != NP_ASFILEONLY) { if (!m_deliveryData) - m_deliveryData = adoptPtr(new Vector<uint8_t>); + m_deliveryData = std::make_unique<Vector<uint8_t>>(); m_deliveryData->reserveCapacity(m_deliveryData->size() + length); m_deliveryData->append(bytes, length); @@ -339,6 +346,11 @@ void NetscapePluginStream::stop(NPReason reason) notifyAndDestroyStream(reason); } +void NetscapePluginStream::setURL(const String& newURLString) +{ + m_requestURLString = newURLString; +} + void NetscapePluginStream::cancel() { m_plugin->cancelStreamLoad(this); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h index ad82c7aa3..7c7045fd3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h @@ -30,6 +30,7 @@ #include <WebCore/FileSystem.h> #include <WebCore/npruntime_internal.h> +#include <memory> #include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -47,15 +48,16 @@ class NetscapePlugin; class NetscapePluginStream : public RefCounted<NetscapePluginStream> { public: - static PassRefPtr<NetscapePluginStream> create(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData) + static Ref<NetscapePluginStream> create(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData) { - return adoptRef(new NetscapePluginStream(plugin, streamID, requestURLString, sendNotification, notificationData)); + return adoptRef(*new NetscapePluginStream(plugin, streamID, requestURLString, sendNotification, notificationData)); } ~NetscapePluginStream(); uint64_t streamID() const { return m_streamID; } const NPStream* npStream() const { return &m_npStream; } + void willSendRequest(const WebCore::URL& requestURL, const WebCore::URL& redirectResponseURL, int redirectResponseStatus); void didReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers); void didReceiveData(const char* bytes, int length); @@ -66,6 +68,7 @@ public: void stop(NPReason); NPError destroy(NPReason); + void setURL(const String& newURLString); private: NetscapePluginStream(PassRefPtr<NetscapePlugin>, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData); @@ -106,7 +109,7 @@ private: CString m_headers; RunLoop::Timer<NetscapePluginStream> m_deliveryDataTimer; - OwnPtr< Vector<uint8_t>> m_deliveryData; + std::unique_ptr<Vector<uint8_t>> m_deliveryData; bool m_stopStreamWhenDoneDelivering; }; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp new file mode 100644 index 000000000..8b8eaa0bc --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetscapePlugin.h" + +#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#include "NetscapePluginX11.h" +#include "WebEvent.h" +#include <WebCore/NotImplemented.h> +#include <WebCore/PlatformDisplay.h> + +using namespace WebCore; + +namespace WebKit { + +void NetscapePlugin::platformPreInitialize() +{ +} + +bool NetscapePlugin::platformPostInitialize() +{ +#if PLATFORM(X11) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + m_impl = NetscapePluginX11::create(*this); + if (!m_impl) + return false; + } +#endif + + // Windowed plugins need a platform implementation. + if (!m_impl) + return !m_isWindowed; + + m_npWindow.type = m_impl->windowType(); + m_npWindow.window = m_impl->window(); + m_npWindow.ws_info = m_impl->windowSystemInfo(); + callSetWindow(); + return true; +} + +void NetscapePlugin::platformDestroy() +{ + m_impl = nullptr; +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + if (!m_impl) + return; + m_impl->geometryDidChange(); +} + +void NetscapePlugin::platformVisibilityDidChange() +{ + if (!m_isWindowed || !m_impl) + return; + + m_impl->visibilityDidChange(); +} + +void NetscapePlugin::platformPaint(GraphicsContext& context, const IntRect& dirtyRect, bool /*isSnapshot*/) +{ + if (m_isWindowed || !m_impl) + return; + + if (!m_isStarted) { + // FIXME: we should paint a missing plugin icon. + return; + } + + m_impl->paint(context, dirtyRect); +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + if ((event.type() == WebEvent::MouseDown || event.type() == WebEvent::MouseUp) + && event.button() == WebMouseEvent::RightButton + && quirks().contains(PluginQuirks::IgnoreRightClickInWindowlessMode)) + return false; + + return m_impl->handleMouseEvent(event); +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleWheelEvent(event); +} + +void NetscapePlugin::platformSetFocus(bool focusIn) +{ + if (m_isWindowed || !m_impl) + return; + + m_impl->setFocus(focusIn); +} + +bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() +{ + return true; +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleMouseEnterEvent(event); +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleMouseLeaveEvent(event); +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +{ + // We don't generate other types of keyboard events via WebEventFactory. + ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp); + + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleKeyboardEvent(event); +} + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h new file mode 100644 index 000000000..efa6cd0ce --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NetscapePluginUnix_h +#define NetscapePluginUnix_h + +#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#include <WebCore/npruntime_internal.h> + +namespace WebCore { +class GraphicsContext; +class IntRect; +} + +namespace WebKit { + +class WebKeyboardEvent; +class WebMouseEvent; +class WebWheelEvent; + +class NetscapePluginUnix { +public: + virtual ~NetscapePluginUnix() { } + virtual NPWindowType windowType() const = 0; + virtual void* window() const = 0; + virtual NPSetWindowCallbackStruct* windowSystemInfo() = 0; + virtual void geometryDidChange() = 0; + virtual void visibilityDidChange() = 0; + virtual void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) = 0; + virtual bool handleMouseEvent(const WebMouseEvent&) = 0; + virtual bool handleWheelEvent(const WebWheelEvent&) = 0; + virtual bool handleMouseEnterEvent(const WebMouseEvent&) = 0; + virtual bool handleMouseLeaveEvent(const WebMouseEvent&) = 0; + virtual bool handleKeyboardEvent(const WebKeyboardEvent&) = 0; + virtual void setFocus(bool) = 0; +}; + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#endif // NetscapePluginUnix_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp index c22bc74a2..2bed46aab 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp @@ -25,14 +25,17 @@ */ #include "config.h" +#include "NetscapePluginX11.h" + #if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) #include "NetscapePlugin.h" - #include "PluginController.h" #include "WebEvent.h" #include <WebCore/GraphicsContext.h> #include <WebCore/NotImplemented.h> +#include <WebCore/PlatformDisplayX11.h> +#include <WebCore/XUniquePtr.h> #if PLATFORM(GTK) #include <gtk/gtk.h> @@ -41,8 +44,6 @@ #endif #include <gdk/gdkx.h> #include <WebCore/GtkVersioning.h> -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) -#include <Ecore_X.h> #endif #if USE(CAIRO) @@ -55,16 +56,19 @@ using namespace WebCore; namespace WebKit { +static inline Display* x11HostDisplay() +{ + return downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native(); +} + static Display* getPluginDisplay() { #if PLATFORM(GTK) // Since we're a gdk/gtk app, we'll (probably?) have the same X connection as any gdk-based // plugins, so we can return that. We might want to add other implementations here later. return GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return static_cast<Display*>(ecore_x_display_get()); #else - return 0; + return nullptr; #endif } @@ -72,8 +76,6 @@ static inline int x11Screen() { #if PLATFORM(GTK) return gdk_screen_get_number(gdk_screen_get_default()); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return ecore_x_screen_index_get(ecore_x_default_screen_get()); #else return 0; #endif @@ -83,8 +85,6 @@ static inline int displayDepth() { #if PLATFORM(GTK) return gdk_visual_get_depth(gdk_screen_get_system_visual(gdk_screen_get_default())); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return ecore_x_default_depth_get(NetscapePlugin::x11HostDisplay(), ecore_x_default_screen_get()); #else return 0; #endif @@ -94,19 +94,6 @@ static inline unsigned long rootWindowID() { #if PLATFORM(GTK) return GDK_ROOT_WINDOW(); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return ecore_x_window_root_first_get(); -#else - return 0; -#endif -} - -Display* NetscapePlugin::x11HostDisplay() -{ -#if PLATFORM(GTK) - return GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return static_cast<Display*>(ecore_x_display_get()); #else return 0; #endif @@ -123,187 +110,165 @@ static gboolean socketPlugRemovedCallback(GtkSocket*) } #endif -bool NetscapePlugin::platformPostInitializeWindowed(bool needsXEmbed, uint64_t windowID) +std::unique_ptr<NetscapePluginX11> NetscapePluginX11::create(NetscapePlugin& plugin) { - m_npWindow.type = NPWindowTypeWindow; - if (!needsXEmbed) { +#if PLATFORM(GTK) + uint64_t windowID = 0; +#endif + if (plugin.isWindowed()) { +#if PLATFORM(GTK) + // NPPVplugiNeedsXEmbed is a boolean value, but at least the + // Flash player plugin is using an 'int' instead. + int needsXEmbed = 0; + plugin.NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); + if (needsXEmbed) { + windowID = plugin.controller()->createPluginContainer(); + if (!windowID) + return nullptr; + } else { + notImplemented(); + return nullptr; + } +#else notImplemented(); - return false; + return nullptr; +#endif } - Display* display = x11HostDisplay(); + Display* display = getPluginDisplay(); + if (!display) + return nullptr; #if PLATFORM(GTK) - // It seems flash needs the socket to be in the same process, - // I guess it uses gdk_window_lookup(), so we create a new socket here - // containing a plug with the UI process socket embedded. - m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID)); - GtkWidget* socket = gtk_socket_new(); - g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), 0); - gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket); - gtk_widget_show(socket); - gtk_widget_show(m_platformPluginWidget); - - m_npWindow.window = GINT_TO_POINTER(gtk_socket_get_id(GTK_SOCKET(socket))); - GdkWindow* window = gtk_widget_get_window(socket); - NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); - callbackStruct->display = GDK_WINDOW_XDISPLAY(window); - callbackStruct->visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); - callbackStruct->depth = gdk_visual_get_depth(gdk_window_get_visual(window)); - callbackStruct->colormap = XCreateColormap(display, GDK_ROOT_WINDOW(), callbackStruct->visual, AllocNone); -#else - UNUSED_PARAM(windowID); + if (plugin.isWindowed()) + return std::make_unique<NetscapePluginX11>(plugin, display, windowID); #endif - XFlush(display); - - callSetWindow(); - - return true; + return std::make_unique<NetscapePluginX11>(plugin, display); } -bool NetscapePlugin::platformPostInitializeWindowless() +NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display) + : m_plugin(plugin) + , m_pluginDisplay(display) { - Display* display = x11HostDisplay(); - m_npWindow.type = NPWindowTypeDrawable; - m_npWindow.window = 0; - + Display* hostDisplay = x11HostDisplay(); int depth = displayDepth(); - - NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); - callbackStruct->display = display; - callbackStruct->depth = depth; + m_setWindowCallbackStruct.display = hostDisplay; + m_setWindowCallbackStruct.depth = depth; XVisualInfo visualTemplate; visualTemplate.screen = x11Screen(); visualTemplate.depth = depth; visualTemplate.c_class = TrueColor; int numMatching; - XVisualInfo* visualInfo = XGetVisualInfo(display, VisualScreenMask | VisualDepthMask | VisualClassMask, - &visualTemplate, &numMatching); + XUniquePtr<XVisualInfo> visualInfo(XGetVisualInfo(hostDisplay, VisualScreenMask | VisualDepthMask | VisualClassMask, &visualTemplate, &numMatching)); ASSERT(visualInfo); - Visual* visual = visualInfo[0].visual; + Visual* visual = visualInfo.get()[0].visual; ASSERT(visual); - XFree(visualInfo); - - callbackStruct->visual = visual; - callbackStruct->colormap = XCreateColormap(display, rootWindowID(), visual, AllocNone); - - callSetWindow(); - return true; + m_setWindowCallbackStruct.visual = visual; + m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, rootWindowID(), visual, AllocNone); } -void NetscapePlugin::platformPreInitialize() -{ -} - -bool NetscapePlugin::platformPostInitialize() +#if PLATFORM(GTK) +NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display, uint64_t windowID) + : m_plugin(plugin) + , m_pluginDisplay(display) + , m_windowID(windowID) { - uint64_t windowID = 0; - // NPPVpluginNeedsXEmbed is a boolean value, but at least the - // Flash player plugin is using an 'int' instead. - int needsXEmbed = 0; - if (m_isWindowed) { - NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); - if (needsXEmbed) { - windowID = controller()->createPluginContainer(); - if (!windowID) - return false; - } else { - notImplemented(); - return false; - } - } + // It seems flash needs the socket to be in the same process, + // I guess it uses gdk_window_lookup(), so we create a new socket here + // containing a plug with the UI process socket embedded. + m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID)); - if (!(m_pluginDisplay = getPluginDisplay())) - return false; + // Hide the GtkPlug on delete-event since we assume the widget is valid while the plugin is active. + // platformDestroy() will be called anyway right after the delete-event. + g_signal_connect(m_platformPluginWidget, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), nullptr); - NPSetWindowCallbackStruct* callbackStruct = new NPSetWindowCallbackStruct; - callbackStruct->type = 0; - m_npWindow.ws_info = callbackStruct; + GtkWidget* socket = gtk_socket_new(); + // Do not show the plug widget until the socket is connected. + g_signal_connect_swapped(socket, "plug-added", G_CALLBACK(gtk_widget_show), m_platformPluginWidget); + g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), nullptr); + gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket); + gtk_widget_show(socket); - if (m_isWindowed) - return platformPostInitializeWindowed(needsXEmbed, windowID); + Display* hostDisplay = x11HostDisplay(); + m_npWindowID = gtk_socket_get_id(GTK_SOCKET(socket)); + GdkWindow* window = gtk_widget_get_window(socket); + m_setWindowCallbackStruct.display = GDK_WINDOW_XDISPLAY(window); + m_setWindowCallbackStruct.visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); + m_setWindowCallbackStruct.depth = gdk_visual_get_depth(gdk_window_get_visual(window)); + m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, GDK_ROOT_WINDOW(), m_setWindowCallbackStruct.visual, AllocNone); - return platformPostInitializeWindowless(); + XFlush(hostDisplay); } +#endif -void NetscapePlugin::platformDestroy() +NetscapePluginX11::~NetscapePluginX11() { - NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); - Display* hostDisplay = x11HostDisplay(); - XFreeColormap(hostDisplay, callbackStruct->colormap); - delete callbackStruct; + XFreeColormap(x11HostDisplay(), m_setWindowCallbackStruct.colormap); - if (m_drawable) { - XFreePixmap(hostDisplay, m_drawable); - m_drawable = 0; - } + m_drawable.reset(); #if PLATFORM(GTK) - if (m_platformPluginWidget) { + if (m_platformPluginWidget) gtk_widget_destroy(m_platformPluginWidget); - m_platformPluginWidget = 0; - } #endif } -bool NetscapePlugin::platformInvalidate(const IntRect&) +NPWindowType NetscapePluginX11::windowType() const { - notImplemented(); - return false; + return m_plugin.isWindowed() ? NPWindowTypeWindow : NPWindowTypeDrawable; +} + +void* NetscapePluginX11::window() const +{ +#if PLATFORM(GTK) + return m_plugin.isWindowed() ? GINT_TO_POINTER(m_npWindowID) : nullptr; +#else + return nullptr; +#endif } -void NetscapePlugin::platformGeometryDidChange() +void NetscapePluginX11::geometryDidChange() { - if (m_isWindowed) { + if (m_plugin.isWindowed()) { uint64_t windowID = 0; #if PLATFORM(GTK) + if (!gtk_plug_get_embedded(GTK_PLUG(m_platformPluginWidget))) + return; windowID = static_cast<uint64_t>(GDK_WINDOW_XID(gtk_plug_get_socket_window(GTK_PLUG(m_platformPluginWidget)))); #endif - controller()->windowedPluginGeometryDidChange(m_frameRectInWindowCoordinates, m_clipRect, windowID); + m_plugin.controller()->windowedPluginGeometryDidChange(m_plugin.frameRectInWindowCoordinates(), m_plugin.clipRect(), windowID); return; } - Display* display = x11HostDisplay(); - if (m_drawable) - XFreePixmap(display, m_drawable); - - if (m_pluginSize.isEmpty()) { - m_drawable = 0; + m_drawable.reset(); + if (m_plugin.size().isEmpty()) return; - } - - m_drawable = XCreatePixmap(display, rootWindowID(), m_pluginSize.width(), m_pluginSize.height(), displayDepth()); - XSync(display, false); // Make sure that the server knows about the Drawable. + m_drawable = XCreatePixmap(x11HostDisplay(), rootWindowID(), m_plugin.size().width(), m_plugin.size().height(), displayDepth()); + XSync(x11HostDisplay(), false); // Make sure that the server knows about the Drawable. } -void NetscapePlugin::platformVisibilityDidChange() +void NetscapePluginX11::visibilityDidChange() { - if (!m_isWindowed) - return; - + ASSERT(m_plugin.isWindowed()); uint64_t windowID = 0; #if PLATFORM(GTK) + if (!gtk_plug_get_embedded(GTK_PLUG(m_platformPluginWidget))) + return; windowID = static_cast<uint64_t>(GDK_WINDOW_XID(gtk_plug_get_socket_window(GTK_PLUG(m_platformPluginWidget)))); #endif - controller()->windowedPluginVisibilityDidChange(m_isVisible, windowID); - controller()->windowedPluginGeometryDidChange(m_frameRectInWindowCoordinates, m_clipRect, windowID); + m_plugin.controller()->windowedPluginVisibilityDidChange(m_plugin.isVisible(), windowID); + m_plugin.controller()->windowedPluginGeometryDidChange(m_plugin.frameRectInWindowCoordinates(), m_plugin.clipRect(), windowID); } -void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool /*isSnapshot*/) +void NetscapePluginX11::paint(GraphicsContext& context, const IntRect& dirtyRect) { - if (m_isWindowed) - return; - - if (!m_isStarted) { - // FIXME: we should paint a missing plugin icon. - return; - } + ASSERT(!m_plugin.isWindowed()); - if (context->paintingDisabled() || !m_drawable) + if (context.paintingDisabled() || !m_drawable) return; XEvent xevent; @@ -311,7 +276,7 @@ void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirt XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; exposeEvent.type = GraphicsExpose; exposeEvent.display = x11HostDisplay(); - exposeEvent.drawable = m_drawable; + exposeEvent.drawable = m_drawable.get(); IntRect exposedRect(dirtyRect); exposeEvent.x = exposedRect.x(); @@ -322,18 +287,15 @@ void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirt exposeEvent.width = exposedRect.width(); exposeEvent.height = exposedRect.height(); - NPP_HandleEvent(&xevent); + m_plugin.NPP_HandleEvent(&xevent); if (m_pluginDisplay != x11HostDisplay()) XSync(m_pluginDisplay, false); -#if PLATFORM(GTK) || (PLATFORM(EFL) && USE(CAIRO)) - RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(m_pluginDisplay, - m_drawable, - static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info)->visual, - m_pluginSize.width(), - m_pluginSize.height())); - cairo_t* cr = context->platformContext()->cr(); +#if PLATFORM(GTK) + RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(m_pluginDisplay, m_drawable.get(), + m_setWindowCallbackStruct.visual, m_plugin.size().width(), m_plugin.size().height())); + cairo_t* cr = context.platformContext()->cr(); cairo_save(cr); cairo_set_source_surface(cr, drawableSurface.get(), 0, 0); @@ -354,7 +316,7 @@ static inline void initializeXEvent(XEvent& event) memset(&event, 0, sizeof(XEvent)); event.xany.serial = 0; event.xany.send_event = false; - event.xany.display = NetscapePlugin::x11HostDisplay(); + event.xany.display = x11HostDisplay(); event.xany.window = 0; } @@ -452,15 +414,9 @@ static inline void setXCrossingEventFields(XEvent& xEvent, const WebMouseEvent& xCrossing.focus = false; } -bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +bool NetscapePluginX11::handleMouseEvent(const WebMouseEvent& event) { - if (m_isWindowed) - return false; - - if ((event.type() == WebEvent::MouseDown || event.type() == WebEvent::MouseUp) - && event.button() == WebMouseEvent::RightButton - && quirks().contains(PluginQuirks::IgnoreRightClickInWindowlessMode)) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); @@ -468,22 +424,20 @@ bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) switch (event.type()) { case WebEvent::MouseDown: case WebEvent::MouseUp: - setXButtonEventFields(xEvent, event, convertToRootView(IntPoint())); + setXButtonEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint())); break; case WebEvent::MouseMove: - setXMotionEventFields(xEvent, event, convertToRootView(IntPoint())); + setXMotionEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint())); break; + case WebEvent::MouseForceChanged: + case WebEvent::MouseForceDown: + case WebEvent::MouseForceUp: case WebEvent::NoType: case WebEvent::Wheel: case WebEvent::KeyDown: case WebEvent::KeyUp: case WebEvent::RawKeyDown: case WebEvent::Char: -#if ENABLE(GESTURE_EVENTS) - case WebEvent::GestureScrollBegin: - case WebEvent::GestureScrollEnd: - case WebEvent::GestureSingleTap: -#endif #if ENABLE(TOUCH_EVENTS) case WebEvent::TouchStart: case WebEvent::TouchMove: @@ -493,7 +447,7 @@ bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) return false; } - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } // We undefine these constants in npruntime_internal.h to avoid collision @@ -503,22 +457,20 @@ const int kKeyReleaseType = 3; const int kFocusInType = 9; const int kFocusOutType = 10; -bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& event) +bool NetscapePluginX11::handleWheelEvent(const WebWheelEvent& event) { - if (m_isWindowed) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); - setXButtonEventFieldsByWebWheelEvent(xEvent, event, convertToRootView(IntPoint())); + setXButtonEventFieldsByWebWheelEvent(xEvent, event, m_plugin.convertToRootView(IntPoint())); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } -void NetscapePlugin::platformSetFocus(bool focusIn) +void NetscapePluginX11::setFocus(bool focusIn) { - if (m_isWindowed) - return; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); @@ -527,36 +479,29 @@ void NetscapePlugin::platformSetFocus(bool focusIn) focusEvent.mode = NotifyNormal; focusEvent.detail = NotifyDetailNone; - NPP_HandleEvent(&xEvent); -} - -bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() -{ - return true; + m_plugin.NPP_HandleEvent(&xEvent); } -bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +bool NetscapePluginX11::handleMouseEnterEvent(const WebMouseEvent& event) { - if (m_isWindowed) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); - setXCrossingEventFields(xEvent, event, convertToRootView(IntPoint()), EnterNotify); + setXCrossingEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()), EnterNotify); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } -bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +bool NetscapePluginX11::handleMouseLeaveEvent(const WebMouseEvent& event) { - if (m_isWindowed) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); - setXCrossingEventFields(xEvent, event, convertToRootView(IntPoint()), LeaveNotify); + setXCrossingEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()), LeaveNotify); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } static inline void setXKeyEventFields(XEvent& xEvent, const WebKeyboardEvent& webEvent) @@ -579,8 +524,9 @@ static inline void setXKeyEventFields(XEvent& xEvent, const WebKeyboardEvent& we xKey.y_root = 0; } -bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +bool NetscapePluginX11::handleKeyboardEvent(const WebKeyboardEvent& event) { + ASSERT(!m_plugin.isWindowed()); // We don't generate other types of keyboard events via WebEventFactory. ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp); @@ -588,7 +534,7 @@ bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) initializeXEvent(xEvent); setXKeyEventFields(xEvent, event); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h new file mode 100644 index 000000000..0fe50a1a6 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 University of Szeged + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NetscapePluginX11_h +#define NetscapePluginX11_h + +#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#include "NetscapePluginUnix.h" +#include <WebCore/XUniqueResource.h> + +namespace WebKit { + +class NetscapePlugin; + +class NetscapePluginX11 final : public NetscapePluginUnix { +public: + static std::unique_ptr<NetscapePluginX11> create(NetscapePlugin&); + NetscapePluginX11(NetscapePlugin&, Display*); +#if PLATFORM(GTK) + NetscapePluginX11(NetscapePlugin&, Display*, uint64_t windowID); +#endif + virtual ~NetscapePluginX11(); + +private: + NPWindowType windowType() const override; + void* window() const override; + NPSetWindowCallbackStruct* windowSystemInfo() override { return &m_setWindowCallbackStruct; } + void geometryDidChange() override; + void visibilityDidChange() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) override; + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override; + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override; + void setFocus(bool) override; + + NetscapePlugin& m_plugin; + Display* m_pluginDisplay { nullptr }; + WebCore::XUniquePixmap m_drawable; + NPSetWindowCallbackStruct m_setWindowCallbackStruct; +#if PLATFORM(GTK) + uint64_t m_windowID { 0 }; + unsigned long m_npWindowID { 0 }; + GtkWidget* m_platformPluginWidget { nullptr }; +#endif +}; +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#endif // NetscapePluginX11_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFLayerControllerSPI.h b/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFLayerControllerSPI.h new file mode 100644 index 000000000..18042e213 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFLayerControllerSPI.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DeprecatedPDFLayerControllerSPI_h +#define DeprecatedPDFLayerControllerSPI_h + +#if ENABLE(PDFKIT_PLUGIN) && USE(DEPRECATED_PDF_PLUGIN) + +#import <PDFKit/PDFKit.h> + +@class CPReadingModel; +@class PDFViewLayout; + +@protocol PDFLayerControllerDelegate <NSObject> + +- (void)updateScrollPosition:(CGPoint)newPosition; +- (void)writeItemsToPasteboard:(NSArray *)items withTypes:(NSArray *)types; +- (void)showDefinitionForAttributedString:(NSAttributedString *)string atPoint:(CGPoint)point; +- (void)performWebSearch:(NSString *)string; +- (void)performSpotlightSearch:(NSString *)string; +- (void)openWithNativeApplication; +- (void)saveToPDF; + +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeActiveAnnotation:(PDFAnnotation *)annotation; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController clickedLinkWithURL:(NSURL *)url; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeContentScaleFactor:(CGFloat)scaleFactor; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeDisplayMode:(int)mode; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeSelection:(PDFSelection *)selection; + +@end + +@interface PDFLayerController : NSObject +@end + +@interface PDFLayerController () + +@property (retain) CALayer *parentLayer; +@property (retain) PDFDocument *document; +@property (retain) id<PDFLayerControllerDelegate> delegate; + +- (void)setFrameSize:(CGSize)size; + +- (PDFDisplayMode)displayMode; +- (void)setDisplayMode:(PDFDisplayMode)mode; +- (void)setDisplaysPageBreaks:(BOOL)pageBreaks; + +- (CGFloat)contentScaleFactor; +- (void)setContentScaleFactor:(CGFloat)scaleFactor; + +- (CGFloat)deviceScaleFactor; +- (void)setDeviceScaleFactor:(CGFloat)scaleFactor; + +- (CGSize)contentSize; +- (CGSize)contentSizeRespectingZoom; + +- (void)snapshotInContext:(CGContextRef)context; + +- (void)magnifyWithMagnification:(CGFloat)magnification atPoint:(CGPoint)point immediately:(BOOL)immediately; + +- (CGPoint)scrollPosition; +- (void)setScrollPosition:(CGPoint)newPosition; +- (void)scrollWithDelta:(CGSize)delta; + +- (void)mouseDown:(NSEvent *)event; +- (void)rightMouseDown:(NSEvent *)event; +- (void)mouseMoved:(NSEvent *)event; +- (void)mouseUp:(NSEvent *)event; +- (void)mouseDragged:(NSEvent *)event; +- (void)mouseEntered:(NSEvent *)event; +- (void)mouseExited:(NSEvent *)event; + +- (NSMenu *)menuForEvent:(NSEvent *)event; + +- (NSArray *)findString:(NSString *)string caseSensitive:(BOOL)isCaseSensitive highlightMatches:(BOOL)shouldHighlightMatches; + +- (PDFSelection *)currentSelection; +- (void)setCurrentSelection:(PDFSelection *)selection; +- (PDFSelection *)searchSelection; +- (void)setSearchSelection:(PDFSelection *)selection; +- (void)gotoSelection:(PDFSelection *)selection; +- (PDFSelection *)getSelectionForWordAtPoint:(CGPoint)point; +- (NSArray *)rectsForSelectionInLayoutSpace:(PDFSelection *)selection; +- (NSArray *)rectsForAnnotationInLayoutSpace:(PDFAnnotation *)annotation; +- (PDFViewLayout *)layout; +- (NSRect)frame; + +- (PDFPage *)currentPage; +- (NSUInteger)lastPageIndex; +- (NSUInteger)currentPageIndex; +- (void)gotoNextPage; +- (void)gotoPreviousPage; + +- (void)copySelection; +- (void)selectAll; + +- (bool)keyDown:(NSEvent *)event; + +- (void)setHUDEnabled:(BOOL)enabled; +- (BOOL)hudEnabled; + +- (CGRect)boundsForAnnotation:(PDFAnnotation *)annotation; +- (void)activateNextAnnotation:(BOOL)previous; + +- (void)attemptToUnlockWithPassword:(NSString *)password; + +- (void)searchInDictionaryWithSelection:(PDFSelection *)selection; + +// Accessibility + +- (CPReadingModel *)readingModel; +- (id)accessibilityFocusedUIElement; +- (NSArray *)accessibilityAttributeNames; +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute; +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute; +- (NSArray *)accessibilityParameterizedAttributeNames; +- (NSString *)accessibilityRoleAttribute; +- (NSString *)accessibilityRoleDescriptionAttribute; +- (NSString *)accessibilityValueAttribute; +- (BOOL)accessibilityIsValueAttributeSettable; +- (NSString *)accessibilitySelectedTextAttribute; +- (BOOL)accessibilityIsSelectedTextAttributeSettable; +- (NSValue *)accessibilitySelectedTextRangeAttribute; +- (NSNumber *)accessibilityNumberOfCharactersAttribute; +- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable; +- (NSValue *)accessibilityVisibleCharacterRangeAttribute; +- (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable; +- (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter; +- (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter; +- (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter; +- (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter; + +@end + +#endif + +#endif // DeprecatedPDFLayerControllerSPI_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h b/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h new file mode 100644 index 000000000..1456a5198 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2011, 2012, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DeprecatedPDFPlugin_h +#define DeprecatedPDFPlugin_h + +#include "PDFKitImports.h" + +#if ENABLE(PDFKIT_PLUGIN) && USE(DEPRECATED_PDF_PLUGIN) + +#include "Plugin.h" +#include "WebEvent.h" +#include "WebHitTestResultData.h" +#include <WebCore/AffineTransform.h> +#include <WebCore/FindOptions.h> +#include <WebCore/ScrollableArea.h> +#include <wtf/RetainPtr.h> + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; +typedef const struct OpaqueJSValue* JSValueRef; + +OBJC_CLASS NSArray; +OBJC_CLASS NSAttributedString; +OBJC_CLASS NSData; +OBJC_CLASS NSString; +OBJC_CLASS PDFAnnotation; +OBJC_CLASS PDFLayerController; +OBJC_CLASS PDFSelection; +OBJC_CLASS WKPDFPluginAccessibilityObject; +OBJC_CLASS WKPDFLayerControllerDelegate; + +namespace IPC { +class DataReference; +} + +namespace WebCore { +class Element; +struct PluginInfo; +} + +namespace WebKit { + +class PDFPluginAnnotation; +class PDFPluginPasswordField; +class PluginView; +class WebFrame; + +class PDFPlugin final : public Plugin, private WebCore::ScrollableArea { +public: + static Ref<PDFPlugin> create(WebFrame*); + ~PDFPlugin(); + + static WebCore::PluginInfo pluginInfo(); + + WebCore::IntSize size() const { return m_size; } + + void didMutatePDFDocument() { m_pdfDocumentWasMutated = true; } + + void paintControlForLayerInContext(CALayer *, CGContextRef); + void setActiveAnnotation(PDFAnnotation *); + + using ScrollableArea::notifyScrollPositionChanged; + void notifyContentScaleFactorChanged(CGFloat scaleFactor); + void notifyDisplayModeChanged(int); + + void notifySelectionChanged(PDFSelection *); + + void clickedLink(NSURL *); + void saveToPDF(); + void openWithNativeApplication(); + void writeItemsToPasteboard(NSString *pasteboardName, NSArray *items, NSArray *types); + void showDefinitionForAttributedString(NSAttributedString *, CGPoint); + void performWebSearch(NSString *); + void performSpotlightSearch(NSString *); + + void focusNextAnnotation(); + void focusPreviousAnnotation(); + + void attemptToUnlockPDF(const String& password); + + WebCore::FloatRect convertFromPDFViewToScreen(const WebCore::FloatRect&) const; + WebCore::IntRect boundsOnScreen() const; + + bool showContextMenuAtPoint(const WebCore::IntPoint&); + + String lookupTextAtLocation(const WebCore::FloatPoint&, WebHitTestResultData&, PDFSelection **, NSDictionary **) const; + WebCore::FloatRect rectForSelectionInRootView(PDFSelection *) const; + + CGFloat scaleFactor() const; + + bool shouldPlaceBlockDirectionScrollbarOnLeft() const override { return false; } + +private: + explicit PDFPlugin(WebFrame*); + + // Plugin functions. + bool initialize(const Parameters&) override; + void destroy() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRectInWindowCoordinates) override { } + void updateControlTints(WebCore::GraphicsContext&) override; + bool supportsSnapshotting() const override { return true; } + RefPtr<ShareableBitmap> snapshot() override; + PlatformLayer* pluginLayer() override; + bool isTransparent() override { return false; } + bool wantsWheelEvents() override { return true; } + void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override; + void contentsScaleFactorChanged(float) override; + void visibilityDidChange(bool) override { } + void frameDidFinishLoading(uint64_t requestID) override; + void frameDidFail(uint64_t requestID, bool wasCancelled) override; + void didEvaluateJavaScript(uint64_t requestID, const String& result) override; + void streamWillSendRequest(uint64_t streamID, const WebCore::URL& requestURL, const WebCore::URL& responseURL, int responseStatus) override { } + void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override; + void streamDidFinishLoading(uint64_t streamID) override; + void streamDidFail(uint64_t streamID, bool wasCancelled) override; + void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& suggestedFileName) override; + void manualStreamDidReceiveData(const char* bytes, int length) override; + void manualStreamDidFinishLoading() override; + void manualStreamDidFail(bool wasCancelled) override; + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override; + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleContextMenuEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override; + bool handleEditingCommand(const String& commandName, const String& argument) override; + bool isEditingCommandEnabled(const String&) override; + bool handlesPageScaleFactor() const override; + bool requiresUnifiedScaleFactor() const override { return true; } + void setFocus(bool) override { } + NPObject* pluginScriptableNPObject() override { return 0; } + void windowFocusChanged(bool) override { } + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override { } + void windowVisibilityChanged(bool) override { } + uint64_t pluginComplexTextInputIdentifier() const override { return 0; } + void sendComplexTextInput(const String& textInput) override { } + void setLayerHostingMode(LayerHostingMode) override { } + WebCore::Scrollbar* horizontalScrollbar() override { return m_horizontalScrollbar.get(); } + WebCore::Scrollbar* verticalScrollbar() override { return m_verticalScrollbar.get(); } + void storageBlockingStateChanged(bool) override { } + void privateBrowsingStateChanged(bool) override { } + bool getFormValue(String& formValue) override { return false; } + bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override; + RefPtr<WebCore::SharedBuffer> liveResourceData() const override; + void willDetatchRenderer() override; + + bool isBeingAsynchronouslyInitialized() const override { return false; } + + RetainPtr<PDFDocument> pdfDocumentForPrinting() const override { return m_pdfDocument; } + NSObject *accessibilityObject() const override; + + unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) override; + bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount) override; + + PDFSelection *nextMatchForString(const String& target, BOOL searchForward, BOOL caseSensitive, BOOL wrapSearch, PDFSelection *initialSelection, BOOL startInSelection); + + bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override; + String getSelectionString() const override; + String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override; + bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override; + + bool shouldAllowScripting() override { return false; } + bool shouldAllowNavigationFromDrags() override { return true; } + bool shouldAlwaysAutoStart() const override { return true; } + + // ScrollableArea functions. + WebCore::IntRect scrollCornerRect() const override; + WebCore::ScrollableArea* enclosingScrollableArea() const override; + bool isScrollableOrRubberbandable() override { return true; } + bool hasScrollableOrRubberbandableAncestor() override { return true; } + WebCore::IntRect scrollableAreaBoundingBox(bool* = nullptr) const override; + void setScrollOffset(const WebCore::ScrollOffset&) override; + void invalidateScrollbarRect(WebCore::Scrollbar&, const WebCore::IntRect&) override; + void invalidateScrollCornerRect(const WebCore::IntRect&) override; + WebCore::IntPoint lastKnownMousePosition() const override { return m_lastMousePositionInPluginCoordinates; } + int scrollSize(WebCore::ScrollbarOrientation) const override; + bool isActive() const override; + bool isScrollCornerVisible() const override { return false; } + int scrollOffset(WebCore::ScrollbarOrientation) const override; + WebCore::ScrollPosition scrollPosition() const override; + WebCore::ScrollPosition minimumScrollPosition() const override; + WebCore::ScrollPosition maximumScrollPosition() const override; + WebCore::IntSize visibleSize() const override { return m_size; } + WebCore::IntSize contentsSize() const override { return m_pdfDocumentSize; } + WebCore::Scrollbar* horizontalScrollbar() const override { return m_horizontalScrollbar.get(); } + WebCore::Scrollbar* verticalScrollbar() const override { return m_verticalScrollbar.get(); } + bool shouldSuspendScrollAnimations() const override { return false; } // If we return true, ScrollAnimatorMac will keep cycling a timer forever, waiting for a good time to animate. + void scrollbarStyleChanged(WebCore::ScrollbarStyle, bool forceUpdate) override; + WebCore::IntRect convertFromScrollbarToContainingView(const WebCore::Scrollbar&, const WebCore::IntRect& scrollbarRect) const override; + WebCore::IntRect convertFromContainingViewToScrollbar(const WebCore::Scrollbar&, const WebCore::IntRect& parentRect) const override; + WebCore::IntPoint convertFromScrollbarToContainingView(const WebCore::Scrollbar&, const WebCore::IntPoint& scrollbarPoint) const override; + WebCore::IntPoint convertFromContainingViewToScrollbar(const WebCore::Scrollbar&, const WebCore::IntPoint& parentPoint) const override; + bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override; + + // PDFPlugin functions. + void updateScrollbars(); + Ref<WebCore::Scrollbar> createScrollbar(WebCore::ScrollbarOrientation); + void destroyScrollbar(WebCore::ScrollbarOrientation); + void pdfDocumentDidLoad(); + void addArchiveResource(); + void computePageBoxes(); + void calculateSizes(); + void runScriptsInPDFDocument(); + + NSEvent *nsEventForWebMouseEvent(const WebMouseEvent&); + WebCore::IntPoint convertFromPluginToPDFView(const WebCore::IntPoint&) const; + WebCore::IntPoint convertFromRootViewToPlugin(const WebCore::IntPoint&) const; + WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const; + + bool supportsForms(); + bool isFullFramePlugin() const; + + void updatePageAndDeviceScaleFactors(); + + void createPasswordEntryForm(); + + RetainPtr<PDFDocument> pdfDocument() const { return m_pdfDocument; } + void setPDFDocument(RetainPtr<PDFDocument> document) { m_pdfDocument = document; } + + WebCore::IntSize pdfDocumentSize() const { return m_pdfDocumentSize; } + void setPDFDocumentSize(WebCore::IntSize size) { m_pdfDocumentSize = size; } + + NSData *liveData() const; + NSData *rawData() const { return (NSData *)m_data.get(); } + + WebFrame* webFrame() const { return m_frame; } + + enum UpdateCursorMode { + UpdateIfNeeded, + ForceUpdate + }; + + enum HitTestResult { + None, + Text + }; + + void updateCursor(const WebMouseEvent&, UpdateCursorMode = UpdateIfNeeded); + + JSObjectRef makeJSPDFDoc(JSContextRef); + static JSValueRef jsPDFDocPrint(JSContextRef, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + + void convertPostScriptDataIfNeeded(); + + // Regular plug-ins don't need access to view, but we add scrollbars to embedding FrameView for proper event handling. + PluginView* pluginView(); + const PluginView* pluginView() const; + + WebFrame* m_frame; + + bool m_isPostScript; + bool m_pdfDocumentWasMutated; + + WebCore::IntSize m_scrollOffset; + + RetainPtr<CALayer> m_containerLayer; + RetainPtr<CALayer> m_contentLayer; + RetainPtr<CALayer> m_horizontalScrollbarLayer; + RetainPtr<CALayer> m_verticalScrollbarLayer; + RetainPtr<CALayer> m_scrollCornerLayer; + RetainPtr<PDFLayerController> m_pdfLayerController; + RetainPtr<WKPDFPluginAccessibilityObject> m_accessibilityObject; + + RefPtr<PDFPluginAnnotation> m_activeAnnotation; + RefPtr<PDFPluginPasswordField> m_passwordField; + RefPtr<WebCore::Element> m_annotationContainer; + + WebCore::AffineTransform m_rootViewToPluginTransform; + WebMouseEvent m_lastMouseEvent; + WebCore::IntPoint m_lastMousePositionInPluginCoordinates; + + String m_temporaryPDFUUID; + + String m_lastFoundString; + + HitTestResult m_lastHitTestResult; + + RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate; + + WebCore::IntSize m_size; + + WebCore::URL m_sourceURL; + + String m_suggestedFilename; + RetainPtr<CFMutableDataRef> m_data; + + RetainPtr<PDFDocument> m_pdfDocument; + Vector<WebCore::IntRect> m_pageBoxes; + WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps. + + RefPtr<WebCore::Scrollbar> m_horizontalScrollbar; + RefPtr<WebCore::Scrollbar> m_verticalScrollbar; +}; + +} // namespace WebKit + +SPECIALIZE_TYPE_TRAITS_PLUGIN(PDFPlugin, PDFPluginType) + +#endif // ENABLE(PDFKIT_PLUGIN) + +#endif // DeprecatedPDFPlugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFAnnotationTextWidgetDetails.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFAnnotationTextWidgetDetails.h new file mode 100644 index 000000000..8656ff466 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFAnnotationTextWidgetDetails.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <PDFKit/PDFKit.h> + +@interface PDFAnnotationTextWidget (Details) +- (BOOL)isMultiline; +- (BOOL)isReadOnly; +@end diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h new file mode 100644 index 000000000..858f5f10c --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PDFLayerControllerSPI_h +#define PDFLayerControllerSPI_h + +#include "PDFKitImports.h" + +#if ENABLE(PDFKIT_PLUGIN) +#if USE(DEPRECATED_PDF_PLUGIN) + +#include "DeprecatedPDFLayerControllerSPI.h" + +#else // USE(DEPRECATED_PDF_PLUGIN) + +#import <PDFKit/PDFKit.h> + +@class CPReadingModel; +@class PDFViewLayout; + +@protocol PDFLayerControllerDelegate <NSObject> + +@optional + +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController scrollToPoint:(CGPoint)newPosition; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController invalidateRect:(CGRect)rect; +- (void)pdfLayerControllerInvalidateHUD:(PDFLayerController *)pdfLayerController; + +- (void)pdfLayerControllerZoomIn:(PDFLayerController *)pdfLayerController; +- (void)pdfLayerControllerZoomOut:(PDFLayerController *)pdfLayerController; + +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeActiveAnnotation:(PDFAnnotation *)annotation; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didClickLinkWithURL:(NSURL *)url; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeDisplayMode:(int)mode; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeSelection:(PDFSelection *)selection; + +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController copyItems:(NSArray *)items withTypes:(NSArray *)types; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController showDefinitionForAttributedString:(NSAttributedString *)string atPoint:(CGPoint)point; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController performWebSearchForString:(NSString *)string; +- (void)pdfLayerController:(PDFLayerController *)pdfLayerController performSpotlightSearchForString:(NSString *)string; +- (void)pdfLayerControllerSaveToPDF:(PDFLayerController *)pdfLayerController; +- (void)pdfLayerControllerOpenWithNativeApplication:(PDFLayerController *)pdfLayerController; + +- (NSColorSpace*)pdfLayerControllerColorSpace:(PDFLayerController *)pdfLayerController; + +@end + +@interface PDFLayerController : NSObject +@end + +@interface PDFLayerController () + +@property (retain) PDFDocument *document; +@property (assign) id<PDFLayerControllerDelegate> delegate; +@property (retain) NSArray *searchMatches; + +- (void)setFrameSize:(CGSize)size; + +- (void)setDisplayMode:(int)mode; +- (int)displayMode; +- (int)realDisplayMode; + +- (CGSize)contentSize; +- (CGSize)contentSizeRespectingZoom; + +- (CGFloat)contentScaleFactor; +- (void)setContentScaleFactor:(CGFloat)contentScaleFactor; + +- (PDFViewLayout *)layout; + +- (void)drawInContext:(CGContextRef)context; +- (void)drawHUDInContext:(CGContextRef)context; + +- (void)mouseDown:(NSEvent *)event; +- (void)mouseUp:(NSEvent *)event; +- (void)mouseDragged:(NSEvent *)event; + +- (BOOL)mouseDown:(NSEvent *)event inHUDWithBounds:(CGRect)bounds; +- (BOOL)mouseUp:(NSEvent *)event inHUDWithBounds:(CGRect)bounds; +- (BOOL)mouseDragged:(NSEvent *)event inHUDWithBounds:(CGRect)bounds; + +- (NSMenu *)menuForEvent:(NSEvent *)event; + +- (NSArray *)pageRects; + +- (void)setVisibleRect:(CGRect)visibleRect; + +- (void)gotoSelection:(PDFSelection *)selection; +- (void)gotoDestination:(PDFDestination *)destination; +- (void)gotoRect:(CGRect)rect onPage:(PDFPage *)page; + +- (PDFSelection *)currentSelection; +- (void)setCurrentSelection:(PDFSelection *)selection; + +- (void)searchInDictionaryWithSelection:(PDFSelection *)selection; +- (PDFSelection *)getSelectionForWordAtPoint:(CGPoint)point; +- (NSArray *)rectsForSelectionInLayoutSpace:(PDFSelection *)selection; + +- (NSArray *)highlights; +- (void)setHighlights:(NSArray*)highlights; + +- (PDFSelection *)searchSelection; +- (NSArray *)searchMatches; +- (void)setSearchSelection:(PDFSelection*)selection; +- (NSArray *)findString:(NSString *)string caseSensitive:(BOOL)isCaseSensitive highlightMatches:(BOOL)shouldHighlightMatches; + +- (void)copySelection; +- (void)selectAll; + +- (PDFPage *)currentPage; +- (NSUInteger)currentPageIndex; + +- (BOOL)documentIsLocked; +- (void)attemptToUnlockWithPassword:(NSString *)password; + +- (CGRect)boundsForAnnotation:(PDFAnnotation *)annotation; +- (void)activateNextAnnotation:(BOOL)previous; + +- (NSRect)frame; + +// Accessibility + +- (CPReadingModel *)readingModel; +- (id)accessibilityFocusedUIElement; +- (NSArray *)accessibilityAttributeNames; +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute; +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute; +- (NSArray *)accessibilityParameterizedAttributeNames; +- (NSString *)accessibilityRoleAttribute; +- (NSString *)accessibilityRoleDescriptionAttribute; +- (NSString *)accessibilityValueAttribute; +- (BOOL)accessibilityIsValueAttributeSettable; +- (NSString *)accessibilitySelectedTextAttribute; +- (BOOL)accessibilityIsSelectedTextAttributeSettable; +- (NSValue *)accessibilitySelectedTextRangeAttribute; +- (NSNumber *)accessibilityNumberOfCharactersAttribute; +- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable; +- (NSValue *)accessibilityVisibleCharacterRangeAttribute; +- (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable; +- (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter; +- (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter; +- (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter; +- (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter; + +@end + +#endif // USE(DEPRECATED_PDF_PLUGIN) +#endif // ENABLE(PDFPLUGIN) + +#endif // PDFLayerControllerSPI_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h new file mode 100644 index 000000000..0c6ab1f3b --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2011, 2012, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PDFPlugin_h +#define PDFPlugin_h + +#include "PDFKitImports.h" + +#if ENABLE(PDFKIT_PLUGIN) +#if USE(DEPRECATED_PDF_PLUGIN) + +#include "DeprecatedPDFPlugin.h" + +#else // USE(DEPRECATED_PDF_PLUGIN) + +#include "Plugin.h" +#include "WebEvent.h" +#include "WebHitTestResultData.h" +#include <WebCore/AffineTransform.h> +#include <WebCore/FindOptions.h> +#include <WebCore/PageOverlay.h> +#include <WebCore/ScrollableArea.h> +#include <wtf/RetainPtr.h> + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; +typedef const struct OpaqueJSValue* JSValueRef; + +OBJC_CLASS NSArray; +OBJC_CLASS NSAttributedString; +OBJC_CLASS NSData; +OBJC_CLASS NSString; +OBJC_CLASS PDFAnnotation; +OBJC_CLASS PDFLayerController; +OBJC_CLASS PDFSelection; +OBJC_CLASS WKPDFPluginAccessibilityObject; +OBJC_CLASS WKPDFLayerControllerDelegate; + +namespace IPC { +class DataReference; +} + +namespace WebCore { +class Element; +struct PluginInfo; +} + +namespace WebKit { + +class PDFPluginAnnotation; +class PDFPluginPasswordField; +class PluginView; +class WebFrame; + +class PDFPlugin final : public Plugin { +public: + static Ref<PDFPlugin> create(WebFrame*); + ~PDFPlugin(); + + static WebCore::PluginInfo pluginInfo(); + + WebCore::IntSize size() const { return m_size; } + float scaleFactor() const; + + void didMutatePDFDocument() { m_pdfDocumentWasMutated = true; } + + void setActiveAnnotation(PDFAnnotation *); + + void notifyDisplayModeChanged(int); + + void notifySelectionChanged(PDFSelection *); + + void clickedLink(NSURL *); + void saveToPDF(); + void openWithNativeApplication(); + void writeItemsToPasteboard(NSString *pasteboardName, NSArray *items, NSArray *types); + void showDefinitionForAttributedString(NSAttributedString *, CGPoint); + void performWebSearch(NSString *); + void performSpotlightSearch(NSString *); + void invalidatePDFRect(WebCore::IntRect); + void invalidateHUD(); + void scrollToPoint(WebCore::IntPoint); + + void zoomIn(); + void zoomOut(); + + void focusNextAnnotation(); + void focusPreviousAnnotation(); + + void attemptToUnlockPDF(const String& password); + + WebCore::IntPoint convertFromPluginToPDFView(const WebCore::IntPoint&) const; + WebCore::IntPoint convertFromRootViewToPlugin(const WebCore::IntPoint&) const; + WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const; + + WebCore::IntRect convertFromPDFViewToRootView(const WebCore::IntRect&) const; + WebCore::FloatRect convertFromPDFViewToScreen(const WebCore::FloatRect&) const; + + WebCore::IntRect boundsOnScreen() const; + + bool showContextMenuAtPoint(const WebCore::IntPoint&); + + String lookupTextAtLocation(const WebCore::FloatPoint&, WebHitTestResultData&, PDFSelection **, NSDictionary **) const; + WebCore::FloatRect rectForSelectionInRootView(PDFSelection *) const; + + PDFLayerController *pdfLayerController() const { return m_pdfLayerController.get(); } + WebFrame* webFrame() const { return m_frame; } + + bool isLocked() const; + +private: + explicit PDFPlugin(WebFrame*); + + // Plugin functions. + bool initialize(const Parameters&) override; + void destroy() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRectInWindowCoordinates) override; + void updateControlTints(WebCore::GraphicsContext&) override { } + bool supportsSnapshotting() const override { return false; } + RefPtr<ShareableBitmap> snapshot() override; + PlatformLayer* pluginLayer() override { return nullptr; } + bool isTransparent() override { return false; } + bool wantsWheelEvents() override { return false; } + void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override; + void contentsScaleFactorChanged(float) override { } + void visibilityDidChange(bool) override { } + void frameDidFinishLoading(uint64_t requestID) override; + void frameDidFail(uint64_t requestID, bool wasCancelled) override; + void didEvaluateJavaScript(uint64_t requestID, const String& result) override; + void streamWillSendRequest(uint64_t streamID, const WebCore::URL& requestURL, const WebCore::URL& responseURL, int responseStatus) override { } + void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override; + void streamDidFinishLoading(uint64_t streamID) override; + void streamDidFail(uint64_t streamID, bool wasCancelled) override; + void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& suggestedFileName) override; + void manualStreamDidReceiveData(const char* bytes, int length) override; + void manualStreamDidFinishLoading() override; + void manualStreamDidFail(bool wasCancelled) override; + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override { return false; } + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleContextMenuEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override { return false; } + bool handleEditingCommand(const String& commandName, const String& argument) override; + bool isEditingCommandEnabled(const String&) override; + void setFocus(bool) override { } + NPObject* pluginScriptableNPObject() override { return nullptr; } + void windowFocusChanged(bool) override { } + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override { } + void windowVisibilityChanged(bool) override { } + uint64_t pluginComplexTextInputIdentifier() const override { return 0; } + void sendComplexTextInput(const String& textInput) override { } + void setLayerHostingMode(LayerHostingMode) override { } + WebCore::Scrollbar* horizontalScrollbar() override { return nullptr; } + WebCore::Scrollbar* verticalScrollbar() override { return nullptr; } + void storageBlockingStateChanged(bool) override { } + void privateBrowsingStateChanged(bool) override { } + bool getFormValue(String& formValue) override { return false; } + bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override { return false; } + RefPtr<WebCore::SharedBuffer> liveResourceData() const override; + + bool handlesPageScaleFactor() const override { return false; } + bool requiresUnifiedScaleFactor() const override { return true; } + + bool isBeingAsynchronouslyInitialized() const override { return false; } + + RetainPtr<PDFDocument> pdfDocumentForPrinting() const override { return m_pdfDocument; } + NSObject *accessibilityObject() const override; + + unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) override; + bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount) override; + + PDFSelection *nextMatchForString(const String& target, BOOL searchForward, BOOL caseSensitive, BOOL wrapSearch, PDFSelection *initialSelection, BOOL startInSelection); + + bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override; + String getSelectionString() const override; + String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override; + bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override; + + bool shouldAllowScripting() override { return false; } + bool shouldAllowNavigationFromDrags() override { return true; } + bool shouldAlwaysAutoStart() const override { return true; } + bool canCreateTransientPaintingSnapshot() const override { return false; } + + // PDFPlugin functions. + void pdfDocumentDidLoad(); + void addArchiveResource(); + void computePageBoxes(); + void calculateSizes(); + void didCalculateSizes(); + void runScriptsInPDFDocument(); + + NSEvent *nsEventForWebMouseEvent(const WebMouseEvent&); + + bool supportsForms(); + bool isFullFramePlugin() const; + + void createPasswordEntryForm(); + + RetainPtr<PDFDocument> pdfDocument() const { return m_pdfDocument; } + void setPDFDocument(RetainPtr<PDFDocument> document) { m_pdfDocument = document; } + + WebCore::IntSize pdfDocumentSize() const { return m_pdfDocumentSize; } + void setPDFDocumentSize(WebCore::IntSize size) { m_pdfDocumentSize = size; } + + NSData *liveData() const; + NSData *rawData() const { return (NSData *)m_data.get(); } + + enum class UpdateCursor { + IfNeeded, + Force + }; + + enum class HitTestResult { + None, + Text, + HUD + }; + + void updateCursor(const WebMouseEvent&, UpdateCursor = UpdateCursor::IfNeeded); + + JSObjectRef makeJSPDFDoc(JSContextRef); + static JSValueRef jsPDFDocPrint(JSContextRef, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + + void convertPostScriptDataIfNeeded(); + + PluginView* pluginView(); + const PluginView* pluginView() const; + + class HUD : public WebCore::PageOverlay::Client { + public: + explicit HUD(PDFPlugin& plugin); + virtual ~HUD(); + + void invalidate(); + bool containsPointInRootView(WebCore::IntPoint); + + enum class AnimateVisibilityTransition { No, Yes }; + void setVisible(bool, AnimateVisibilityTransition); + + private: + void willMoveToPage(WebCore::PageOverlay&, WebCore::Page*) override; + void didMoveToPage(WebCore::PageOverlay&, WebCore::Page*) override; + void drawRect(WebCore::PageOverlay&, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override; + bool mouseEvent(WebCore::PageOverlay&, const WebCore::PlatformMouseEvent&) override; + + WebCore::IntRect frameInRootView() const; + + bool m_visible { false }; + Ref<WebCore::PageOverlay> m_overlay; + PDFPlugin& m_plugin; + }; + + WebFrame* m_frame; + + bool m_isPostScript { false }; + bool m_pdfDocumentWasMutated { false }; + bool m_usingContinuousMode { true }; + + RetainPtr<PDFLayerController> m_pdfLayerController; + RetainPtr<WKPDFPluginAccessibilityObject> m_accessibilityObject; + + RefPtr<PDFPluginAnnotation> m_activeAnnotation; + RefPtr<PDFPluginPasswordField> m_passwordField; + RefPtr<WebCore::Element> m_passwordContainer; + + WebCore::AffineTransform m_rootViewToPluginTransform; + WebCore::AffineTransform m_pluginToRootViewTransform; + WebMouseEvent m_lastMouseEvent; + WebCore::IntPoint m_lastMousePositionInPluginCoordinates; + + String m_temporaryPDFUUID; + + String m_lastFoundString; + + HitTestResult m_lastHitTestResult; + + RetainPtr<WKPDFLayerControllerDelegate> m_pdfLayerControllerDelegate; + + WebCore::IntSize m_size; + + WebCore::URL m_sourceURL; + + String m_suggestedFilename; + RetainPtr<CFMutableDataRef> m_data; + + RetainPtr<PDFDocument> m_pdfDocument; + WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps. + + HUD m_HUD; +}; + +} // namespace WebKit + +SPECIALIZE_TYPE_TRAITS_PLUGIN(PDFPlugin, PDFPluginType) + +#endif // USE(DEPRECATED_PDF_PLUGIN) +#endif // ENABLE(PDFKIT_PLUGIN) + +#endif // PDFPlugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h new file mode 100644 index 000000000..f6339701e --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PDFPluginAnnotation_h +#define PDFPluginAnnotation_h + +#if ENABLE(PDFKIT_PLUGIN) + +#include <WebCore/EventListener.h> +#include <wtf/RefCounted.h> +#include <wtf/RetainPtr.h> + +namespace WebCore { +class Document; +class Element; +} + +OBJC_CLASS PDFAnnotation; +OBJC_CLASS PDFLayerController; + +namespace WebKit { + +class PDFPlugin; + +class PDFPluginAnnotation : public RefCounted<PDFPluginAnnotation> { +public: + static PassRefPtr<PDFPluginAnnotation> create(PDFAnnotation *, PDFLayerController *, PDFPlugin*); + virtual ~PDFPluginAnnotation(); + + WebCore::Element* element() const { return m_element.get(); } + PDFAnnotation *annotation() const { return m_annotation.get(); } + PDFPlugin* plugin() const { return m_plugin; } + + virtual void updateGeometry(); + virtual void commit(); + + void attach(WebCore::Element*); + +protected: + PDFPluginAnnotation(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin) + : m_parent(0) + , m_annotation(annotation) + , m_eventListener(PDFPluginAnnotationEventListener::create(this)) + , m_pdfLayerController(pdfLayerController) + , m_plugin(plugin) + { + } + + WebCore::Element* parent() const { return m_parent; } + PDFLayerController *pdfLayerController() const { return m_pdfLayerController; } + WebCore::EventListener* eventListener() const { return m_eventListener.get(); } + + virtual bool handleEvent(WebCore::Event*); + +private: + virtual PassRefPtr<WebCore::Element> createAnnotationElement() = 0; + + class PDFPluginAnnotationEventListener : public WebCore::EventListener { + public: + static Ref<PDFPluginAnnotationEventListener> create(PDFPluginAnnotation* annotation) + { + return adoptRef(*new PDFPluginAnnotationEventListener(annotation)); + } + + bool operator==(const EventListener& listener) const override { return this == &listener; } + + void setAnnotation(PDFPluginAnnotation* annotation) { m_annotation = annotation; } + + private: + + PDFPluginAnnotationEventListener(PDFPluginAnnotation* annotation) + : WebCore::EventListener(WebCore::EventListener::CPPEventListenerType) + , m_annotation(annotation) + { + } + + void handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) override; + + PDFPluginAnnotation* m_annotation; + }; + + WebCore::Element* m_parent; + + RefPtr<WebCore::Element> m_element; + RetainPtr<PDFAnnotation> m_annotation; + + RefPtr<PDFPluginAnnotationEventListener> m_eventListener; + + PDFLayerController *m_pdfLayerController; + PDFPlugin* m_plugin; +}; + +} // namespace WebKit + +#endif // ENABLE(PDFKIT_PLUGIN) + +#endif // PDFPluginAnnotation_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h new file mode 100644 index 000000000..6af87cd7f --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PDFPluginChoiceAnnotation_h +#define PDFPluginChoiceAnnotation_h + +#if ENABLE(PDFKIT_PLUGIN) + +#include "PDFPluginAnnotation.h" + +namespace WebCore { +class Element; +} + +OBJC_CLASS PDFAnnotationChoiceWidget; + +namespace WebKit { + +class PDFPluginChoiceAnnotation : public PDFPluginAnnotation { +public: + static Ref<PDFPluginChoiceAnnotation> create(PDFAnnotation *, PDFLayerController *, PDFPlugin*); + + void updateGeometry() override; + void commit() override; + +private: + PDFPluginChoiceAnnotation(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin) + : PDFPluginAnnotation(annotation, pdfLayerController, plugin) + { + } + + PassRefPtr<WebCore::Element> createAnnotationElement() override; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + PDFAnnotationChoiceWidget *choiceAnnotation() { return static_cast<PDFAnnotationChoiceWidget *>(annotation()); } +#pragma clang diagnostic pop +}; + +} // namespace WebKit + +#endif // ENABLE(PDFKIT_PLUGIN) + +#endif // PDFPluginChoiceAnnotation_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginPasswordField.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginPasswordField.h new file mode 100644 index 000000000..163250adb --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginPasswordField.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PDFPluginPasswordField_h +#define PDFPluginPasswordField_h + +#if ENABLE(PDFKIT_PLUGIN) + +#include "PDFPluginTextAnnotation.h" + +namespace WebKit { + +class PDFPluginPasswordField : public PDFPluginTextAnnotation { +public: + static Ref<PDFPluginPasswordField> create(PDFLayerController *, PDFPlugin*); + virtual ~PDFPluginPasswordField(); + + void updateGeometry() override; + +private: + PDFPluginPasswordField(PDFLayerController *pdfLayerController, PDFPlugin* plugin) + : PDFPluginTextAnnotation(0, pdfLayerController, plugin) + { + } + + PassRefPtr<WebCore::Element> createAnnotationElement() override; + + bool handleEvent(WebCore::Event*) override; +}; + +} // namespace WebKit + +#endif // ENABLE(PDFKIT_PLUGIN) + +#endif // PDFPluginTextAnnotation_h diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h new file mode 100644 index 000000000..a8e62e9cc --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PDFPluginTextAnnotation_h +#define PDFPluginTextAnnotation_h + +#if ENABLE(PDFKIT_PLUGIN) + +#include "PDFPluginAnnotation.h" + +#include <wtf/text/WTFString.h> + +namespace WebCore { +class Element; +} + +OBJC_CLASS PDFAnnotationTextWidget; + +namespace WebKit { + +class PDFPluginTextAnnotation : public PDFPluginAnnotation { +public: + static Ref<PDFPluginTextAnnotation> create(PDFAnnotation *, PDFLayerController *, PDFPlugin*); + virtual ~PDFPluginTextAnnotation(); + + void updateGeometry() override; + void commit() override; + +protected: + PDFPluginTextAnnotation(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin) + : PDFPluginAnnotation(annotation, pdfLayerController, plugin) + { + } + + PassRefPtr<WebCore::Element> createAnnotationElement() override; + String value() const; + +private: + bool handleEvent(WebCore::Event*) override; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + PDFAnnotationTextWidget *textAnnotation() const { return static_cast<PDFAnnotationTextWidget *>(annotation()); } +#pragma clang diagnostic pop +}; + +} // namespace WebKit + +#endif // ENABLE(PDFKIT_PLUGIN) + +#endif // PDFPluginTextAnnotation_h diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.cpp b/Source/WebKit2/WebProcess/Plugins/Plugin.cpp index 119d5ab78..ec23fcf31 100644 --- a/Source/WebKit2/WebProcess/Plugins/Plugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.cpp @@ -33,7 +33,7 @@ using namespace WebCore; namespace WebKit { -void Plugin::Parameters::encode(IPC::ArgumentEncoder& encoder) const +void Plugin::Parameters::encode(IPC::Encoder& encoder) const { encoder << url.string(); encoder << names; @@ -41,12 +41,12 @@ void Plugin::Parameters::encode(IPC::ArgumentEncoder& encoder) const encoder << mimeType; encoder << isFullFramePlugin; encoder << shouldUseManualLoader; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) encoder.encodeEnum(layerHostingMode); #endif } -bool Plugin::Parameters::decode(IPC::ArgumentDecoder& decoder, Parameters& parameters) +bool Plugin::Parameters::decode(IPC::Decoder& decoder, Parameters& parameters) { String urlString; if (!decoder.decode(urlString)) @@ -64,7 +64,7 @@ bool Plugin::Parameters::decode(IPC::ArgumentDecoder& decoder, Parameters& param return false; if (!decoder.decode(parameters.shouldUseManualLoader)) return false; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (!decoder.decodeEnum(parameters.layerHostingMode)) return false; #endif @@ -76,8 +76,9 @@ bool Plugin::Parameters::decode(IPC::ArgumentDecoder& decoder, Parameters& param return true; } -Plugin::Plugin() - : m_pluginController(0) +Plugin::Plugin(PluginType type) + : m_type(type) + , m_pluginController(0) { } @@ -102,7 +103,7 @@ void Plugin::destroyPlugin() m_pluginController = 0; } -void Plugin::updateControlTints(GraphicsContext*) +void Plugin::updateControlTints(GraphicsContext&) { } diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.h b/Source/WebKit2/WebProcess/Plugins/Plugin.h index 29ffac93b..a86773caf 100644 --- a/Source/WebKit2/WebProcess/Plugins/Plugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,18 +35,20 @@ #include <wtf/RetainPtr.h> #include <wtf/Vector.h> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include "LayerHostingContext.h" +OBJC_CLASS NSDictionary; OBJC_CLASS NSObject; OBJC_CLASS PDFDocument; +OBJC_CLASS PDFSelection; #endif struct NPObject; namespace IPC { - class ArgumentEncoder; - class ArgumentDecoder; +class Encoder; +class Decoder; } namespace WebCore { @@ -70,6 +72,12 @@ class WebWheelEvent; class PluginController; +enum PluginType { + PluginProxyType, + NetscapePluginType, + PDFPluginType, +}; + class Plugin : public ThreadSafeRefCounted<Plugin> { public: struct Parameters { @@ -79,12 +87,12 @@ public: String mimeType; bool isFullFramePlugin; bool shouldUseManualLoader; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) LayerHostingMode layerHostingMode; #endif - void encode(IPC::ArgumentEncoder&) const; - static bool decode(IPC::ArgumentDecoder&, Parameters&); + void encode(IPC::Encoder&) const; + static bool decode(IPC::Decoder&, Parameters&); }; // Sets the active plug-in controller and initializes the plug-in. @@ -101,6 +109,8 @@ public: virtual ~Plugin(); + PluginType type() const { return m_type; } + private: // Initializes the plug-in. If the plug-in fails to initialize this should return false. @@ -114,18 +124,18 @@ public: // Tells the plug-in to paint itself into the given graphics context. The passed-in context and // dirty rect are in window coordinates. The context is saved/restored by the caller. - virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect) = 0; + virtual void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) = 0; // Invalidate native tintable controls. The passed-in context is in window coordinates. - virtual void updateControlTints(WebCore::GraphicsContext*); + virtual void updateControlTints(WebCore::GraphicsContext&); // Returns whether the plug-in supports snapshotting or not. virtual bool supportsSnapshotting() const = 0; // Tells the plug-in to draw itself into a bitmap, and return that. - virtual PassRefPtr<ShareableBitmap> snapshot() = 0; + virtual RefPtr<ShareableBitmap> snapshot() = 0; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // If a plug-in is using the Core Animation drawing model, this returns its plug-in layer. virtual PlatformLayer* pluginLayer() = 0; #endif @@ -153,6 +163,9 @@ public: // back the result. If evaluating the script failed, result will be null. virtual void didEvaluateJavaScript(uint64_t requestID, const String& result) = 0; + // Tells the plug-in that a stream may send an HTTP request. + virtual void streamWillSendRequest(uint64_t streamID, const WebCore::URL& requestURL, const WebCore::URL& responseURL, int responseStatusCode) = 0; + // Tells the plug-in that a stream has received its HTTP response. virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) = 0; @@ -208,25 +221,25 @@ public: // Ask the plug-in whether it wants URLs and files dragged onto it to cause navigation. virtual bool shouldAllowNavigationFromDrags() = 0; - + // Ask the plug-in whether it wants to override full-page zoom. - virtual bool handlesPageScaleFactor() = 0; - + virtual bool handlesPageScaleFactor() const = 0; + // Tells the plug-in about focus changes. virtual void setFocus(bool) = 0; // Get the NPObject that corresponds to the plug-in's scriptable object. Returns a retained object. virtual NPObject* pluginScriptableNPObject() = 0; -#if PLATFORM(MAC) // Tells the plug-in about window focus changes. virtual void windowFocusChanged(bool) = 0; - - // Tells the plug-in about window and plug-in frame changes. - virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) = 0; - + // Tells the plug-in about window visibility changes. virtual void windowVisibilityChanged(bool) = 0; + +#if PLATFORM(COCOA) + // Tells the plug-in about window and plug-in frame changes. + virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) = 0; // Get the per complex text input identifier. virtual uint64_t pluginComplexTextInputIdentifier() const = 0; @@ -258,7 +271,7 @@ public: virtual WebCore::Scrollbar* horizontalScrollbar() = 0; virtual WebCore::Scrollbar* verticalScrollbar() = 0; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) virtual RetainPtr<PDFDocument> pdfDocumentForPrinting() const { return 0; } virtual NSObject *accessibilityObject() const { return 0; } #endif @@ -271,14 +284,26 @@ public: virtual bool shouldAlwaysAutoStart() const { return false; } - virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const = 0; + virtual RefPtr<WebCore::SharedBuffer> liveResourceData() const = 0; virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) = 0; virtual String getSelectionString() const = 0; + virtual String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const = 0; + virtual bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const = 0; + + virtual void mutedStateChanged(bool) { } + + virtual bool canCreateTransientPaintingSnapshot() const { return true; } + + virtual bool requiresUnifiedScaleFactor() const { return false; } + + virtual void willDetatchRenderer() { } protected: - Plugin(); + Plugin(PluginType); + + PluginType m_type; private: PluginController* m_pluginController; @@ -286,4 +311,9 @@ private: } // namespace WebKit +#define SPECIALIZE_TYPE_TRAITS_PLUGIN(ToValueTypeName, SpecificPluginType) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebKit::ToValueTypeName) \ +static bool isType(const WebKit::Plugin& plugin) { return plugin.type() == WebKit::SpecificPluginType; } \ +SPECIALIZE_TYPE_TRAITS_END() + #endif // Plugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginController.h b/Source/WebKit2/WebProcess/Plugins/PluginController.h index 85cced767..6fa0586aa 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginController.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginController.h @@ -28,7 +28,7 @@ #include <wtf/Forward.h> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include "PluginComplexTextInputState.h" #endif @@ -37,19 +37,17 @@ typedef struct _NPVariant NPVariant; typedef void* NPIdentifier; namespace WebCore { - class HTTPHeaderMap; - class IntRect; - class URL; - class ProtectionSpace; +class HTTPHeaderMap; +class IntRect; +class MachSendRight; +class ProtectionSpace; +class URL; } namespace WebKit { class PluginController { public: - // Returns false if the plugin has explicitly been hidden. Returns true otherwise (even if the plugin is currently obscured from view on screen.) - virtual bool isPluginVisible() = 0; - // Tells the controller that the plug-in wants the given rect to be repainted. The rect is in the plug-in's coordinate system. virtual void invalidate(const WebCore::IntRect&) = 0; @@ -66,7 +64,10 @@ public: virtual void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) = 0; - /// Cancels the load of a stream that was requested by loadURL. + // Continues the load of a stream that was requested by loadURL. + virtual void continueStreamLoad(uint64_t streamID) = 0; + + // Cancels the load of a stream that was requested by loadURL. virtual void cancelStreamLoad(uint64_t streamID) = 0; // Cancels the load of the manual stream. @@ -81,23 +82,24 @@ public: // Evaluates the given script string in the context of the given NPObject. virtual bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups) = 0; + + // Called by the Netscape plug-in when it starts or stops playing audio. + virtual void setPluginIsPlayingAudio(bool) = 0; + + // Returns whether the plugin should be muted. + virtual bool isMuted() const = 0; #endif // Set the statusbar text. virtual void setStatusbarText(const String&) = 0; -#if USE(ACCELERATED_COMPOSITING) // Return whether accelerated compositing is enabled. virtual bool isAcceleratedCompositingEnabled() = 0; -#endif // Tells the controller that the plug-in process has crashed. virtual void pluginProcessCrashed() = 0; - - // Tells the controller that we're about to dispatch an event to the plug-in. - virtual void willSendEventToPlugin() = 0; - -#if PLATFORM(MAC) + +#if PLATFORM(COCOA) // Tells the controller that the plug-in focus or window focus did change. virtual void pluginFocusOrWindowFocusChanged(bool) = 0; @@ -105,10 +107,7 @@ public: virtual void setComplexTextInputState(PluginComplexTextInputState) = 0; // Returns the mach port of the compositing render server. - virtual mach_port_t compositingRenderServerPort() = 0; - - // Open the preference pane for this plug-in (as stated in the plug-in's Info.plist). - virtual void openPluginPreferencePane() = 0; + virtual const WebCore::MachSendRight& compositingRenderServerPort() = 0; #endif // Returns the contents scale factor. diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp index aeab8054b..050cca9a2 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp @@ -47,7 +47,7 @@ PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* , m_pluginProcessToken(pluginProcessToken) , m_supportsAsynchronousPluginInitialization(supportsAsynchronousPluginInitialization) { - m_connection = IPC::Connection::createClientConnection(connectionIdentifier, this, RunLoop::main()); + m_connection = IPC::Connection::createClientConnection(connectionIdentifier, *this); m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get()); @@ -88,7 +88,7 @@ void PluginProcessConnection::removePluginProxy(PluginProxy* plugin) m_pluginProcessConnectionManager->removePluginProcessConnection(this); } -void PluginProcessConnection::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) +void PluginProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) { ASSERT(decoder.destinationID()); @@ -99,7 +99,7 @@ void PluginProcessConnection::didReceiveMessage(IPC::Connection* connection, IPC pluginProxy->didReceivePluginProxyMessage(connection, decoder); } -void PluginProcessConnection::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) +void PluginProcessConnection::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) { if (decoder.messageReceiverName() == Messages::NPObjectMessageReceiver::messageReceiverName()) { m_npRemoteObjectMap->didReceiveSyncMessage(connection, decoder, replyEncoder); @@ -120,7 +120,7 @@ void PluginProcessConnection::didReceiveSyncMessage(IPC::Connection* connection, pluginProxy->didReceiveSyncPluginProxyMessage(connection, decoder, replyEncoder); } -void PluginProcessConnection::didClose(IPC::Connection*) +void PluginProcessConnection::didClose(IPC::Connection&) { // The plug-in process must have crashed. for (HashMap<uint64_t, PluginProxy*>::const_iterator::Values it = m_plugins.begin().values(), end = m_plugins.end().values(); it != end; ++it) { @@ -130,7 +130,7 @@ void PluginProcessConnection::didClose(IPC::Connection*) } } -void PluginProcessConnection::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference) +void PluginProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } @@ -138,7 +138,7 @@ void PluginProcessConnection::setException(const String& exceptionString) { NPRuntimeObjectMap::setGlobalException(exceptionString); } - + } // namespace WebKit #endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h index 841ec36d6..6ab6f51bd 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h @@ -42,9 +42,9 @@ class PluginProxy; class PluginProcessConnection : public RefCounted<PluginProcessConnection>, IPC::Connection::Client { public: - static PassRefPtr<PluginProcessConnection> create(PluginProcessConnectionManager* pluginProcessConnectionManager, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization) + static Ref<PluginProcessConnection> create(PluginProcessConnectionManager* pluginProcessConnectionManager, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization) { - return adoptRef(new PluginProcessConnection(pluginProcessConnectionManager, pluginProcessToken, connectionIdentifier, supportsAsynchronousPluginInitialization)); + return adoptRef(*new PluginProcessConnection(pluginProcessConnectionManager, pluginProcessToken, connectionIdentifier, supportsAsynchronousPluginInitialization)); } ~PluginProcessConnection(); @@ -58,18 +58,18 @@ public: NPRemoteObjectMap* npRemoteObjectMap() const { return m_npRemoteObjectMap.get(); } bool supportsAsynchronousPluginInitialization() const { return m_supportsAsynchronousPluginInitialization; } - + private: PluginProcessConnection(PluginProcessConnectionManager*, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousInitialization); // IPC::Connection::Client - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; - virtual void didClose(IPC::Connection*); - virtual void didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; + void didClose(IPC::Connection&) override; + void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; // Message handlers. - void didReceiveSyncPluginProcessConnectionMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + void didReceiveSyncPluginProcessConnectionMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); void setException(const String&); PluginProcessConnectionManager* m_pluginProcessConnectionManager; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp index bd8af4b22..cbc4f0e3e 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp @@ -28,23 +28,23 @@ #if ENABLE(NETSCAPE_PLUGIN_API) -#include "ArgumentDecoder.h" -#include "ArgumentEncoder.h" +#include "Decoder.h" +#include "Encoder.h" #include "PluginProcessConnection.h" #include "PluginProcessConnectionManagerMessages.h" #include "WebCoreArgumentCoders.h" #include "WebProcess.h" #include "WebProcessProxyMessages.h" -#if PLATFORM(MAC) +#if OS(DARWIN) && !USE(UNIX_DOMAIN_SOCKETS) #include "MachPort.h" #endif namespace WebKit { -PassRefPtr<PluginProcessConnectionManager> PluginProcessConnectionManager::create() +Ref<PluginProcessConnectionManager> PluginProcessConnectionManager::create() { - return adoptRef(new PluginProcessConnectionManager); + return adoptRef(*new PluginProcessConnectionManager); } PluginProcessConnectionManager::PluginProcessConnectionManager() @@ -70,25 +70,23 @@ PluginProcessConnection* PluginProcessConnectionManager::getPluginProcessConnect IPC::Attachment encodedConnectionIdentifier; bool supportsAsynchronousInitialization; - if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetPluginProcessConnection(pluginProcessToken), + if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetPluginProcessConnection(pluginProcessToken), Messages::WebProcessProxy::GetPluginProcessConnection::Reply(encodedConnectionIdentifier, supportsAsynchronousInitialization), 0)) return 0; -#if PLATFORM(MAC) +#if USE(UNIX_DOMAIN_SOCKETS) + IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.releaseFileDescriptor(); +#elif OS(DARWIN) IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port()); - if (IPC::Connection::identifierIsNull(connectionIdentifier)) - return 0; -#elif USE(UNIX_DOMAIN_SOCKETS) - IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.fileDescriptor(); - if (connectionIdentifier == -1) - return 0; #endif + if (IPC::Connection::identifierIsNull(connectionIdentifier)) + return nullptr; RefPtr<PluginProcessConnection> pluginProcessConnection = PluginProcessConnection::create(this, pluginProcessToken, connectionIdentifier, supportsAsynchronousInitialization); m_pluginProcessConnections.append(pluginProcessConnection); { - MutexLocker locker(m_tokensAndConnectionsMutex); + LockHolder locker(m_tokensAndConnectionsMutex); ASSERT(!m_tokensAndConnections.contains(pluginProcessToken)); m_tokensAndConnections.set(pluginProcessToken, pluginProcessConnection->connection()); @@ -103,7 +101,7 @@ void PluginProcessConnectionManager::removePluginProcessConnection(PluginProcess ASSERT(vectorIndex != notFound); { - MutexLocker locker(m_tokensAndConnectionsMutex); + LockHolder locker(m_tokensAndConnectionsMutex); ASSERT(m_tokensAndConnections.contains(pluginProcessConnection->pluginProcessToken())); m_tokensAndConnections.remove(pluginProcessConnection->pluginProcessToken()); @@ -114,7 +112,7 @@ void PluginProcessConnectionManager::removePluginProcessConnection(PluginProcess void PluginProcessConnectionManager::pluginProcessCrashed(uint64_t pluginProcessToken) { - MutexLocker locker(m_tokensAndConnectionsMutex); + LockHolder locker(m_tokensAndConnectionsMutex); IPC::Connection* connection = m_tokensAndConnections.get(pluginProcessToken); // It's OK for connection to be null here; it will happen if this web process doesn't know diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h index fa2abb7e3..4f137b85d 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h @@ -44,7 +44,7 @@ class PluginProcessConnection; class PluginProcessConnectionManager : public IPC::Connection::WorkQueueMessageReceiver { public: - static PassRefPtr<PluginProcessConnectionManager> create(); + static Ref<PluginProcessConnectionManager> create(); ~PluginProcessConnectionManager(); void initializeConnection(IPC::Connection*); @@ -52,21 +52,19 @@ public: PluginProcessConnection* getPluginProcessConnection(uint64_t pluginProcessToken); void removePluginProcessConnection(PluginProcessConnection*); - void didReceivePluginProcessConnectionManagerMessageOnConnectionWorkQueue(IPC::Connection*, OwnPtr<IPC::MessageDecoder>&); - private: PluginProcessConnectionManager(); // IPC::Connection::WorkQueueMessageReceiver. - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; void pluginProcessCrashed(uint64_t pluginProcessToken); - RefPtr<WorkQueue> m_queue; + Ref<WorkQueue> m_queue; Vector<RefPtr<PluginProcessConnection>> m_pluginProcessConnections; - Mutex m_tokensAndConnectionsMutex; + Lock m_tokensAndConnectionsMutex; HashMap<uint64_t, RefPtr<IPC::Connection>> m_tokensAndConnections; }; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp index 0f7ec36a2..6b4ddfcc9 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp @@ -43,7 +43,6 @@ #include "WebProcess.h" #include "WebProcessConnectionMessages.h" #include <WebCore/GraphicsContext.h> -#include <WebCore/NotImplemented.h> #include <WebCore/SharedBuffer.h> using namespace WebCore; @@ -56,13 +55,14 @@ static uint64_t generatePluginInstanceID() return ++uniquePluginInstanceID; } -PassRefPtr<PluginProxy> PluginProxy::create(uint64_t pluginProcessToken, bool isRestartedProcess) +Ref<PluginProxy> PluginProxy::create(uint64_t pluginProcessToken, bool isRestartedProcess) { - return adoptRef(new PluginProxy(pluginProcessToken, isRestartedProcess)); + return adoptRef(*new PluginProxy(pluginProcessToken, isRestartedProcess)); } PluginProxy::PluginProxy(uint64_t pluginProcessToken, bool isRestartedProcess) - : m_pluginProcessToken(pluginProcessToken) + : Plugin(PluginProxyType) + , m_pluginProcessToken(pluginProcessToken) , m_pluginInstanceID(generatePluginInstanceID()) , m_pluginBackingStoreContainsValidData(false) , m_isStarted(false) @@ -86,7 +86,7 @@ void PluginProxy::pluginProcessCrashed() bool PluginProxy::initialize(const Parameters& parameters) { ASSERT(!m_connection); - m_connection = WebProcess::shared().pluginProcessConnectionManager().getPluginProcessConnection(m_pluginProcessToken); + m_connection = WebProcess::singleton().pluginProcessConnectionManager().getPluginProcessConnection(m_pluginProcessToken); if (!m_connection) return false; @@ -96,7 +96,7 @@ bool PluginProxy::initialize(const Parameters& parameters) m_connection->addPluginProxy(this); // Ask the plug-in process to create a plug-in. - m_pendingPluginCreationParameters = adoptPtr(new PluginCreationParameters); + m_pendingPluginCreationParameters = std::make_unique<PluginCreationParameters>(); m_pendingPluginCreationParameters->pluginInstanceID = m_pluginInstanceID; m_pendingPluginCreationParameters->windowNPObjectID = windowNPObjectID(); @@ -104,11 +104,9 @@ bool PluginProxy::initialize(const Parameters& parameters) m_pendingPluginCreationParameters->userAgent = controller()->userAgent(); m_pendingPluginCreationParameters->contentsScaleFactor = contentsScaleFactor(); m_pendingPluginCreationParameters->isPrivateBrowsingEnabled = controller()->isPrivateBrowsingEnabled(); + m_pendingPluginCreationParameters->isMuted = controller()->isMuted(); m_pendingPluginCreationParameters->artificialPluginInitializationDelayEnabled = controller()->artificialPluginInitializationDelayEnabled(); - -#if USE(ACCELERATED_COMPOSITING) m_pendingPluginCreationParameters->isAcceleratedCompositingEnabled = controller()->isAcceleratedCompositingEnabled(); -#endif if (!canInitializeAsynchronously()) return initializeSynchronously(); @@ -173,7 +171,7 @@ void PluginProxy::didCreatePluginInternal(bool wantsWheelEvents, uint32_t remote // Whether synchronously or asynchronously, this plug-in was created and we shouldn't need to remember // anything about how. - m_pendingPluginCreationParameters.clear(); + m_pendingPluginCreationParameters = nullptr; m_waitingOnAsynchronousInitialization = false; } @@ -187,7 +185,7 @@ void PluginProxy::didFailToCreatePluginInternal() // Whether synchronously or asynchronously, this plug-in failed to create and we shouldn't need to remember // anything about how. - m_pendingPluginCreationParameters.clear(); + m_pendingPluginCreationParameters = nullptr; m_waitingOnAsynchronousInitialization = false; } @@ -202,7 +200,7 @@ void PluginProxy::destroy() m_connection->removePluginProxy(this); } -void PluginProxy::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRect) +void PluginProxy::paint(GraphicsContext& graphicsContext, const IntRect& dirtyRect) { if (!needsBackingStore() || !m_backingStore) return; @@ -220,12 +218,11 @@ void PluginProxy::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRe m_pluginBackingStoreContainsValidData = true; } - m_backingStore->paint(*graphicsContext, contentsScaleFactor(), dirtyRect.location(), dirtyRect); + m_backingStore->paint(graphicsContext, contentsScaleFactor(), dirtyRect.location(), dirtyRect); if (m_waitingForPaintInResponseToUpdate) { m_waitingForPaintInResponseToUpdate = false; m_connection->connection()->send(Messages::PluginControllerProxy::DidUpdate(), m_pluginInstanceID); - return; } } @@ -241,16 +238,16 @@ bool PluginProxy::supportsSnapshotting() const return isSupported; } -PassRefPtr<ShareableBitmap> PluginProxy::snapshot() +RefPtr<ShareableBitmap> PluginProxy::snapshot() { ShareableBitmap::Handle snapshotStoreHandle; m_connection->connection()->sendSync(Messages::PluginControllerProxy::Snapshot(), Messages::PluginControllerProxy::Snapshot::Reply(snapshotStoreHandle), m_pluginInstanceID); if (snapshotStoreHandle.isNull()) - return 0; + return nullptr; RefPtr<ShareableBitmap> snapshotBuffer = ShareableBitmap::create(snapshotStoreHandle); - return snapshotBuffer.release(); + return snapshotBuffer; } bool PluginProxy::isTransparent() @@ -286,7 +283,7 @@ void PluginProxy::geometryDidChange() m_pluginBackingStoreContainsValidData = false; } - m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_pluginSize, m_clipRect, m_pluginToRootViewTransform, contentsScaleFactor(), pluginBackingStoreHandle), m_pluginInstanceID, IPC::DispatchMessageEvenWhenWaitingForSyncReply); + m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_pluginSize, m_clipRect, m_pluginToRootViewTransform, contentsScaleFactor(), pluginBackingStoreHandle), m_pluginInstanceID, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); } void PluginProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform) @@ -324,6 +321,11 @@ void PluginProxy::didEvaluateJavaScript(uint64_t requestID, const WTF::String& r m_connection->connection()->send(Messages::PluginControllerProxy::DidEvaluateJavaScript(requestID, result), m_pluginInstanceID); } +void PluginProxy::streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& responseURL, int responseStatus) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::StreamWillSendRequest(streamID, requestURL.string(), responseURL.string(), responseStatus), m_pluginInstanceID); +} + void PluginProxy::streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& /* suggestedFileName */) { m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveResponse(streamID, responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID); @@ -369,11 +371,8 @@ bool PluginProxy::handleMouseEvent(const WebMouseEvent& mouseEvent) if (m_waitingOnAsynchronousInitialization) return false; - bool handled = false; - if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseEvent(mouseEvent), Messages::PluginControllerProxy::HandleMouseEvent::Reply(handled), m_pluginInstanceID)) - return false; - - return handled; + m_connection->connection()->send(Messages::PluginControllerProxy::HandleMouseEvent(mouseEvent), m_pluginInstanceID); + return true; } bool PluginProxy::handleWheelEvent(const WebWheelEvent& wheelEvent) @@ -459,7 +458,7 @@ bool PluginProxy::isEditingCommandEnabled(const String& commandName) return enabled; } -bool PluginProxy::handlesPageScaleFactor() +bool PluginProxy::handlesPageScaleFactor() const { if (m_waitingOnAsynchronousInitialization) return false; @@ -471,6 +470,18 @@ bool PluginProxy::handlesPageScaleFactor() return handled; } +bool PluginProxy::requiresUnifiedScaleFactor() const +{ + if (m_waitingOnAsynchronousInitialization) + return false; + + bool required = false; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::RequiresUnifiedScaleFactor(), Messages::PluginControllerProxy::RequiresUnifiedScaleFactor::Reply(required), m_pluginInstanceID)) + return false; + + return required; +} + NPObject* PluginProxy::pluginScriptableNPObject() { // Sending the synchronous Messages::PluginControllerProxy::GetPluginScriptableNPObject message can cause us to dispatch an @@ -488,22 +499,21 @@ NPObject* PluginProxy::pluginScriptableNPObject() return m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginScriptableNPObjectID, this); } -#if PLATFORM(MAC) void PluginProxy::windowFocusChanged(bool hasFocus) { m_connection->connection()->send(Messages::PluginControllerProxy::WindowFocusChanged(hasFocus), m_pluginInstanceID); } -void PluginProxy::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) -{ - m_connection->connection()->send(Messages::PluginControllerProxy::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates), m_pluginInstanceID); -} - void PluginProxy::windowVisibilityChanged(bool isVisible) { m_connection->connection()->send(Messages::PluginControllerProxy::WindowVisibilityChanged(isVisible), m_pluginInstanceID); } +#if PLATFORM(COCOA) +void PluginProxy::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates), m_pluginInstanceID); +} uint64_t PluginProxy::pluginComplexTextInputIdentifier() const { return m_pluginInstanceID; @@ -530,6 +540,11 @@ void PluginProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled) m_connection->connection()->send(Messages::PluginControllerProxy::PrivateBrowsingStateChanged(isPrivateBrowsingEnabled), m_pluginInstanceID); } +void PluginProxy::mutedStateChanged(bool isMuted) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::MutedStateChanged(isMuted), m_pluginInstanceID); +} + bool PluginProxy::getFormValue(String& formValue) { bool returnValue; @@ -591,18 +606,15 @@ bool PluginProxy::updateBackingStore() IntSize backingStoreSize = m_pluginSize; backingStoreSize.scale(contentsScaleFactor()); - - if (!m_backingStore) { - m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha); - return true; - } - if (backingStoreSize != m_backingStore->size()) { - // The backing store already exists, just resize it. - return m_backingStore->resize(backingStoreSize); + if (m_backingStore) { + if (m_backingStore->size() == backingStoreSize) + return false; + m_backingStore = nullptr; // Give malloc a chance to recycle our backing store. } - return false; + m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha); + return !!m_backingStore; } uint64_t PluginProxy::windowNPObjectID() @@ -658,6 +670,16 @@ void PluginProxy::evaluate(const NPVariantData& npObjectAsVariantData, const Str releaseNPVariantValue(&npObjectAsVariant); } +void PluginProxy::setPluginIsPlayingAudio(bool pluginIsPlayingAudio) +{ + controller()->setPluginIsPlayingAudio(pluginIsPlayingAudio); +} + +void PluginProxy::continueStreamLoad(uint64_t streamID) +{ + controller()->continueStreamLoad(streamID); +} + void PluginProxy::cancelStreamLoad(uint64_t streamID) { controller()->cancelStreamLoad(streamID); @@ -713,9 +735,9 @@ IntPoint PluginProxy::convertToRootView(const IntPoint& point) const return m_pluginToRootViewTransform.mapPoint(point); } -PassRefPtr<WebCore::SharedBuffer> PluginProxy::liveResourceData() const +RefPtr<WebCore::SharedBuffer> PluginProxy::liveResourceData() const { - return 0; + return nullptr; } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h index 0bc30cb03..031619355 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +35,9 @@ #include <WebCore/FindOptions.h> #include <WebCore/IntRect.h> #include <WebCore/SecurityOrigin.h> +#include <memory> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include <wtf/RetainPtr.h> OBJC_CLASS CALayer; #endif @@ -56,88 +57,95 @@ struct PluginCreationParameters; class PluginProxy : public Plugin { public: - static PassRefPtr<PluginProxy> create(uint64_t pluginProcessToken, bool isRestartedProcess); + static Ref<PluginProxy> create(uint64_t pluginProcessToken, bool isRestartedProcess); ~PluginProxy(); uint64_t pluginInstanceID() const { return m_pluginInstanceID; } void pluginProcessCrashed(); - void didReceivePluginProxyMessage(IPC::Connection*, IPC::MessageDecoder&); - void didReceiveSyncPluginProxyMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + void didReceivePluginProxyMessage(IPC::Connection&, IPC::Decoder&); + void didReceiveSyncPluginProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); - bool isBeingAsynchronouslyInitialized() const { return m_waitingOnAsynchronousInitialization; } + bool isBeingAsynchronouslyInitialized() const override { return m_waitingOnAsynchronousInitialization; } private: explicit PluginProxy(uint64_t pluginProcessToken, bool isRestartedProcess); // Plugin - virtual bool initialize(const Parameters&); + bool initialize(const Parameters&) override; bool initializeSynchronously(); - virtual void destroy(); - virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); - virtual bool supportsSnapshotting() const; - virtual PassRefPtr<ShareableBitmap> snapshot(); -#if PLATFORM(MAC) - virtual PlatformLayer* pluginLayer(); + void destroy() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override; + bool supportsSnapshotting() const override; + RefPtr<ShareableBitmap> snapshot() override; +#if PLATFORM(COCOA) + PlatformLayer* pluginLayer() override; #endif - virtual bool isTransparent(); - virtual bool wantsWheelEvents() override; - virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform); - virtual void visibilityDidChange(bool isVisible); - virtual void frameDidFinishLoading(uint64_t requestID); - virtual void frameDidFail(uint64_t requestID, bool wasCancelled); - virtual void didEvaluateJavaScript(uint64_t requestID, const String& result); - virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName); - virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length); - virtual void streamDidFinishLoading(uint64_t streamID); - virtual void streamDidFail(uint64_t streamID, bool wasCancelled); - virtual void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& suggestedFileName); - virtual void manualStreamDidReceiveData(const char* bytes, int length); - virtual void manualStreamDidFinishLoading(); - virtual void manualStreamDidFail(bool wasCancelled); + bool isTransparent() override; + bool wantsWheelEvents() override; + void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override; + void visibilityDidChange(bool isVisible) override; + void frameDidFinishLoading(uint64_t requestID) override; + void frameDidFail(uint64_t requestID, bool wasCancelled) override; + void didEvaluateJavaScript(uint64_t requestID, const String& result) override; + void streamWillSendRequest(uint64_t streamID, const WebCore::URL& requestURL, const WebCore::URL& responseURL, int responseStatus) override; + void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override; + void streamDidFinishLoading(uint64_t streamID) override; + void streamDidFail(uint64_t streamID, bool wasCancelled) override; + void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& suggestedFileName) override; + void manualStreamDidReceiveData(const char* bytes, int length) override; + void manualStreamDidFinishLoading() override; + void manualStreamDidFail(bool wasCancelled) override; - virtual bool handleMouseEvent(const WebMouseEvent&); - virtual bool handleWheelEvent(const WebWheelEvent&); - virtual bool handleMouseEnterEvent(const WebMouseEvent&); - virtual bool handleMouseLeaveEvent(const WebMouseEvent&); - virtual bool handleContextMenuEvent(const WebMouseEvent&); - virtual bool handleKeyboardEvent(const WebKeyboardEvent&); - virtual void setFocus(bool); - virtual bool handleEditingCommand(const String& commandName, const String& argument) override; - virtual bool isEditingCommandEnabled(const String& commandName) override; - virtual bool shouldAllowScripting() override { return true; } - virtual bool shouldAllowNavigationFromDrags() override { return false; } + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override; + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleContextMenuEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override; + void setFocus(bool) override; + bool handleEditingCommand(const String& commandName, const String& argument) override; + bool isEditingCommandEnabled(const String& commandName) override; + bool shouldAllowScripting() override { return true; } + bool shouldAllowNavigationFromDrags() override { return false; } - virtual bool handlesPageScaleFactor(); + bool handlesPageScaleFactor() const override; + bool requiresUnifiedScaleFactor() const override; - virtual NPObject* pluginScriptableNPObject(); -#if PLATFORM(MAC) - virtual void windowFocusChanged(bool); - virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); - virtual void windowVisibilityChanged(bool); - virtual uint64_t pluginComplexTextInputIdentifier() const; - virtual void sendComplexTextInput(const String& textInput); - virtual void setLayerHostingMode(LayerHostingMode) override; + NPObject* pluginScriptableNPObject() override; + + void windowFocusChanged(bool) override; + void windowVisibilityChanged(bool) override; + +#if PLATFORM(COCOA) + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override; + uint64_t pluginComplexTextInputIdentifier() const override; + void sendComplexTextInput(const String& textInput) override; + void setLayerHostingMode(LayerHostingMode) override; #endif - virtual void contentsScaleFactorChanged(float); - virtual void storageBlockingStateChanged(bool); - virtual void privateBrowsingStateChanged(bool); - virtual bool getFormValue(String& formValue); - virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); - virtual WebCore::Scrollbar* horizontalScrollbar(); - virtual WebCore::Scrollbar* verticalScrollbar(); + void contentsScaleFactorChanged(float) override; + void storageBlockingStateChanged(bool) override; + void privateBrowsingStateChanged(bool) override; + void mutedStateChanged(bool) override; + bool getFormValue(String& formValue) override; + bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override; + WebCore::Scrollbar* horizontalScrollbar() override; + WebCore::Scrollbar* verticalScrollbar() override; - virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned) override { return 0; } - virtual bool findString(const String&, WebCore::FindOptions, unsigned) override { return false; } + unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned) override { return 0; } + bool findString(const String&, WebCore::FindOptions, unsigned) override { return false; } - virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override; + WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override; - virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const override; - virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; } + RefPtr<WebCore::SharedBuffer> liveResourceData() const override; + bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; } - virtual String getSelectionString() const override { return String(); } + String getSelectionString() const override { return String(); } + String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override { return String(); } + bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override { return false; } float contentsScaleFactor(); bool needsBackingStore() const; @@ -156,10 +164,12 @@ private: void getAuthenticationInfo(const WebCore::ProtectionSpace&, bool& returnValue, String& username, String& password); void getPluginElementNPObject(uint64_t& pluginElementNPObjectID); void evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, bool& returnValue, NPVariantData& resultData); + void setPluginIsPlayingAudio(bool); + void continueStreamLoad(uint64_t streamID); void cancelStreamLoad(uint64_t streamID); void cancelManualStreamLoad(); void setStatusbarText(const String& statusbarText); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void pluginFocusOrWindowFocusChanged(bool); void setComplexTextInputState(uint64_t); void setLayerHostingContextID(uint32_t); @@ -212,10 +222,10 @@ private: // The client ID for the CA layer in the plug-in process. Will be 0 if the plug-in is not a CA plug-in. uint32_t m_remoteLayerClientID; - OwnPtr<PluginCreationParameters> m_pendingPluginCreationParameters; + std::unique_ptr<PluginCreationParameters> m_pendingPluginCreationParameters; bool m_waitingOnAsynchronousInitialization; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) RetainPtr<CALayer> m_pluginLayer; #endif @@ -224,6 +234,8 @@ private: } // namespace WebKit +SPECIALIZE_TYPE_TRAITS_PLUGIN(PluginProxy, PluginProxyType) + #endif // ENABLE(NETSCAPE_PLUGIN_API) #endif // PluginProxy_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in index 07ea1d4e3..bee843d8d 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in @@ -50,13 +50,16 @@ messages -> PluginProxy LegacyReceiver { # Cancels the given stream load. CancelStreamLoad(uint64_t streamID) + # Continues the given stream load. + ContinueStreamLoad(uint64_t streamID) + # Cancel the manual stream load. CancelManualStreamLoad() # Set the status bar text. SetStatusbarText(String statusbarText) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) # Called when the plug-in's focus or its containing window focus changes. PluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) @@ -83,6 +86,9 @@ messages -> PluginProxy LegacyReceiver { # Tells the WebProcess that the plug-in failed to initialize. DidFailToCreatePlugin() -> () + + # Tells the WebProcess that the plug-in has started or stopped playing audio. + SetPluginIsPlayingAudio(bool pluginIsPlayingAudio) } #endif diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp index 00cb367f5..6efd32ce9 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2012, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +31,7 @@ #include "ShareableBitmap.h" #include "WebCoreArgumentCoders.h" #include "WebEvent.h" +#include "WebLoaderStrategy.h" #include "WebPage.h" #include "WebPageProxyMessages.h" #include "WebProcess.h" @@ -41,6 +42,7 @@ #include <WebCore/CredentialStorage.h> #include <WebCore/DocumentLoader.h> #include <WebCore/EventHandler.h> +#include <WebCore/EventNames.h> #include <WebCore/FocusController.h> #include <WebCore/FrameLoadRequest.h> #include <WebCore/FrameLoader.h> @@ -49,6 +51,7 @@ #include <WebCore/GraphicsContext.h> #include <WebCore/HTMLPlugInElement.h> #include <WebCore/HTMLPlugInImageElement.h> +#include <WebCore/HTTPHeaderNames.h> #include <WebCore/HostWindow.h> #include <WebCore/MIMETypeRegistry.h> #include <WebCore/MainFrame.h> @@ -56,12 +59,10 @@ #include <WebCore/NetscapePlugInStreamLoader.h> #include <WebCore/NetworkingContext.h> #include <WebCore/Page.h> -#include <WebCore/PageThrottler.h> #include <WebCore/PlatformMouseEvent.h> #include <WebCore/ProtectionSpace.h> #include <WebCore/ProxyServer.h> #include <WebCore/RenderEmbeddedObject.h> -#include <WebCore/ResourceLoadScheduler.h> #include <WebCore/ScriptController.h> #include <WebCore/ScrollView.h> #include <WebCore/SecurityOrigin.h> @@ -71,19 +72,23 @@ #include <bindings/ScriptValue.h> #include <wtf/text/StringBuilder.h> +#if PLUGIN_ARCHITECTURE(X11) +#include <WebCore/PlatformDisplay.h> +#endif + using namespace JSC; using namespace WebCore; namespace WebKit { // This simulated mouse click delay in HTMLPlugInImageElement.cpp should generally be the same or shorter than this delay. -static const double pluginSnapshotTimerDelay = 1.1; +static const auto pluginSnapshotTimerDelay = std::chrono::milliseconds { 1100 }; class PluginView::URLRequest : public RefCounted<URLRequest> { public: - static PassRefPtr<PluginView::URLRequest> create(uint64_t requestID, const FrameLoadRequest& request, bool allowPopups) + static Ref<PluginView::URLRequest> create(uint64_t requestID, const FrameLoadRequest& request, bool allowPopups) { - return adoptRef(new URLRequest(requestID, request, allowPopups)); + return adoptRef(*new URLRequest(requestID, request, allowPopups)); } uint64_t requestID() const { return m_requestID; } @@ -106,14 +111,15 @@ private: class PluginView::Stream : public RefCounted<PluginView::Stream>, NetscapePlugInStreamLoaderClient { public: - static PassRefPtr<Stream> create(PluginView* pluginView, uint64_t streamID, const ResourceRequest& request) + static Ref<Stream> create(PluginView* pluginView, uint64_t streamID, const ResourceRequest& request) { - return adoptRef(new Stream(pluginView, streamID, request)); + return adoptRef(*new Stream(pluginView, streamID, request)); } ~Stream(); void start(); void cancel(); + void continueLoad(); uint64_t streamID() const { return m_streamID; } @@ -127,15 +133,17 @@ private: } // NetscapePluginStreamLoaderClient - virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&); - virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int); - virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&); - virtual void didFinishLoading(NetscapePlugInStreamLoader*); + void willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&&, const ResourceResponse& redirectResponse, std::function<void (ResourceRequest&&)>&&) override; + void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&) override; + void didReceiveData(NetscapePlugInStreamLoader*, const char*, int) override; + void didFail(NetscapePlugInStreamLoader*, const ResourceError&) override; + void didFinishLoading(NetscapePlugInStreamLoader*) override; PluginView* m_pluginView; uint64_t m_streamID; - const ResourceRequest m_request; - + ResourceRequest m_request; + std::function<void (ResourceRequest)> m_loadCallback; + // True if the stream was explicitly cancelled by calling cancel(). // (As opposed to being cancelled by the user hitting the stop button for example. bool m_streamWasCancelled; @@ -156,7 +164,7 @@ void PluginView::Stream::start() Frame* frame = m_pluginView->m_pluginElement->document().frame(); ASSERT(frame); - m_loader = resourceLoadScheduler()->schedulePluginStreamLoad(frame, this, m_request); + m_loader = WebProcess::singleton().webLoaderStrategy().schedulePluginStreamLoad(*frame, *this, m_request); } void PluginView::Stream::cancel() @@ -165,7 +173,15 @@ void PluginView::Stream::cancel() m_streamWasCancelled = true; m_loader->cancel(m_loader->cancelledError()); - m_loader = 0; + m_loader = nullptr; +} + +void PluginView::Stream::continueLoad() +{ + ASSERT(m_pluginView->m_plugin); + ASSERT(m_loadCallback); + + m_loadCallback(m_request); } static String buildHTTPHeaders(const ResourceResponse& response, long long& expectedContentLength) @@ -173,40 +189,46 @@ static String buildHTTPHeaders(const ResourceResponse& response, long long& expe if (!response.isHTTP()) return String(); - StringBuilder stringBuilder; - - String statusLine = String::format("HTTP %d ", response.httpStatusCode()); - stringBuilder.append(statusLine); - stringBuilder.append(response.httpStatusText()); - stringBuilder.append('\n'); - - HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end(); - for (HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin(); it != end; ++it) { - stringBuilder.append(it->key); - stringBuilder.appendLiteral(": "); - stringBuilder.append(it->value); - stringBuilder.append('\n'); + StringBuilder header; + header.appendLiteral("HTTP "); + header.appendNumber(response.httpStatusCode()); + header.append(' '); + header.append(response.httpStatusText()); + header.append('\n'); + for (auto& field : response.httpHeaderFields()) { + header.append(field.key); + header.appendLiteral(": "); + header.append(field.value); + header.append('\n'); } - - String headers = stringBuilder.toString(); - + // If the content is encoded (most likely compressed), then don't send its length to the plugin, // which is only interested in the decoded length, not yet known at the moment. // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic. - String contentEncoding = response.httpHeaderField("Content-Encoding"); + String contentEncoding = response.httpHeaderField(HTTPHeaderName::ContentEncoding); if (!contentEncoding.isNull() && contentEncoding != "identity") expectedContentLength = -1; - return headers; + return header.toString(); } -static uint32_t lastModifiedDate(const ResourceResponse& response) +static uint32_t lastModifiedDateMS(const ResourceResponse& response) { - double lastModified = response.lastModified(); - if (!std::isfinite(lastModified)) + auto lastModified = response.lastModified(); + if (!lastModified) return 0; - return lastModified * 1000; + return std::chrono::duration_cast<std::chrono::milliseconds>(lastModified.value().time_since_epoch()).count(); +} + +void PluginView::Stream::willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&& request, const ResourceResponse& redirectResponse, std::function<void (ResourceRequest&&)>&& decisionHandler) +{ + const URL& requestURL = request.url(); + const URL& redirectResponseURL = redirectResponse.url(); + + m_loadCallback = decisionHandler; + m_request = request; + m_pluginView->m_plugin->streamWillSendRequest(m_streamID, requestURL, redirectResponseURL, redirectResponse.httpStatusCode()); } void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse& response) @@ -222,7 +244,7 @@ void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const R if (expectedContentLength > 0) streamLength = expectedContentLength; - m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, lastModifiedDate(response), mimeType, headers, response.suggestedFilename()); + m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, lastModifiedDateMS(response), mimeType, headers, response.suggestedFilename()); } void PluginView::Stream::didReceiveData(NetscapePlugInStreamLoader*, const char* bytes, int length) @@ -263,38 +285,26 @@ static inline WebPage* webPage(HTMLPlugInElement* pluginElement) Frame* frame = pluginElement->document().frame(); ASSERT(frame); - WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client()); - WebPage* webPage = webFrameLoaderClient ? webFrameLoaderClient->webFrame()->page() : 0; - ASSERT(webPage); + WebFrame* webFrame = WebFrame::fromCoreFrame(*frame); + if (!webFrame) + return nullptr; - return webPage; + return webFrame->page(); } -PassRefPtr<PluginView> PluginView::create(PassRefPtr<HTMLPlugInElement> pluginElement, PassRefPtr<Plugin> plugin, const Plugin::Parameters& parameters) +Ref<PluginView> PluginView::create(HTMLPlugInElement& pluginElement, Ref<Plugin>&& plugin, const Plugin::Parameters& parameters) { - return adoptRef(new PluginView(pluginElement, plugin, parameters)); + return adoptRef(*new PluginView(pluginElement, WTFMove(plugin), parameters)); } -PluginView::PluginView(PassRefPtr<HTMLPlugInElement> pluginElement, PassRefPtr<Plugin> plugin, const Plugin::Parameters& parameters) +PluginView::PluginView(HTMLPlugInElement& pluginElement, Ref<Plugin>&& plugin, const Plugin::Parameters& parameters) : PluginViewBase(0) - , m_pluginElement(pluginElement) - , m_plugin(plugin) + , m_pluginElement(&pluginElement) + , m_plugin(WTFMove(plugin)) , m_webPage(webPage(m_pluginElement.get())) , m_parameters(parameters) - , m_isInitialized(false) - , m_isWaitingForSynchronousInitialization(false) - , m_isWaitingUntilMediaCanStart(false) - , m_isBeingDestroyed(false) - , m_pluginProcessHasCrashed(false) , m_pendingURLRequestsTimer(RunLoop::main(), this, &PluginView::pendingURLRequestsTimerFired) -#if ENABLE(NETSCAPE_PLUGIN_API) - , m_npRuntimeObjectMap(this) -#endif - , m_manualStreamState(StreamStateInitial) - , m_pluginSnapshotTimer(this, &PluginView::pluginSnapshotTimerFired, pluginSnapshotTimerDelay) - , m_countSnapshotRetries(0) - , m_didReceiveUserInteraction(false) - , m_pageScaleFactor(1) + , m_pluginSnapshotTimer(*this, &PluginView::pluginSnapshotTimerFired, pluginSnapshotTimerDelay) { m_webPage->addPluginView(this); } @@ -309,6 +319,8 @@ PluginView::~PluginView() if (m_isWaitingUntilMediaCanStart) m_pluginElement->document().removeMediaCanStartListener(this); + m_pluginElement->document().removeAudioProducer(this); + destroyPluginAndReset(); // Null out the plug-in element explicitly so we'll crash earlier if we try to use @@ -330,7 +342,7 @@ void PluginView::destroyPluginAndReset() m_pendingURLRequests.clear(); m_pendingURLRequestsTimer.stop(); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (m_webPage) pluginFocusOrWindowFocusChanged(false); #endif @@ -344,7 +356,7 @@ void PluginView::destroyPluginAndReset() cancelAllStreams(); } -void PluginView::recreateAndInitialize(PassRefPtr<Plugin> plugin) +void PluginView::recreateAndInitialize(Ref<Plugin>&& plugin) { if (m_plugin) { if (m_pluginSnapshotTimer.isActive()) @@ -352,13 +364,12 @@ void PluginView::recreateAndInitialize(PassRefPtr<Plugin> plugin) destroyPluginAndReset(); } - // Reset member variables to initial values. - m_plugin = plugin; + m_plugin = WTFMove(plugin); m_isInitialized = false; m_isWaitingForSynchronousInitialization = false; m_isWaitingUntilMediaCanStart = false; m_isBeingDestroyed = false; - m_manualStreamState = StreamStateInitial; + m_manualStreamState = ManualStreamState::Initial; m_transientPaintingSnapshot = nullptr; initializePlugin(); @@ -366,7 +377,7 @@ void PluginView::recreateAndInitialize(PassRefPtr<Plugin> plugin) void PluginView::setLayerHostingMode(LayerHostingMode layerHostingMode) { -#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) +#if HAVE(OUT_OF_PROCESS_LAYER_HOSTING) if (!m_plugin) return; @@ -391,8 +402,8 @@ void PluginView::manualLoadDidReceiveResponse(const ResourceResponse& response) return; if (!m_isInitialized) { - ASSERT(m_manualStreamState == StreamStateInitial); - m_manualStreamState = StreamStateHasReceivedResponse; + ASSERT(m_manualStreamState == ManualStreamState::Initial); + m_manualStreamState = ManualStreamState::HasReceivedResponse; m_manualStreamResponse = response; return; } @@ -408,7 +419,7 @@ void PluginView::manualLoadDidReceiveResponse(const ResourceResponse& response) if (expectedContentLength > 0) streamLength = expectedContentLength; - m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, lastModifiedDate(response), mimeType, headers, response.suggestedFilename()); + m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, lastModifiedDateMS(response), mimeType, headers, response.suggestedFilename()); } void PluginView::manualLoadDidReceiveData(const char* bytes, int length) @@ -418,7 +429,7 @@ void PluginView::manualLoadDidReceiveData(const char* bytes, int length) return; if (!m_isInitialized) { - ASSERT(m_manualStreamState == StreamStateHasReceivedResponse); + ASSERT(m_manualStreamState == ManualStreamState::HasReceivedResponse); if (!m_manualStreamData) m_manualStreamData = SharedBuffer::create(); @@ -436,8 +447,8 @@ void PluginView::manualLoadDidFinishLoading() return; if (!m_isInitialized) { - ASSERT(m_manualStreamState == StreamStateHasReceivedResponse); - m_manualStreamState = StreamStateFinished; + ASSERT(m_manualStreamState == ManualStreamState::HasReceivedResponse); + m_manualStreamState = ManualStreamState::Finished; return; } @@ -451,7 +462,7 @@ void PluginView::manualLoadDidFail(const ResourceError& error) return; if (!m_isInitialized) { - m_manualStreamState = StreamStateFinished; + m_manualStreamState = ManualStreamState::Finished; m_manualStreamError = error; m_manualStreamData = nullptr; return; @@ -460,12 +471,12 @@ void PluginView::manualLoadDidFail(const ResourceError& error) m_plugin->manualStreamDidFail(error.isCancellation()); } -RenderBoxModelObject* PluginView::renderer() const +void PluginView::pageScaleFactorDidChange() { - return toRenderBoxModelObject(m_pluginElement->renderer()); + viewGeometryDidChange(); } -void PluginView::pageScaleFactorDidChange() +void PluginView::topContentInsetDidChange() { viewGeometryDidChange(); } @@ -473,8 +484,8 @@ void PluginView::pageScaleFactorDidChange() void PluginView::setPageScaleFactor(double scaleFactor, IntPoint) { m_pageScaleFactor = scaleFactor; - m_webPage->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor)); - m_webPage->send(Messages::WebPageProxy::PageZoomFactorDidChange(scaleFactor)); + m_webPage->send(Messages::WebPageProxy::PluginScaleFactorDidChange(scaleFactor)); + m_webPage->send(Messages::WebPageProxy::PluginZoomFactorDidChange(scaleFactor)); pageScaleFactorDidChange(); } @@ -491,30 +502,31 @@ bool PluginView::handlesPageScaleFactor() const return m_plugin->handlesPageScaleFactor(); } -void PluginView::webPageDestroyed() +bool PluginView::requiresUnifiedScaleFactor() const { - m_webPage = 0; + if (!m_plugin || !m_isInitialized) + return false; + + return m_plugin->requiresUnifiedScaleFactor(); } -void PluginView::viewStateDidChange(ViewState::Flags changed) +void PluginView::webPageDestroyed() { -#if PLATFORM(MAC) - platformViewStateDidChange(changed); -#endif + m_webPage = 0; } -#if PLATFORM(MAC) -void PluginView::platformViewStateDidChange(ViewState::Flags changed) +void PluginView::activityStateDidChange(ActivityState::Flags changed) { if (!m_plugin || !m_isInitialized) return; - if (changed & ViewState::IsVisible) - m_plugin->windowVisibilityChanged(m_webPage->isVisible()); - if (changed & ViewState::WindowIsActive) + if (changed & ActivityState::IsVisibleOrOccluded) + m_plugin->windowVisibilityChanged(m_webPage->isVisibleOrOccluded()); + if (changed & ActivityState::WindowIsActive) m_plugin->windowFocusChanged(m_webPage->windowIsFocused()); } +#if PLATFORM(COCOA) void PluginView::setDeviceScaleFactor(float scaleFactor) { if (!m_isInitialized || !m_plugin) @@ -542,7 +554,7 @@ bool PluginView::sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, m_plugin->sendComplexTextInput(textInput); return true; } - + NSObject *PluginView::accessibilityObject() const { if (!m_isInitialized || !m_plugin) @@ -577,6 +589,12 @@ void PluginView::initializePlugin() } } + m_pluginElement->document().addAudioProducer(this); + +#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) + HTMLPlugInImageElement& plugInImageElement = downcast<HTMLPlugInImageElement>(*m_pluginElement); + m_didPlugInStartOffScreen = !m_webPage->plugInIntersectsSearchRect(plugInImageElement); +#endif m_plugin->initialize(this, m_parameters); // Plug-in initialization continued in didFailToInitializePlugin() or didInitializePlugin(). @@ -584,7 +602,7 @@ void PluginView::initializePlugin() void PluginView::didFailToInitializePlugin() { - m_plugin = 0; + m_plugin = nullptr; #if ENABLE(NETSCAPE_PLUGIN_API) String frameURLString = frame()->loader().documentLoader()->responseURL().string(); @@ -597,7 +615,7 @@ void PluginView::didInitializePlugin() { m_isInitialized = true; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) windowAndViewFramesChanged(m_webPage->windowFrameInScreenCoordinates(), m_webPage->viewFrameInWindowCoordinates()); #endif @@ -609,27 +627,28 @@ void PluginView::didInitializePlugin() redeliverManualStream(); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (m_pluginElement->displayState() < HTMLPlugInElement::Restarting) { if (m_plugin->pluginLayer() && frame()) { frame()->view()->enterCompositingMode(); - m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange); + m_pluginElement->invalidateStyleAndLayerComposition(); } if (frame() && !frame()->settings().maximumPlugInSnapshotAttempts()) { - m_pluginElement->setDisplayState(HTMLPlugInElement::DisplayingSnapshot); + beginSnapshottingRunningPlugin(); return; } m_pluginSnapshotTimer.restart(); } else { if (m_plugin->pluginLayer() && frame()) { frame()->view()->enterCompositingMode(); - m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange); + m_pluginElement->invalidateStyleAndLayerComposition(); } if (m_pluginElement->displayState() == HTMLPlugInElement::RestartingWithPendingMouseClick) m_pluginElement->dispatchPendingMouseClick(); } - m_plugin->windowVisibilityChanged(m_webPage->isVisible()); + m_plugin->visibilityDidChange(isVisible()); + m_plugin->windowVisibilityChanged(m_webPage->isVisibleOrOccluded()); m_plugin->windowFocusChanged(m_webPage->windowIsFocused()); #endif @@ -639,9 +658,15 @@ void PluginView::didInitializePlugin() frameView->setNeedsLayout(); } } + + if (Frame* frame = m_pluginElement->document().frame()) { + auto* webFrame = WebFrame::fromCoreFrame(*frame); + if (webFrame->isMainFrame()) + webFrame->page()->send(Messages::WebPageProxy::MainFramePluginHandlesPageScaleGestureDidChange(handlesPageScaleFactor())); + } } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) PlatformLayer* PluginView::platformLayer() const { // The plug-in can be null here if it failed to initialize. @@ -685,7 +710,7 @@ void PluginView::storageBlockingStateChanged() if (!m_isInitialized || !m_plugin) return; - bool storageBlockingPolicy = !frame()->document()->securityOrigin()->canAccessPluginStorage(frame()->document()->topOrigin()); + bool storageBlockingPolicy = !frame()->document()->securityOrigin().canAccessPluginStorage(frame()->document()->topOrigin()); m_plugin->storageBlockingStateChanged(storageBlockingPolicy); } @@ -750,13 +775,13 @@ void PluginView::setFrameRect(const WebCore::IntRect& rect) viewGeometryDidChange(); } -void PluginView::paint(GraphicsContext* context, const IntRect& /*dirtyRect*/) +void PluginView::paint(GraphicsContext& context, const IntRect& /*dirtyRect*/, Widget::SecurityOriginPaintPolicy) { if (!m_plugin || !m_isInitialized || m_pluginElement->displayState() < HTMLPlugInElement::Restarting) return; - if (context->paintingDisabled()) { - if (context->updatingControlTints()) + if (context.paintingDisabled()) { + if (context.updatingControlTints()) m_plugin->updateControlTints(context); return; } @@ -768,14 +793,14 @@ void PluginView::paint(GraphicsContext* context, const IntRect& /*dirtyRect*/) return; if (m_transientPaintingSnapshot) { - m_transientPaintingSnapshot->paint(*context, contentsScaleFactor(), frameRect().location(), m_transientPaintingSnapshot->bounds()); + m_transientPaintingSnapshot->paint(context, contentsScaleFactor(), frameRect().location(), m_transientPaintingSnapshot->bounds()); return; } - GraphicsContextStateSaver stateSaver(*context); + GraphicsContextStateSaver stateSaver(context); // Translate the coordinate system so that the origin is in the top-left corner of the plug-in. - context->translate(frameRect().location().x(), frameRect().location().y()); + context.translate(frameRect().location().x(), frameRect().location().y()); m_plugin->paint(context, paintRect); } @@ -823,7 +848,7 @@ String PluginView::getSelectionString() const return m_plugin->getSelectionString(); } -OwnPtr<WebEvent> PluginView::createWebEvent(MouseEvent* event) const +std::unique_ptr<WebEvent> PluginView::createWebEvent(MouseEvent* event) const { WebEvent::Type type = WebEvent::NoType; unsigned clickCount = 1; @@ -865,7 +890,7 @@ OwnPtr<WebEvent> PluginView::createWebEvent(MouseEvent* event) const if (event->metaKey()) modifiers |= WebEvent::MetaKey; - return adoptPtr(new WebMouseEvent(type, button, m_plugin->convertToRootView(IntPoint(event->offsetX(), event->offsetY())), event->screenLocation(), 0, 0, 0, clickCount, static_cast<WebEvent::Modifiers>(modifiers), 0)); + return std::make_unique<WebMouseEvent>(type, button, m_plugin->convertToRootView(IntPoint(event->offsetX(), event->offsetY())), event->screenLocation(), 0, 0, 0, clickCount, static_cast<WebEvent::Modifiers>(modifiers), 0, 0); } void PluginView::handleEvent(Event* event) @@ -874,9 +899,9 @@ void PluginView::handleEvent(Event* event) return; const WebEvent* currentEvent = WebPage::currentEvent(); - OwnPtr<WebEvent> simulatedWebEvent; - if (event->isMouseEvent() && toMouseEvent(event)->isSimulated()) { - simulatedWebEvent = createWebEvent(toMouseEvent(event)); + std::unique_ptr<WebEvent> simulatedWebEvent; + if (is<MouseEvent>(*event) && downcast<MouseEvent>(*event).isSimulated()) { + simulatedWebEvent = createWebEvent(downcast<MouseEvent>(event)); currentEvent = simulatedWebEvent.get(); } if (!currentEvent) @@ -897,7 +922,7 @@ void PluginView::handleEvent(Event* event) didHandleEvent = m_plugin->handleMouseEvent(static_cast<const WebMouseEvent&>(*currentEvent)); if (event->type() != eventNames().mousemoveEvent) pluginDidReceiveUserInteraction(); - } else if ((event->type() == eventNames().wheelEvent || event->type() == eventNames().mousewheelEvent) + } else if (eventNames().isWheelEventType(event->type()) && currentEvent->type() == WebEvent::Wheel && m_plugin->wantsWheelEvents()) { didHandleEvent = m_plugin->handleWheelEvent(static_cast<const WebWheelEvent&>(*currentEvent)); pluginDidReceiveUserInteraction(); @@ -955,7 +980,15 @@ bool PluginView::shouldNotAddLayer() const return m_pluginElement->displayState() < HTMLPlugInElement::Restarting && !m_plugin->supportsSnapshotting(); } -PassRefPtr<SharedBuffer> PluginView::liveResourceData() const +void PluginView::willDetatchRenderer() +{ + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->willDetatchRenderer(); +} + +RefPtr<SharedBuffer> PluginView::liveResourceData() const { if (!m_isInitialized || !m_plugin) return 0; @@ -971,6 +1004,22 @@ bool PluginView::performDictionaryLookupAtLocation(const WebCore::FloatPoint& po return m_plugin->performDictionaryLookupAtLocation(point); } +String PluginView::getSelectionForWordAtPoint(const WebCore::FloatPoint& point) const +{ + if (!m_isInitialized || !m_plugin) + return String(); + + return m_plugin->getSelectionForWordAtPoint(point); +} + +bool PluginView::existingSelectionContainsPoint(const WebCore::FloatPoint& point) const +{ + if (!m_isInitialized || !m_plugin) + return false; + + return m_plugin->existingSelectionContainsPoint(point); +} + void PluginView::notifyWidget(WidgetNotification notification) { switch (notification) { @@ -1083,9 +1132,9 @@ void PluginView::focusPluginElement() ASSERT(frame()); if (Page* page = frame()->page()) - page->focusController().setFocusedElement(m_pluginElement.get(), frame()); + page->focusController().setFocusedElement(m_pluginElement.get(), *frame()); else - frame()->document()->setFocusedElement(m_pluginElement); + frame()->document()->setFocusedElement(m_pluginElement.get()); } void PluginView::pendingURLRequestsTimerFired() @@ -1131,19 +1180,19 @@ void PluginView::performFrameLoadURLRequest(URLRequest* request) if (!frame) return; - if (!m_pluginElement->document().securityOrigin()->canDisplay(request->request().url())) { + if (!m_pluginElement->document().securityOrigin().canDisplay(request->request().url())) { // We can't load the request, send back a reply to the plug-in. m_plugin->frameDidFail(request->requestID(), false); return; } - UserGestureIndicator gestureIndicator(request->allowPopups() ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture); + UserGestureIndicator gestureIndicator(request->allowPopups() ? std::optional<ProcessingUserGestureState>(ProcessingUserGesture) : std::nullopt); // First, try to find a target frame. Frame* targetFrame = frame->loader().findFrameForNavigation(request->target()); if (!targetFrame) { // We did not find a target frame. Ask our frame to load the page. This may or may not create a popup window. - FrameLoadRequest frameRequest(frame, request->request()); + FrameLoadRequest frameRequest(frame, request->request(), ShouldOpenExternalURLsPolicy::ShouldNotAllow); frameRequest.setFrameName(request->target()); frameRequest.setShouldCheckNewWindowPolicy(true); frame->loader().load(frameRequest); @@ -1155,10 +1204,9 @@ void PluginView::performFrameLoadURLRequest(URLRequest* request) } // Now ask the frame to load the request. - targetFrame->loader().load(FrameLoadRequest(targetFrame, request->request())); + targetFrame->loader().load(FrameLoadRequest(targetFrame, request->request(), ShouldOpenExternalURLsPolicy::ShouldNotAllow)); - WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(targetFrame->loader().client()); - WebFrame* targetWebFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0; + auto* targetWebFrame = WebFrame::fromCoreFrame(*targetFrame); ASSERT(targetWebFrame); if (WebFrame::LoadListener* loadListener = targetWebFrame->loadListener()) { @@ -1193,7 +1241,10 @@ void PluginView::performJavaScriptURLRequest(URLRequest* request) // Evaluate the JavaScript code. Note that running JavaScript here could cause the plug-in to be destroyed, so we // grab references to the plug-in here. RefPtr<Plugin> plugin = m_plugin; - Deprecated::ScriptValue result = frame->script().executeScript(jsString, request->allowPopups()); + auto result = frame->script().executeScript(jsString, request->allowPopups()); + + if (!result) + return; // Check if evaluating the JavaScript destroyed the plug-in. if (!plugin->controller()) @@ -1238,12 +1289,12 @@ void PluginView::cancelAllStreams() void PluginView::redeliverManualStream() { - if (m_manualStreamState == StreamStateInitial) { + if (m_manualStreamState == ManualStreamState::Initial) { // Nothing to do. return; } - if (m_manualStreamState == StreamStateFailed) { + if (m_manualStreamState == ManualStreamState::Failed) { manualLoadDidFail(m_manualStreamError); return; } @@ -1264,7 +1315,7 @@ void PluginView::redeliverManualStream() m_manualStreamData = nullptr; } - if (m_manualStreamState == StreamStateFinished) + if (m_manualStreamState == ManualStreamState::Finished) manualLoadDidFinishLoading(); } @@ -1273,7 +1324,7 @@ void PluginView::invalidateRect(const IntRect& dirtyRect) if (!parent() || !m_plugin || !m_isInitialized) return; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (m_plugin->pluginLayer()) return; #endif @@ -1281,12 +1332,13 @@ void PluginView::invalidateRect(const IntRect& dirtyRect) if (m_pluginElement->displayState() < HTMLPlugInElement::Restarting) return; - RenderBoxModelObject* renderer = toRenderBoxModelObject(m_pluginElement->renderer()); - if (!renderer) + auto* renderer = m_pluginElement->renderer(); + if (!is<RenderEmbeddedObject>(renderer)) return; + auto& object = downcast<RenderEmbeddedObject>(*renderer); IntRect contentRect(dirtyRect); - contentRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop()); + contentRect.move(object.borderLeft() + object.paddingLeft(), object.borderTop() + object.paddingTop()); renderer->repaintRectangle(contentRect); } @@ -1300,7 +1352,7 @@ void PluginView::setFocus(bool hasFocus) m_plugin->setFocus(hasFocus); } -void PluginView::mediaCanStart() +void PluginView::mediaCanStart(WebCore::Document&) { ASSERT(m_isWaitingUntilMediaCanStart); m_isWaitingUntilMediaCanStart = false; @@ -1308,9 +1360,15 @@ void PluginView::mediaCanStart() initializePlugin(); } -bool PluginView::isPluginVisible() +void PluginView::pageMutedStateDidChange() { - return isVisible(); +#if ENABLE(NETSCAPE_PLUGIN_API) + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->mutedStateChanged(isMuted()); +#endif } void PluginView::invalidate(const IntRect& dirtyRect) @@ -1327,14 +1385,18 @@ String PluginView::userAgent() return frame->loader().client().userAgent(URL()); } -void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, - const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) +void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) { - FrameLoadRequest frameLoadRequest(m_pluginElement->document().securityOrigin()); + FrameLoadRequest frameLoadRequest(m_pluginElement->document().securityOrigin(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow); frameLoadRequest.resourceRequest().setHTTPMethod(method); frameLoadRequest.resourceRequest().setURL(m_pluginElement->document().completeURL(urlString)); - frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields); - frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(httpBody.data(), httpBody.size())); + frameLoadRequest.resourceRequest().setHTTPHeaderFields(headerFields); + if (!httpBody.isEmpty()) { + frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(httpBody.data(), httpBody.size())); + if (frameLoadRequest.resourceRequest().httpContentType().isEmpty()) + frameLoadRequest.resourceRequest().setHTTPContentType("application/x-www-form-urlencoded"); + } + frameLoadRequest.setFrameName(target); String referrer = SecurityPolicy::generateReferrerHeader(frame()->document()->referrerPolicy(), frameLoadRequest.resourceRequest().url(), frame()->loader().outgoingReferrer()); @@ -1358,6 +1420,15 @@ void PluginView::cancelStreamLoad(uint64_t streamID) ASSERT(!m_streams.contains(streamID)); } +void PluginView::continueStreamLoad(uint64_t streamID) +{ + RefPtr<Stream> stream = m_streams.get(streamID); + if (!stream) + return; + + stream->continueLoad(); +} + void PluginView::cancelManualStreamLoad() { if (!frame()) @@ -1381,7 +1452,7 @@ NPObject* PluginView::windowScriptNPObject() return 0; } - return m_npRuntimeObjectMap.getOrCreateNPObject(*pluginWorld().vm(), frame()->script().windowShell(pluginWorld())->window()); + return m_npRuntimeObjectMap.getOrCreateNPObject(pluginWorld().vm(), frame()->script().windowShell(pluginWorld())->window()); } NPObject* PluginView::pluginElementNPObject() @@ -1397,7 +1468,7 @@ NPObject* PluginView::pluginElementNPObject() JSObject* object = frame()->script().jsObjectForPluginElement(m_pluginElement.get()); ASSERT(object); - return m_npRuntimeObjectMap.getOrCreateNPObject(*pluginWorld().vm(), object); + return m_npRuntimeObjectMap.getOrCreateNPObject(pluginWorld().vm(), object); } bool PluginView::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups) @@ -1410,9 +1481,26 @@ bool PluginView::evaluate(NPObject* npObject, const String& scriptString, NPVari // protect the plug-in view from destruction. NPRuntimeObjectMap::PluginProtector pluginProtector(&m_npRuntimeObjectMap); - UserGestureIndicator gestureIndicator(allowPopups ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture); + UserGestureIndicator gestureIndicator(allowPopups ? std::optional<ProcessingUserGestureState>(ProcessingUserGesture) : std::nullopt); return m_npRuntimeObjectMap.evaluate(npObject, scriptString, result); } + +void PluginView::setPluginIsPlayingAudio(bool pluginIsPlayingAudio) +{ + if (m_pluginIsPlayingAudio == pluginIsPlayingAudio) + return; + + m_pluginIsPlayingAudio = pluginIsPlayingAudio; + m_pluginElement->document().updateIsPlayingMedia(); +} + +bool PluginView::isMuted() const +{ + if (!frame() || !frame()->page()) + return false; + + return frame()->page()->isAudioMuted(); +} #endif void PluginView::setStatusbarText(const String& statusbarText) @@ -1424,7 +1512,7 @@ void PluginView::setStatusbarText(const String& statusbarText) if (!page) return; - page->chrome().setStatusbarText(frame(), statusbarText); + page->chrome().setStatusbarText(*frame(), statusbarText); } bool PluginView::isAcceleratedCompositingEnabled() @@ -1446,29 +1534,18 @@ void PluginView::pluginProcessCrashed() { m_pluginProcessHasCrashed = true; - if (!m_pluginElement->renderer()) + auto* renderer = m_pluginElement->renderer(); + if (!is<RenderEmbeddedObject>(renderer)) return; - if (!m_pluginElement->renderer()->isEmbeddedObject()) - return; + m_pluginElement->invalidateStyleAndLayerComposition(); - m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange); + downcast<RenderEmbeddedObject>(*renderer).setPluginUnavailabilityReason(RenderEmbeddedObject::PluginCrashed); - RenderEmbeddedObject* renderer = toRenderEmbeddedObject(m_pluginElement->renderer()); - renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginCrashed); - Widget::invalidate(); } -void PluginView::willSendEventToPlugin() -{ - // If we're sending an event to a plug-in, we can't control how long the plug-in - // takes to process it (e.g. it may display a context menu), so we tell the UI process - // to stop the responsiveness timer in this case. - m_webPage->send(Messages::WebPageProxy::StopResponsivenessTimer()); -} - -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void PluginView::pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) { if (m_webPage) @@ -1481,14 +1558,9 @@ void PluginView::setComplexTextInputState(PluginComplexTextInputState pluginComp m_webPage->send(Messages::WebPageProxy::SetPluginComplexTextInputState(m_plugin->pluginComplexTextInputIdentifier(), pluginComplexTextInputState)); } -mach_port_t PluginView::compositingRenderServerPort() +const MachSendRight& PluginView::compositingRenderServerPort() { - return WebProcess::shared().compositingRenderServerPort(); -} - -void PluginView::openPluginPreferencePane() -{ - ASSERT_NOT_REACHED(); + return WebProcess::singleton().compositingRenderServerPort(); } #endif @@ -1511,19 +1583,24 @@ String PluginView::proxiesForURL(const String& urlString) String PluginView::cookiesForURL(const String& urlString) { - return cookies(&m_pluginElement->document(), URL(URL(), urlString)); + return cookies(m_pluginElement->document(), URL(URL(), urlString)); } void PluginView::setCookiesForURL(const String& urlString, const String& cookieString) { - setCookies(&m_pluginElement->document(), URL(URL(), urlString), cookieString); + setCookies(m_pluginElement->document(), URL(URL(), urlString), cookieString); } bool PluginView::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password) { - Credential credential = CredentialStorage::get(protectionSpace); + auto* contentDocument = m_pluginElement->contentDocument(); + if (!contentDocument) + return false; + + String partitionName = contentDocument->topDocument().securityOrigin().domainForCachePartition(); + Credential credential = CredentialStorage::defaultCredentialStorage().get(partitionName, protectionSpace); if (credential.isEmpty()) - credential = CredentialStorage::getFromPersistentStorage(protectionSpace); + credential = CredentialStorage::defaultCredentialStorage().getFromPersistentStorage(protectionSpace); if (!credential.hasPassword()) return false; @@ -1540,10 +1617,10 @@ bool PluginView::isPrivateBrowsingEnabled() if (!frame()) return true; - if (!frame()->document()->securityOrigin()->canAccessPluginStorage(frame()->document()->topOrigin())) + if (!frame()->document()->securityOrigin().canAccessPluginStorage(frame()->document()->topOrigin())) return true; - return frame()->settings().privateBrowsingEnabled(); + return frame()->page()->usesEphemeralSession(); } bool PluginView::asynchronousPluginInitializationEnabled() const @@ -1567,11 +1644,6 @@ void PluginView::protectPluginFromDestruction() ref(); } -static void derefPluginView(PluginView* pluginView) -{ - pluginView->deref(); -} - void PluginView::unprotectPluginFromDestruction() { if (m_isBeingDestroyed) @@ -1582,10 +1654,13 @@ void PluginView::unprotectPluginFromDestruction() // for example, may crash if the plug-in is destroyed and we return to code for // the destroyed object higher on the stack. To prevent this, if the plug-in has // only one remaining reference, call deref() asynchronously. - if (hasOneRef()) - RunLoop::main()->dispatch(bind(derefPluginView, this)); - else - deref(); + if (hasOneRef()) { + RunLoop::main().dispatch([lastRef = adoptRef(*this)] { + }); + return; + } + + deref(); } void PluginView::didFinishLoad(WebFrame* webFrame) @@ -1610,7 +1685,8 @@ void PluginView::didFailLoad(WebFrame* webFrame, bool wasCancelled) uint64_t PluginView::createPluginContainer() { uint64_t windowID = 0; - m_webPage->sendSync(Messages::WebPageProxy::CreatePluginContainer(), Messages::WebPageProxy::CreatePluginContainer::Reply(windowID)); + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) + m_webPage->sendSync(Messages::WebPageProxy::CreatePluginContainer(), Messages::WebPageProxy::CreatePluginContainer::Reply(windowID)); return windowID; } @@ -1625,10 +1701,10 @@ void PluginView::windowedPluginVisibilityDidChange(bool isVisible, uint64_t wind } #endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) static bool isAlmostSolidColor(BitmapImage* bitmap) { - CGImageRef image = bitmap->getCGImageRef(); + CGImageRef image = bitmap->nativeImage().get(); ASSERT(CGImageGetBitsPerComponent(image) == 8); CGBitmapInfo imageInfo = CGImageGetBitmapInfo(image); @@ -1688,11 +1764,16 @@ static bool isAlmostSolidColor(BitmapImage* bitmap) } #endif -void PluginView::pluginSnapshotTimerFired(DeferrableOneShotTimer<PluginView>&) +void PluginView::pluginSnapshotTimerFired() { - ASSERT(m_plugin); +#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) + HTMLPlugInImageElement& plugInImageElement = downcast<HTMLPlugInImageElement>(*m_pluginElement); + bool isPlugInOnScreen = m_webPage->plugInIntersectsSearchRect(plugInImageElement); + bool plugInCameOnScreen = isPlugInOnScreen && m_didPlugInStartOffScreen; + bool snapshotFound = false; +#endif - if (m_plugin->supportsSnapshotting()) { + if (m_plugin && m_plugin->supportsSnapshotting()) { // Snapshot might be 0 if plugin size is 0x0. RefPtr<ShareableBitmap> snapshot = m_plugin->snapshot(); RefPtr<Image> snapshotImage; @@ -1700,18 +1781,33 @@ void PluginView::pluginSnapshotTimerFired(DeferrableOneShotTimer<PluginView>&) snapshotImage = snapshot->createImage(); m_pluginElement->updateSnapshot(snapshotImage.get()); -#if PLATFORM(MAC) - unsigned maximumSnapshotRetries = frame() ? frame()->settings().maximumPlugInSnapshotAttempts() : 0; - if (snapshotImage && isAlmostSolidColor(toBitmapImage(snapshotImage.get())) && m_countSnapshotRetries < maximumSnapshotRetries) { - ++m_countSnapshotRetries; - m_pluginSnapshotTimer.restart(); - return; - } + if (snapshotImage) { +#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) + bool snapshotIsAlmostSolidColor = isAlmostSolidColor(downcast<BitmapImage>(snapshotImage.get())); + snapshotFound = !snapshotIsAlmostSolidColor; +#endif + +#if PLATFORM(COCOA) + unsigned maximumSnapshotRetries = frame() ? frame()->settings().maximumPlugInSnapshotAttempts() : 0; + if (snapshotIsAlmostSolidColor && m_countSnapshotRetries < maximumSnapshotRetries && !plugInCameOnScreen) { + ++m_countSnapshotRetries; + m_pluginSnapshotTimer.restart(); + return; + } #endif + } } - // Even if there is no snapshot we still set the state to DisplayingSnapshot - // since we just want to display the default empty box. - m_pluginElement->setDisplayState(HTMLPlugInElement::DisplayingSnapshot); + +#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) + unsigned candidateArea = 0; + unsigned maximumSnapshotRetries = frame() ? frame()->settings().maximumPlugInSnapshotAttempts() : 0; + bool noSnapshotFoundAfterMaxRetries = m_countSnapshotRetries == maximumSnapshotRetries && !isPlugInOnScreen && !snapshotFound; + if (m_webPage->plugInIsPrimarySize(plugInImageElement, candidateArea) + && (noSnapshotFoundAfterMaxRetries || plugInCameOnScreen)) + m_pluginElement->setDisplayState(HTMLPlugInElement::Playing); + else +#endif + m_pluginElement->setDisplayState(HTMLPlugInElement::DisplayingSnapshot); } void PluginView::beginSnapshottingRunningPlugin() @@ -1740,12 +1836,12 @@ void PluginView::pluginDidReceiveUserInteraction() m_didReceiveUserInteraction = true; - WebCore::HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(m_pluginElement.get()); - String pageOrigin = plugInImageElement->document().page()->mainFrame().document()->baseURL().host(); - String pluginOrigin = plugInImageElement->loadedUrl().host(); - String mimeType = plugInImageElement->loadedMimeType(); + HTMLPlugInImageElement& plugInImageElement = downcast<HTMLPlugInImageElement>(*m_pluginElement); + String pageOrigin = plugInImageElement.document().page()->mainFrame().document()->baseURL().host(); + String pluginOrigin = plugInImageElement.loadedUrl().host(); + String mimeType = plugInImageElement.loadedMimeType(); - WebProcess::shared().plugInDidReceiveUserInteraction(pageOrigin, pluginOrigin, mimeType); + WebProcess::singleton().plugInDidReceiveUserInteraction(pageOrigin, pluginOrigin, mimeType, plugInImageElement.document().page()->sessionID()); } bool PluginView::shouldCreateTransientPaintingSnapshot() const @@ -1757,13 +1853,16 @@ bool PluginView::shouldCreateTransientPaintingSnapshot() const return false; if (FrameView* frameView = frame()->view()) { - if (frameView->paintBehavior() & (PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText)) { + if (frameView->paintBehavior() & (PaintBehaviorSelectionOnly | PaintBehaviorSelectionAndBackgroundsOnly | PaintBehaviorForceBlackText)) { // This paint behavior is used when drawing the find indicator and there's no need to // snapshot plug-ins, because they can never be painted as part of the find indicator. return false; } } + if (!m_plugin->canCreateTransientPaintingSnapshot()) + return false; + return true; } diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.h b/Source/WebKit2/WebProcess/Plugins/PluginView.h index 556745aed..6fb61486c 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginView.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2012, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,35 +31,42 @@ #include "Plugin.h" #include "PluginController.h" #include "WebFrame.h" +#include <WebCore/ActivityState.h> #include <WebCore/FindOptions.h> #include <WebCore/Image.h> #include <WebCore/MediaCanStartListener.h> +#include <WebCore/MediaProducer.h> #include <WebCore/PluginViewBase.h> #include <WebCore/ResourceError.h> #include <WebCore/ResourceResponse.h> #include <WebCore/Timer.h> -#include <WebCore/ViewState.h> +#include <memory> #include <wtf/Deque.h> #include <wtf/RunLoop.h> // FIXME: Eventually this should move to WebCore. +#if PLATFORM(COCOA) +OBJC_CLASS NSDictionary; +OBJC_CLASS PDFSelection; +#endif + namespace WebCore { class Frame; class HTMLPlugInElement; +class MachSendRight; class MouseEvent; -class RenderBoxModelObject; } namespace WebKit { class WebEvent; -class PluginView : public WebCore::PluginViewBase, public PluginController, private WebCore::MediaCanStartListener, private WebFrame::LoadListener { +class PluginView : public WebCore::PluginViewBase, public PluginController, private WebCore::MediaCanStartListener, private WebFrame::LoadListener, private WebCore::MediaProducer { public: - static PassRefPtr<PluginView> create(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters&); + static Ref<PluginView> create(WebCore::HTMLPlugInElement&, Ref<Plugin>&&, const Plugin::Parameters&); - void recreateAndInitialize(PassRefPtr<Plugin>); + void recreateAndInitialize(Ref<Plugin>&&); WebCore::Frame* frame() const; @@ -70,11 +77,10 @@ public: void manualLoadDidFinishLoading(); void manualLoadDidFail(const WebCore::ResourceError&); - void viewStateDidChange(WebCore::ViewState::Flags changed); + void activityStateDidChange(WebCore::ActivityState::Flags changed); void setLayerHostingMode(LayerHostingMode); -#if PLATFORM(MAC) - void platformViewStateDidChange(WebCore::ViewState::Flags changed); +#if PLATFORM(COCOA) void setDeviceScaleFactor(float); void windowAndViewFramesChanged(const WebCore::FloatRect& windowFrameInScreenCoordinates, const WebCore::FloatRect& viewFrameInWindowCoordinates); bool sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput); @@ -84,15 +90,16 @@ public: WebCore::HTMLPlugInElement* pluginElement() const { return m_pluginElement.get(); } const Plugin::Parameters& initialParameters() const { return m_parameters; } + Plugin* plugin() const { return m_plugin.get(); } - // FIXME: Remove this; nobody should have to know about the plug-in view's renderer except the plug-in view itself. - WebCore::RenderBoxModelObject* renderer() const; - void setPageScaleFactor(double scaleFactor, WebCore::IntPoint origin); double pageScaleFactor() const; bool handlesPageScaleFactor() const; + bool requiresUnifiedScaleFactor() const; void pageScaleFactorDidChange(); + void topContentInsetDidChange(); + void webPageDestroyed(); bool handleEditingCommand(const String& commandName, const String& argument); @@ -105,11 +112,13 @@ public: bool shouldAllowScripting(); - PassRefPtr<WebCore::SharedBuffer> liveResourceData() const; + RefPtr<WebCore::SharedBuffer> liveResourceData() const; bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&); + String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const; + bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const; private: - PluginView(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters& parameters); + PluginView(WebCore::HTMLPlugInElement&, Ref<Plugin>&&, const Plugin::Parameters&); virtual ~PluginView(); void initializePlugin(); @@ -136,106 +145,114 @@ private: void redeliverManualStream(); - void pluginSnapshotTimerFired(WebCore::DeferrableOneShotTimer<PluginView>&); + void pluginSnapshotTimerFired(); void pluginDidReceiveUserInteraction(); bool shouldCreateTransientPaintingSnapshot() const; // WebCore::PluginViewBase -#if PLATFORM(MAC) - virtual PlatformLayer* platformLayer() const; +#if PLATFORM(COCOA) + PlatformLayer* platformLayer() const override; #endif - virtual JSC::JSObject* scriptObject(JSC::JSGlobalObject*); - virtual void storageBlockingStateChanged(); - virtual void privateBrowsingStateChanged(bool); - virtual bool getFormValue(String&); - virtual bool scroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); - virtual WebCore::Scrollbar* horizontalScrollbar(); - virtual WebCore::Scrollbar* verticalScrollbar(); - virtual bool wantsWheelEvents(); - virtual bool shouldAlwaysAutoStart() const override; - virtual void beginSnapshottingRunningPlugin() override; - virtual bool shouldAllowNavigationFromDrags() const override; - virtual bool shouldNotAddLayer() const override; + JSC::JSObject* scriptObject(JSC::JSGlobalObject*) override; + void storageBlockingStateChanged() override; + void privateBrowsingStateChanged(bool) override; + bool getFormValue(String&) override; + bool scroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override; + WebCore::Scrollbar* horizontalScrollbar() override; + WebCore::Scrollbar* verticalScrollbar() override; + bool wantsWheelEvents() override; + bool shouldAlwaysAutoStart() const override; + void beginSnapshottingRunningPlugin() override; + bool shouldAllowNavigationFromDrags() const override; + bool shouldNotAddLayer() const override; + void willDetatchRenderer() override; // WebCore::Widget - virtual void setFrameRect(const WebCore::IntRect&); - virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect&); - virtual void invalidateRect(const WebCore::IntRect&); - virtual void setFocus(bool); - virtual void frameRectsChanged(); - virtual void setParent(WebCore::ScrollView*); - virtual void handleEvent(WebCore::Event*); - virtual void notifyWidget(WebCore::WidgetNotification); - virtual void show(); - virtual void hide(); - virtual void setParentVisible(bool); - virtual bool transformsAffectFrameRect(); - virtual void clipRectChanged() override; + void setFrameRect(const WebCore::IntRect&) override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect&, WebCore::Widget::SecurityOriginPaintPolicy) override; + void invalidateRect(const WebCore::IntRect&) override; + void setFocus(bool) override; + void frameRectsChanged() override; + void setParent(WebCore::ScrollView*) override; + void handleEvent(WebCore::Event*) override; + void notifyWidget(WebCore::WidgetNotification) override; + void show() override; + void hide() override; + void setParentVisible(bool) override; + bool transformsAffectFrameRect() override; + void clipRectChanged() override; // WebCore::MediaCanStartListener - virtual void mediaCanStart(); + void mediaCanStart(WebCore::Document&) override; + + // WebCore::MediaProducer + MediaProducer::MediaStateFlags mediaState() const override { return m_pluginIsPlayingAudio ? MediaProducer::IsPlayingAudio : MediaProducer::IsNotPlaying; } + void pageMutedStateDidChange() override; // PluginController - virtual bool isPluginVisible(); - virtual void invalidate(const WebCore::IntRect&); - virtual String userAgent(); - virtual void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, - const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups); - virtual void cancelStreamLoad(uint64_t streamID); - virtual void cancelManualStreamLoad(); + void invalidate(const WebCore::IntRect&) override; + String userAgent() override; + void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) override; + void cancelStreamLoad(uint64_t streamID) override; + void continueStreamLoad(uint64_t streamID) override; + void cancelManualStreamLoad() override; #if ENABLE(NETSCAPE_PLUGIN_API) - virtual NPObject* windowScriptNPObject(); - virtual NPObject* pluginElementNPObject(); - virtual bool evaluate(NPObject*, const String&scriptString, NPVariant* result, bool allowPopups); + NPObject* windowScriptNPObject() override; + NPObject* pluginElementNPObject() override; + bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups) override; + void setPluginIsPlayingAudio(bool) override; + bool isMuted() const override; #endif - virtual void setStatusbarText(const String&); - virtual bool isAcceleratedCompositingEnabled(); - virtual void pluginProcessCrashed(); - virtual void willSendEventToPlugin(); -#if PLATFORM(MAC) - virtual void pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus); - virtual void setComplexTextInputState(PluginComplexTextInputState); - virtual mach_port_t compositingRenderServerPort(); - virtual void openPluginPreferencePane() override; + void setStatusbarText(const String&) override; + bool isAcceleratedCompositingEnabled() override; + void pluginProcessCrashed() override; +#if PLATFORM(COCOA) + void pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) override; + void setComplexTextInputState(PluginComplexTextInputState) override; + const WebCore::MachSendRight& compositingRenderServerPort() override; #endif - virtual float contentsScaleFactor(); - virtual String proxiesForURL(const String&); - virtual String cookiesForURL(const String&); - virtual void setCookiesForURL(const String& urlString, const String& cookieString); - virtual bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); - virtual bool isPrivateBrowsingEnabled(); - virtual bool asynchronousPluginInitializationEnabled() const; - virtual bool asynchronousPluginInitializationEnabledForAllPlugins() const; - virtual bool artificialPluginInitializationDelayEnabled() const; - virtual void protectPluginFromDestruction(); - virtual void unprotectPluginFromDestruction(); + float contentsScaleFactor() override; + String proxiesForURL(const String&) override; + String cookiesForURL(const String&) override; + void setCookiesForURL(const String& urlString, const String& cookieString) override; + bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password) override; + bool isPrivateBrowsingEnabled() override; + bool asynchronousPluginInitializationEnabled() const override; + bool asynchronousPluginInitializationEnabledForAllPlugins() const override; + bool artificialPluginInitializationDelayEnabled() const override; + void protectPluginFromDestruction() override; + void unprotectPluginFromDestruction() override; #if PLUGIN_ARCHITECTURE(X11) - virtual uint64_t createPluginContainer(); - virtual void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID); - virtual void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID); + uint64_t createPluginContainer() override; + void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID) override; + void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID) override; #endif - virtual void didInitializePlugin(); - virtual void didFailToInitializePlugin(); + void didInitializePlugin() override; + void didFailToInitializePlugin() override; void destroyPluginAndReset(); // WebFrame::LoadListener - virtual void didFinishLoad(WebFrame*); - virtual void didFailLoad(WebFrame*, bool wasCancelled); + void didFinishLoad(WebFrame*) override; + void didFailLoad(WebFrame*, bool wasCancelled) override; - OwnPtr<WebEvent> createWebEvent(WebCore::MouseEvent*) const; + std::unique_ptr<WebEvent> createWebEvent(WebCore::MouseEvent*) const; RefPtr<WebCore::HTMLPlugInElement> m_pluginElement; RefPtr<Plugin> m_plugin; WebPage* m_webPage; Plugin::Parameters m_parameters; - - bool m_isInitialized; - bool m_isWaitingForSynchronousInitialization; - bool m_isWaitingUntilMediaCanStart; - bool m_isBeingDestroyed; - bool m_pluginProcessHasCrashed; + + bool m_isInitialized { false }; + bool m_isWaitingForSynchronousInitialization { false }; + bool m_isWaitingUntilMediaCanStart { false }; + bool m_isBeingDestroyed { false }; + bool m_pluginProcessHasCrashed { false }; + +#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) + bool m_didPlugInStartOffScreen { false }; +#endif // Pending URLRequests that the plug-in has made. Deque<RefPtr<URLRequest>> m_pendingURLRequests; @@ -250,31 +267,30 @@ private: #if ENABLE(NETSCAPE_PLUGIN_API) // A map of all related NPObjects for this plug-in view. - NPRuntimeObjectMap m_npRuntimeObjectMap; + NPRuntimeObjectMap m_npRuntimeObjectMap { this }; #endif // The manual stream state. This is used so we can deliver a manual stream to a plug-in // when it is initialized. - enum ManualStreamState { - StreamStateInitial, - StreamStateHasReceivedResponse, - StreamStateFinished, - StreamStateFailed - }; - ManualStreamState m_manualStreamState; + enum class ManualStreamState { Initial, HasReceivedResponse, Finished, Failed }; + ManualStreamState m_manualStreamState { ManualStreamState::Initial }; WebCore::ResourceResponse m_manualStreamResponse; WebCore::ResourceError m_manualStreamError; RefPtr<WebCore::SharedBuffer> m_manualStreamData; - + // This snapshot is used to avoid side effects should the plugin run JS during painting. RefPtr<ShareableBitmap> m_transientPaintingSnapshot; // This timer is used when plugin snapshotting is enabled, to capture a plugin placeholder. - WebCore::DeferrableOneShotTimer<PluginView> m_pluginSnapshotTimer; - unsigned m_countSnapshotRetries; - bool m_didReceiveUserInteraction; + WebCore::DeferrableOneShotTimer m_pluginSnapshotTimer; +#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) || PLATFORM(COCOA) + unsigned m_countSnapshotRetries { 0 }; +#endif + bool m_didReceiveUserInteraction { false }; + + double m_pageScaleFactor { 1 }; - double m_pageScaleFactor; + bool m_pluginIsPlayingAudio { false }; }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/WebPluginInfoProvider.cpp b/Source/WebKit2/WebProcess/Plugins/WebPluginInfoProvider.cpp new file mode 100644 index 000000000..144c8ad41 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/WebPluginInfoProvider.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPluginInfoProvider.h" + +#include "HangDetectionDisabler.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcess.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/Document.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/MainFrame.h> +#include <WebCore/Page.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SubframeLoader.h> +#include <wtf/text/StringHash.h> + +#if PLATFORM(MAC) +#include "StringUtilities.h" +#endif + +namespace WebKit { + +WebPluginInfoProvider& WebPluginInfoProvider::singleton() +{ + static WebPluginInfoProvider& pluginInfoProvider = adoptRef(*new WebPluginInfoProvider).leakRef(); + + return pluginInfoProvider; +} + +WebPluginInfoProvider::WebPluginInfoProvider() +{ +} + +WebPluginInfoProvider::~WebPluginInfoProvider() +{ +} + +#if PLATFORM(MAC) +void WebPluginInfoProvider::setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy clientPolicy, const String& host, const String& bundleIdentifier, const String& versionString) +{ + String hostToSet = host.isNull() || !host.length() ? "*" : host; + String bundleIdentifierToSet = bundleIdentifier.isNull() || !bundleIdentifier.length() ? "*" : bundleIdentifier; + String versionStringToSet = versionString.isNull() || !versionString.length() ? "*" : versionString; + + PluginPolicyMapsByIdentifier policiesByIdentifier; + if (m_hostsToPluginIdentifierData.contains(hostToSet)) + policiesByIdentifier = m_hostsToPluginIdentifierData.get(hostToSet); + + PluginLoadClientPoliciesByBundleVersion versionsToPolicies; + if (policiesByIdentifier.contains(bundleIdentifierToSet)) + versionsToPolicies = policiesByIdentifier.get(bundleIdentifierToSet); + + versionsToPolicies.set(versionStringToSet, clientPolicy); + policiesByIdentifier.set(bundleIdentifierToSet, versionsToPolicies); + m_hostsToPluginIdentifierData.set(hostToSet, policiesByIdentifier); +} + +void WebPluginInfoProvider::clearPluginClientPolicies() +{ + m_hostsToPluginIdentifierData.clear(); +} +#endif + +void WebPluginInfoProvider::refreshPlugins() +{ +#if ENABLE(NETSCAPE_PLUGIN_API) + m_cachedPlugins.clear(); + m_pluginCacheIsPopulated = false; + m_shouldRefreshPlugins = true; +#endif +} + +void WebPluginInfoProvider::getPluginInfo(WebCore::Page& page, Vector<WebCore::PluginInfo>& plugins) +{ +#if ENABLE(NETSCAPE_PLUGIN_API) + populatePluginCache(page); + + if (page.mainFrame().loader().subframeLoader().allowPlugins()) { + plugins = m_cachedPlugins; + return; + } + + plugins = m_cachedApplicationPlugins; +#else + UNUSED_PARAM(page); + UNUSED_PARAM(plugins); +#endif // ENABLE(NETSCAPE_PLUGIN_API) +} + +void WebPluginInfoProvider::getWebVisiblePluginInfo(WebCore::Page& page, Vector<WebCore::PluginInfo>& plugins) +{ + ASSERT_ARG(plugins, plugins.isEmpty()); + + getPluginInfo(page, plugins); + +#if PLATFORM(MAC) + if (auto* document = page.mainFrame().document()) { + if (document->securityOrigin().isLocal()) + return; + } + + for (int32_t i = plugins.size() - 1; i >= 0; --i) { + auto& info = plugins.at(i); + + // Allow built-in plugins. Also tentatively allow plugins that the client might later selectively permit. + if (info.isApplicationPlugin || info.clientLoadPolicy == WebCore::PluginLoadClientPolicyAsk) + continue; + + if (info.clientLoadPolicy == WebCore::PluginLoadClientPolicyBlock) + plugins.remove(i); + } +#endif +} + +#if ENABLE(NETSCAPE_PLUGIN_API) +void WebPluginInfoProvider::populatePluginCache(const WebCore::Page& page) +{ + if (!m_pluginCacheIsPopulated) { + HangDetectionDisabler hangDetectionDisabler; + + if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetPlugins(m_shouldRefreshPlugins), Messages::WebProcessProxy::GetPlugins::Reply(m_cachedPlugins, m_cachedApplicationPlugins), 0)) + return; + + m_shouldRefreshPlugins = false; + m_pluginCacheIsPopulated = true; + } + +#if PLATFORM(MAC) + String pageHost = page.mainFrame().loader().documentLoader()->responseURL().host(); + for (auto& info : m_cachedPlugins) { + if (auto clientPolicy = pluginLoadClientPolicyForHost(pageHost, info)) + info.clientLoadPolicy = *clientPolicy; + } +#else + UNUSED_PARAM(page); +#endif // not PLATFORM(MAC) +} +#endif + +#if PLATFORM(MAC) +std::optional<WebCore::PluginLoadClientPolicy> WebPluginInfoProvider::pluginLoadClientPolicyForHost(const String& host, const WebCore::PluginInfo& info) const +{ + String hostToLookUp = host; + String identifier = info.bundleIdentifier; + + auto policiesByIdentifierIterator = m_hostsToPluginIdentifierData.find(hostToLookUp); + + if (!identifier.isNull() && policiesByIdentifierIterator == m_hostsToPluginIdentifierData.end()) { + if (!replaceHostWithMatchedWildcardHost(hostToLookUp, identifier)) + hostToLookUp = "*"; + policiesByIdentifierIterator = m_hostsToPluginIdentifierData.find(hostToLookUp); + if (hostToLookUp != "*" && policiesByIdentifierIterator == m_hostsToPluginIdentifierData.end()) { + hostToLookUp = "*"; + policiesByIdentifierIterator = m_hostsToPluginIdentifierData.find(hostToLookUp); + } + } + if (policiesByIdentifierIterator == m_hostsToPluginIdentifierData.end()) + return std::nullopt; + + auto& policiesByIdentifier = policiesByIdentifierIterator->value; + + if (!identifier) + identifier = "*"; + + auto identifierPolicyIterator = policiesByIdentifier.find(identifier); + if (identifier != "*" && identifierPolicyIterator == policiesByIdentifier.end()) { + identifier = "*"; + identifierPolicyIterator = policiesByIdentifier.find(identifier); + } + + if (identifierPolicyIterator == policiesByIdentifier.end()) + return std::nullopt; + + auto& versionsToPolicies = identifierPolicyIterator->value; + + String version = info.versionString; + if (!version) + version = "*"; + auto policyIterator = versionsToPolicies.find(version); + if (version != "*" && policyIterator == versionsToPolicies.end()) { + version = "*"; + policyIterator = versionsToPolicies.find(version); + } + + if (policyIterator == versionsToPolicies.end()) + return std::nullopt; + + return policyIterator->value; +} + +String WebPluginInfoProvider::longestMatchedWildcardHostForHost(const String& host) const +{ + String longestMatchedHost; + + for (auto& key : m_hostsToPluginIdentifierData.keys()) { + if (key.contains('*') && key != "*" && stringMatchesWildcardString(host, key)) { + if (key.length() > longestMatchedHost.length()) + longestMatchedHost = key; + else if (key.length() == longestMatchedHost.length() && codePointCompareLessThan(key, longestMatchedHost)) + longestMatchedHost = key; + } + } + + return longestMatchedHost; +} + +bool WebPluginInfoProvider::replaceHostWithMatchedWildcardHost(String& host, const String& identifier) const +{ + String matchedWildcardHost = longestMatchedWildcardHostForHost(host); + + if (matchedWildcardHost.isNull()) + return false; + + auto plugInIdentifierData = m_hostsToPluginIdentifierData.find(matchedWildcardHost); + if (plugInIdentifierData == m_hostsToPluginIdentifierData.end() || !plugInIdentifierData->value.contains(identifier)) + return false; + + host = matchedWildcardHost; + return true; +} +#endif + +} diff --git a/Source/WebKit2/WebProcess/Plugins/WebPluginInfoProvider.h b/Source/WebKit2/WebProcess/Plugins/WebPluginInfoProvider.h new file mode 100644 index 000000000..30fda4f52 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/WebPluginInfoProvider.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <WebCore/PluginInfoProvider.h> +#include <wtf/HashMap.h> + +namespace WebKit { + +class WebPluginInfoProvider final : public WebCore::PluginInfoProvider { + friend class NeverDestroyed<WebPluginInfoProvider>; + +public: + static WebPluginInfoProvider& singleton(); + virtual ~WebPluginInfoProvider(); + +#if PLATFORM(MAC) + void setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy, const String& host, const String& bundleIdentifier, const String& versionString); + void clearPluginClientPolicies(); +#endif + +private: + WebPluginInfoProvider(); + + void getPluginInfo(WebCore::Page&, Vector<WebCore::PluginInfo>&) override; + void getWebVisiblePluginInfo(WebCore::Page&, Vector<WebCore::PluginInfo>&) override; + void refreshPlugins() override; + +#if ENABLE(NETSCAPE_PLUGIN_API) + void populatePluginCache(const WebCore::Page&); +#endif // ENABLE(NETSCAPE_PLUGIN_API) + +#if PLATFORM(MAC) + std::optional<WebCore::PluginLoadClientPolicy> pluginLoadClientPolicyForHost(const String&, const WebCore::PluginInfo&) const; + String longestMatchedWildcardHostForHost(const String& host) const; + bool replaceHostWithMatchedWildcardHost(String& host, const String& identifier) const; + + typedef HashMap<String, WebCore::PluginLoadClientPolicy> PluginLoadClientPoliciesByBundleVersion; + typedef HashMap<String, PluginLoadClientPoliciesByBundleVersion> PluginPolicyMapsByIdentifier; + HashMap<String, PluginPolicyMapsByIdentifier> m_hostsToPluginIdentifierData; +#endif + +#if ENABLE(NETSCAPE_PLUGIN_API) + bool m_pluginCacheIsPopulated { false }; + bool m_shouldRefreshPlugins { false }; + Vector<WebCore::PluginInfo> m_cachedPlugins; + Vector<WebCore::PluginInfo> m_cachedApplicationPlugins; +#endif +}; + +} |