Full-page PDFPlugin should support inline form editing
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Oct 2012 07:53:47 +0000 (07:53 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Oct 2012 07:53:47 +0000 (07:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=100155

Reviewed by Dan Bernstein.

Add form controls corresponding to Text and Choice PDF annotations,
allowing for single- and multi-line text input, and <select>-like input.

Currently, forms are only implemented for full-page PDF documents.

* Shared/mac/PDFKitImports.h:
(WebKit): Add pdfAnnotationTextWidgetClass and pdfAnnotationChoiceWidgetClass.
* Shared/mac/PDFKitImports.mm:
(WebKit::pdfAnnotationTextWidgetClass): Add pdfAnnotationTextWidgetClass.
(WebKit::pdfAnnotationChoiceWidgetClass): Add pdfAnnotationChoiceWidgetClass.
* WebKit2.xcodeproj/project.pbxproj: Add PDFLayerControllerDetails, PDFPluginTextAnnotation, PDFPluginChoiceAnnotation,
and PDFPluginAnnotation.
* WebProcess/Plugins/PDF/PDFLayerControllerDetails.h: Added. Extract PDFLayerController details category into a header.
* WebProcess/Plugins/PDF/PDFPlugin.h:
(PDFPlugin): Add m_activeAnnotation, to keep track of the active PDFPluginAnnotation, and m_annotationContainer,
the <div> that form controls are inserted into.
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(-[WKPDFLayerControllerDelegate pdfLayerController:didChangeActiveAnnotation:]): Forward active annotation changes to PDFPlugin.
(WebKit::PDFPlugin::PDFPlugin): Add a <div> to the PluginDocument <body>, which will contain <input>, <select>, and <textarea> elements
corresponding to the active annotation. This div is made to fit to the body, and is "overflow: hidden" so that form elements scrolled
out of the viewport do not cause the Document to expand to be larger than the Plugin.
(WebKit::PDFPlugin::pdfDocumentDidLoad): Update PDFPlugin's notion of the scroll position immediately after the document loads, in case
the scroll position is constrained by PDFKit.
(WebKit::PDFPlugin::destroy): Tear down any forms for the active annotation.
(WebKit::PDFPlugin::geometryDidChange): Notify the current annotation that it should update its geometry when the Plugin's geometry changes.
(WebKit::PDFPlugin::setScrollOffset): Notify the current annotation that it should update its geometry when we scroll.
(WebKit::PDFPlugin::setActiveAnnotation): Commit changes to the current annotation, if there is one, then make a new PDFPluginAnnotation
corresponding to the newly active annotation, and attach it to our document.
* WebProcess/Plugins/PDF/PDFPluginAnnotation.h: Added.
(WebKit::PDFPluginAnnotation::element): Return the Element corresponding to this object.
(WebKit::PDFPluginAnnotation::annotation): Return the PDFAnnotation corresponding to this object.
(WebKit::PDFPluginAnnotation::plugin): Return the Plugin that created this object.
(WebKit::PDFPluginAnnotation::commit): Commit changes from the form to the PDFAnnotation. This is implemented in subclasses.
(WebKit::PDFPluginAnnotation::attach): Attach a PDFPluginAnnotation to its parent Element.
(WebKit::PDFPluginAnnotation::parent): Return the parent Element that we're attach()ed to.
(WebKit::PDFPluginAnnotation::pdfLayerController): Return the pdfLayerController that the PDFAnnotation comes from.
(PDFPluginAnnotationEventListener): Add an event listener to respond to "change" and "blur" events from m_element.
* WebProcess/Plugins/PDF/PDFPluginAnnotation.mm: Added.
(WebKit::PDFPluginAnnotation::create): Create the appropriate PDFPluginAnnotation subclass (PDFPluginTextAnnotation or
PDFPluginChoiceAnnotation based on the class of the PDFAnnotation).
(WebKit::PDFPluginAnnotation::attach): Lazily create the HTML form element corresponding to this annotation. Add it to its parent
element. Add event listeners for "change" and "blur".
(WebKit::PDFPluginAnnotation::~PDFPluginAnnotation): Tear down the annotation, by removing event listeners and removing
the form element from its parent element.
(WebKit::PDFPluginAnnotation::updateGeometry): Update the size and position of the form element, given the current PDF scale and scrolling position.
(WebKit::PDFPluginAnnotation::PDFPluginAnnotationEventListener::handleEvent): If we get a blur or change event, we should remove the
form control to match the behavior of PDFKit.
* WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h: Added.
(WebKit::PDFPluginChoiceAnnotation::choiceAnnotation): Return annotation() with the appropriate cast.
* WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.mm: Added.
(WebKit::PDFPluginChoiceAnnotation::updateGeometry): Update the font size of the choice widget given the current PDF scale.
(WebKit::PDFPluginChoiceAnnotation::commit): Save the value of the currently selected <option> into the PDFAnnotationChoiceWidget.
(WebKit::PDFPluginChoiceAnnotation::createAnnotationElement): Create a <select> element, populated with <option> elements
for the PDFAnnotationChoiceWidget's available choices. Select the correct <option> initially.
* WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h: Added.
(WebKit::PDFPluginTextAnnotation::textAnnotation): Return annotation() with the appropriate cast.
* WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm: Added.
(WebKit::cssAlignmentValueForNSTextAlignment): Return the CSS alignment value for a given NSTextAlignment.
(WebKit::PDFPluginTextAnnotation::createAnnotationElement): Create a <textarea> or <input> element, depending on whether the
PDFAnnotationTextWidget supports multiline editing or not.
(WebKit::PDFPluginTextAnnotation::updateGeometry): Update the font size of the text widget given the current PDF scale.
(WebKit::PDFPluginTextAnnotation::commit): Save the current string in the form element into the PDFAnnotationTextWidget.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::focusedPluginViewForFrame): Return the PluginView for a Frame only if the Plugin's element is focused.
(WebKit::WebPage::executeEditingCommand): Only forward editing commands to PluginView if the plugin itself is focused.
(WebKit::WebPage::isEditingCommandEnabled): Ditto.
(WebKit::WebPage::validateCommand): Ditto.

* WebCore.exp.in: Expose a variety of additional WebCore functionality to WebKit2.
* WebCore.xcodeproj/project.pbxproj: Expose some more WebCore headers as private headers for use in WebKit2.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@132992 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/PDFKitImports.h
Source/WebKit2/Shared/mac/PDFKitImports.mm
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerDetails.h [new file with mode: 0644]
Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h
Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h [new file with mode: 0644]
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm [new file with mode: 0644]
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h [new file with mode: 0644]
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.mm [new file with mode: 0644]
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h [new file with mode: 0644]
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm [new file with mode: 0644]
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index 234527c..3f7f5a7 100644 (file)
@@ -1,3 +1,18 @@
+2012-10-31  Tim Horton  <timothy_horton@apple.com>
+
+        Full-page PDFPlugin should support inline form editing
+        https://bugs.webkit.org/show_bug.cgi?id=100155
+
+        Reviewed by Dan Bernstein.
+
+        Add form controls corresponding to Text and Choice PDF annotations,
+        allowing for single- and multi-line text input, and <option>-like input.
+
+        Currently, forms are only implemented for full-page PDF documents.
+
+        * WebCore.exp.in: Expose a variety of additional WebCore functionality to WebKit2.
+        * WebCore.xcodeproj/project.pbxproj: Expose some more WebCore headers as private headers for use in WebKit2.
+
 2012-10-30  Eric Seidel  <eric@webkit.org>
 
         RoboHornetPro spends ~25% of total test time in WebCore::Region::Shape methods
index af114f4..86e22e3 100644 (file)
@@ -215,6 +215,8 @@ __ZN7WebCore13AXObjectCache21gAccessibilityEnabledE
 __ZN7WebCore13AXObjectCache23focusedUIElementForPageEPKNS_4PageE
 __ZN7WebCore13AXObjectCache42gAccessibilityEnhancedUserInterfaceEnabledE
 __ZN7WebCore13CharacterData7setDataERKN3WTF6StringERi
+__ZN7WebCore13ContainerNode11appendChildEN3WTF10PassRefPtrINS_4NodeEEERib
+__ZN7WebCore13ContainerNode11removeChildEPNS_4NodeERi
 __ZN7WebCore13HTTPHeaderMapC1Ev
 __ZN7WebCore13HTTPHeaderMapD1Ev
 __ZN7WebCore13HitTestResultC1ERKS0_
@@ -226,6 +228,8 @@ __ZN7WebCore13KeyboardEventC1ERKN3WTF12AtomicStringEbbPNS_9DOMWindowERKNS1_6Stri
 __ZN7WebCore13KeyboardEventC1ERKNS_21PlatformKeyboardEventEPNS_9DOMWindowE
 __ZN7WebCore13ResourceErrorC1EP7NSError
 __ZN7WebCore13ResourceErrorC1EP9__CFError
+__ZN7WebCore13StyledElement22setInlineStylePropertyENS_13CSSPropertyIDERKN3WTF6StringEb
+__ZN7WebCore13StyledElement22setInlineStylePropertyENS_13CSSPropertyIDEdNS_17CSSPrimitiveValue9UnitTypesEb
 __ZN7WebCore13createWrapperEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_4NodeE
 __ZN7WebCore13directoryNameERKN3WTF6StringE
 __ZN7WebCore13toHTMLElementEPNS_21FormAssociatedElementE
@@ -265,6 +269,7 @@ __ZN7WebCore14FrameSelection6modifyENS0_11EAlterationENS_18SelectionDirectionENS
 __ZN7WebCore14FrameSelection9selectAllEv
 __ZN7WebCore14FrameSelectionC1EPNS_5FrameE
 __ZN7WebCore14LoaderStrategy21resourceLoadSchedulerEv
+__ZN7WebCore14PluginDocument10pluginNodeEv
 __ZN7WebCore14PluginDocument12pluginWidgetEv
 __ZN7WebCore14ResourceBuffer12createNSDataEv
 __ZN7WebCore14ResourceBufferD1Ev
@@ -412,6 +417,7 @@ __ZN7WebCore16DeviceMotionData12RotationRate6createEbdbdbd
 __ZN7WebCore16DeviceMotionData6createEN3WTF10PassRefPtrINS0_12AccelerationEEES4_NS2_INS0_12RotationRateEEEbd
 __ZN7WebCore16FontFallbackList15releaseFontDataEv
 __ZN7WebCore16FontPlatformDataD1Ev
+__ZN7WebCore16HTMLInputElement8setValueERKN3WTF6StringENS_22TextFieldEventBehaviorE
 __ZN7WebCore16HTMLInputElement13setAutofilledEb
 __ZN7WebCore16HTMLInputElement15setEditingValueERKN3WTF6StringE
 __ZN7WebCore16HTMLInputElement15setValueForUserERKN3WTF6StringE
@@ -526,6 +532,7 @@ __ZN7WebCore19LayerFlushScheduler7suspendEv
 __ZN7WebCore19LayerFlushScheduler8scheduleEv
 __ZN7WebCore19LayerFlushSchedulerC1EPNS_25LayerFlushSchedulerClientE
 __ZN7WebCore19LayerFlushSchedulerD1Ev
+__ZN7WebCore19HTMLTextAreaElement8setValueERKN3WTF6StringE
 __ZN7WebCore19ResourceRequestBase11setHTTPBodyEN3WTF10PassRefPtrINS_8FormDataEEE
 __ZN7WebCore19ResourceRequestBase13setHTTPMethodERKN3WTF6StringE
 __ZN7WebCore19ResourceRequestBase18setHTTPHeaderFieldEPKcRKN3WTF6StringE
@@ -693,6 +700,7 @@ __ZN7WebCore4Node10renderRectEPb
 __ZN7WebCore4Node11appendChildEN3WTF10PassRefPtrIS0_EERib
 __ZN7WebCore4Node11removeChildEPS0_Ri
 __ZN7WebCore4Node14removedLastRefEv
+__ZN7WebCore4Node14setTextContentERKN3WTF6StringERi
 __ZN7WebCore4Node17stopIgnoringLeaksEv
 __ZN7WebCore4Node18startIgnoringLeaksEv
 __ZN7WebCore4Node19setNeedsStyleRecalcENS_15StyleChangeTypeE
@@ -843,6 +851,7 @@ __ZN7WebCore6toNodeEN3JSC7JSValueE
 __ZN7WebCore7Console21shouldPrintExceptionsEv
 __ZN7WebCore7Console24setShouldPrintExceptionsEb
 __ZN7WebCore7Element12setAttributeERKN3WTF12AtomicStringES4_Ri
+__ZN7WebCore7Element12setAttributeERKNS_13QualifiedNameERKN3WTF12AtomicStringE
 __ZN7WebCore7Element17setShadowPseudoIdERKN3WTF12AtomicStringERi
 __ZN7WebCore7Element21boundsInRootViewSpaceEv
 __ZN7WebCore7Element9innerTextEv
@@ -875,6 +884,7 @@ __ZN7WebCore7toRangeEN3JSC7JSValueE
 __ZN7WebCore8CSSValue7destroyEv
 __ZN7WebCore8Document11createRangeEv
 __ZN7WebCore8Document12updateLayoutEv
+__ZN7WebCore8Document13createElementERKNS_13QualifiedNameEb
 __ZN7WebCore8Document14createTextNodeERKN3WTF6StringE
 __ZN7WebCore8Document14setFocusedNodeEN3WTF10PassRefPtrINS_4NodeEEE
 __ZN7WebCore8Document16isPageBoxVisibleEi
@@ -1061,11 +1071,18 @@ __ZN7WebCore9HTMLNames8frameTagE
 __ZN7WebCore9HTMLNames8hrefAttrE
 __ZN7WebCore9HTMLNames8inputTagE
 __ZN7WebCore9HTMLNames8nameAttrE
+__ZN7WebCore9HTMLNames8styleTagE
 __ZN7WebCore9HTMLNames8videoTagE
 __ZN7WebCore9HTMLNames9appletTagE
+__ZN7WebCore9HTMLNames9classAttrE
 __ZN7WebCore9HTMLNames9iframeTagE
 __ZN7WebCore9HTMLNames9objectTagE
+__ZN7WebCore9HTMLNames9optionTagE
 __ZN7WebCore9HTMLNames9scriptTagE
+__ZN7WebCore9HTMLNames9selectTagE
+__ZN7WebCore9HTMLNames9styleAttrE
+__ZN7WebCore9HTMLNames9valueAttrE
+__ZN7WebCore9HTMLNames12selectedAttrE
 __ZN7WebCore9JSElement6s_infoE
 __ZN7WebCore9PageCache11setCapacityEi
 __ZN7WebCore9PageCache27releaseAutoreleasedPagesNowEv
@@ -1279,6 +1296,7 @@ __ZNK7WebCore16VisibleSelection19rootEditableElementEv
 __ZNK7WebCore16VisibleSelection23isContentRichlyEditableEv
 __ZNK7WebCore16VisibleSelection5isAllENS_27EditingBoundaryCrossingRuleE
 __ZNK7WebCore17HTMLPlugInElement12pluginWidgetEv
+__ZNK7WebCore17HTMLSelectElement5valueEv
 __ZNK7WebCore17JSDOMGlobalObject22scriptExecutionContextEv
 __ZNK7WebCore17RegularExpression13matchedLengthEv
 __ZNK7WebCore17RegularExpression5matchERKN3WTF6StringEiPi
@@ -1345,6 +1363,7 @@ __ZNK7WebCore4KURL8protocolEv
 __ZNK7WebCore4KURLcvP5NSURLEv
 __ZNK7WebCore4Node11textContentEb
 __ZN7WebCore4Node12insertBeforeEN3WTF10PassRefPtrIS0_EEPS0_Rib
+__ZNK7WebCore4Node13ownerDocumentEv
 __ZNK7WebCore4Node14isDescendantOfEPKS0_
 __ZNK7WebCore4Node18getSubresourceURLsERN3WTF11ListHashSetINS_4KURLELm256ENS_8KURLHashEEE
 __ZNK7WebCore4Node20traversePreviousNodeEPKS0_
@@ -1361,6 +1380,7 @@ __ZNK7WebCore4Page9groupNameEv
 __ZNK7WebCore4Page9pageCountEv
 __ZNK7WebCore4Node9textRectsERN3WTF6VectorINS_7IntRectELm0EEE
 __ZNK7WebCore5Color7getRGBAERdS1_S1_S1_
+__ZNK7WebCore5Color10serializedEv
 __ZNK7WebCore5Frame13ownerRendererEv
 __ZNK7WebCore5Frame14selectionImageEb
 __ZNK7WebCore5Frame15contentRendererEv
index 2d24d0a..82eb6ab 100644 (file)
                A81369D5097374F600D74463 /* HTMLFieldSetElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81369B9097374F500D74463 /* HTMLFieldSetElement.cpp */; };
                A81369D6097374F600D74463 /* HTMLTextAreaElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369BA097374F500D74463 /* HTMLTextAreaElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A81369D7097374F600D74463 /* HTMLTextAreaElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81369BB097374F500D74463 /* HTMLTextAreaElement.cpp */; };
-               A81369D8097374F600D74463 /* HTMLSelectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369BC097374F500D74463 /* HTMLSelectElement.h */; };
+               A81369D8097374F600D74463 /* HTMLSelectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369BC097374F500D74463 /* HTMLSelectElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A81369D9097374F600D74463 /* HTMLSelectElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81369BD097374F500D74463 /* HTMLSelectElement.cpp */; };
-               A81369DA097374F600D74463 /* HTMLOptionsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369BE097374F500D74463 /* HTMLOptionsCollection.h */; };
-               A81369DC097374F600D74463 /* HTMLOptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369C0097374F500D74463 /* HTMLOptionElement.h */; };
+               A81369DA097374F600D74463 /* HTMLOptionsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369BE097374F500D74463 /* HTMLOptionsCollection.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A81369DC097374F600D74463 /* HTMLOptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369C0097374F500D74463 /* HTMLOptionElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A81369DD097374F600D74463 /* HTMLOptionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81369C1097374F500D74463 /* HTMLOptionElement.cpp */; };
                A81369DE097374F600D74463 /* HTMLOptGroupElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369C2097374F500D74463 /* HTMLOptGroupElement.h */; };
                A81369DF097374F600D74463 /* HTMLOptGroupElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81369C3097374F500D74463 /* HTMLOptGroupElement.cpp */; };
                BC772E16133162C2001EC9CE /* CSSLineBoxContainValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772E15133162C2001EC9CE /* CSSLineBoxContainValue.cpp */; };
                BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F44A70B9E324E00A9D081 /* ImageObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC7FA6200D1F0CBD00DB22A9 /* DynamicNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA61E0D1F0CBD00DB22A9 /* DynamicNodeList.cpp */; };
-               BC7FA6210D1F0CBD00DB22A9 /* DynamicNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */; };
+               BC7FA6210D1F0CBD00DB22A9 /* DynamicNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC7FA62D0D1F0EFF00DB22A9 /* StaticNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA62B0D1F0EFF00DB22A9 /* StaticNodeList.h */; };
                BC7FA62E0D1F0EFF00DB22A9 /* StaticNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */; };
                BC80C9870CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC80C9850CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp */; };
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               BC7FA6210D1F0CBD00DB22A9 /* DynamicNodeList.h in Headers */,
+                               A81369DA097374F600D74463 /* HTMLOptionsCollection.h in Headers */,
+                               A81369D8097374F600D74463 /* HTMLSelectElement.h in Headers */,
+                               A81369DC097374F600D74463 /* HTMLOptionElement.h in Headers */,
                                97BC69DB1505F076001B74AC /* AbstractDatabase.h in Headers */,
                                41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */,
                                29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */,
                                3169379C14609C6C00C01362 /* DragSession.h in Headers */,
                                81F65FF613788FAA00FF6F2D /* DragState.h in Headers */,
                                498770DC1242C535002226BA /* DrawingBuffer.h in Headers */,
-                               BC7FA6210D1F0CBD00DB22A9 /* DynamicNodeList.h in Headers */,
                                FD6ED2C8136B8E66003CF072 /* DynamicsCompressor.h in Headers */,
                                FD537357137B653B00008DCE /* DynamicsCompressorKernel.h in Headers */,
                                FD6ED2C4136B8E42003CF072 /* DynamicsCompressorNode.h in Headers */,
                                A871D45A0A127CBC00B12A68 /* HTMLObjectElement.h in Headers */,
                                A8EA79F10A1916DF00A8EF5F /* HTMLOListElement.h in Headers */,
                                A81369DE097374F600D74463 /* HTMLOptGroupElement.h in Headers */,
-                               A81369DC097374F600D74463 /* HTMLOptionElement.h in Headers */,
-                               A81369DA097374F600D74463 /* HTMLOptionsCollection.h in Headers */,
                                4AD01009127E642A0015035F /* HTMLOutputElement.h in Headers */,
                                A8EA7CB50A192B9C00A8EF5F /* HTMLParagraphElement.h in Headers */,
                                A871D4580A127CBC00B12A68 /* HTMLParamElement.h in Headers */,
                                A871DC250A15205700B12A68 /* HTMLScriptElement.h in Headers */,
                                977B3875122883E900B81FF8 /* HTMLScriptRunner.h in Headers */,
                                977B3876122883E900B81FF8 /* HTMLScriptRunnerHost.h in Headers */,
-                               A81369D8097374F600D74463 /* HTMLSelectElement.h in Headers */,
                                4ABDFF0C14DBE385004D117D /* HTMLShadowElement.h in Headers */,
                                E44613A80CD6331000FADA75 /* HTMLSourceElement.h in Headers */,
                                977E2DCE12F0E28300C13379 /* HTMLSourceTracker.h in Headers */,
index ffa9e38..f639ffb 100644 (file)
@@ -1,3 +1,78 @@
+2012-10-31  Tim Horton  <timothy_horton@apple.com>
+
+        Full-page PDFPlugin should support inline form editing
+        https://bugs.webkit.org/show_bug.cgi?id=100155
+
+        Reviewed by Dan Bernstein.
+
+        Add form controls corresponding to Text and Choice PDF annotations,
+        allowing for single- and multi-line text input, and <select>-like input.
+
+        Currently, forms are only implemented for full-page PDF documents.
+
+        * Shared/mac/PDFKitImports.h:
+        (WebKit): Add pdfAnnotationTextWidgetClass and pdfAnnotationChoiceWidgetClass.
+        * Shared/mac/PDFKitImports.mm:
+        (WebKit::pdfAnnotationTextWidgetClass): Add pdfAnnotationTextWidgetClass.
+        (WebKit::pdfAnnotationChoiceWidgetClass): Add pdfAnnotationChoiceWidgetClass.
+        * WebKit2.xcodeproj/project.pbxproj: Add PDFLayerControllerDetails, PDFPluginTextAnnotation, PDFPluginChoiceAnnotation,
+        and PDFPluginAnnotation.
+        * WebProcess/Plugins/PDF/PDFLayerControllerDetails.h: Added. Extract PDFLayerController details category into a header.
+        * WebProcess/Plugins/PDF/PDFPlugin.h:
+        (PDFPlugin): Add m_activeAnnotation, to keep track of the active PDFPluginAnnotation, and m_annotationContainer,
+        the <div> that form controls are inserted into.
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (-[WKPDFLayerControllerDelegate pdfLayerController:didChangeActiveAnnotation:]): Forward active annotation changes to PDFPlugin.
+        (WebKit::PDFPlugin::PDFPlugin): Add a <div> to the PluginDocument <body>, which will contain <input>, <select>, and <textarea> elements
+        corresponding to the active annotation. This div is made to fit to the body, and is "overflow: hidden" so that form elements scrolled
+        out of the viewport do not cause the Document to expand to be larger than the Plugin.
+        (WebKit::PDFPlugin::pdfDocumentDidLoad): Update PDFPlugin's notion of the scroll position immediately after the document loads, in case
+        the scroll position is constrained by PDFKit.
+        (WebKit::PDFPlugin::destroy): Tear down any forms for the active annotation.
+        (WebKit::PDFPlugin::geometryDidChange): Notify the current annotation that it should update its geometry when the Plugin's geometry changes.
+        (WebKit::PDFPlugin::setScrollOffset): Notify the current annotation that it should update its geometry when we scroll.
+        (WebKit::PDFPlugin::setActiveAnnotation): Commit changes to the current annotation, if there is one, then make a new PDFPluginAnnotation
+        corresponding to the newly active annotation, and attach it to our document.
+        * WebProcess/Plugins/PDF/PDFPluginAnnotation.h: Added.
+        (WebKit::PDFPluginAnnotation::element): Return the Element corresponding to this object.
+        (WebKit::PDFPluginAnnotation::annotation): Return the PDFAnnotation corresponding to this object.
+        (WebKit::PDFPluginAnnotation::plugin): Return the Plugin that created this object.
+        (WebKit::PDFPluginAnnotation::commit): Commit changes from the form to the PDFAnnotation. This is implemented in subclasses.
+        (WebKit::PDFPluginAnnotation::attach): Attach a PDFPluginAnnotation to its parent Element.
+        (WebKit::PDFPluginAnnotation::parent): Return the parent Element that we're attach()ed to.
+        (WebKit::PDFPluginAnnotation::pdfLayerController): Return the pdfLayerController that the PDFAnnotation comes from.
+        (PDFPluginAnnotationEventListener): Add an event listener to respond to "change" and "blur" events from m_element.
+        * WebProcess/Plugins/PDF/PDFPluginAnnotation.mm: Added.
+        (WebKit::PDFPluginAnnotation::create): Create the appropriate PDFPluginAnnotation subclass (PDFPluginTextAnnotation or
+        PDFPluginChoiceAnnotation based on the class of the PDFAnnotation).
+        (WebKit::PDFPluginAnnotation::attach): Lazily create the HTML form element corresponding to this annotation. Add it to its parent
+        element. Add event listeners for "change" and "blur".
+        (WebKit::PDFPluginAnnotation::~PDFPluginAnnotation): Tear down the annotation, by removing event listeners and removing
+        the form element from its parent element.
+        (WebKit::PDFPluginAnnotation::updateGeometry): Update the size and position of the form element, given the current PDF scale and scrolling position.
+        (WebKit::PDFPluginAnnotation::PDFPluginAnnotationEventListener::handleEvent): If we get a blur or change event, we should remove the
+        form control to match the behavior of PDFKit.
+        * WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h: Added.
+        (WebKit::PDFPluginChoiceAnnotation::choiceAnnotation): Return annotation() with the appropriate cast.
+        * WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.mm: Added.
+        (WebKit::PDFPluginChoiceAnnotation::updateGeometry): Update the font size of the choice widget given the current PDF scale.
+        (WebKit::PDFPluginChoiceAnnotation::commit): Save the value of the currently selected <option> into the PDFAnnotationChoiceWidget.
+        (WebKit::PDFPluginChoiceAnnotation::createAnnotationElement): Create a <select> element, populated with <option> elements
+        for the PDFAnnotationChoiceWidget's available choices. Select the correct <option> initially.
+        * WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h: Added.
+        (WebKit::PDFPluginTextAnnotation::textAnnotation): Return annotation() with the appropriate cast.
+        * WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm: Added.
+        (WebKit::cssAlignmentValueForNSTextAlignment): Return the CSS alignment value for a given NSTextAlignment.
+        (WebKit::PDFPluginTextAnnotation::createAnnotationElement): Create a <textarea> or <input> element, depending on whether the
+        PDFAnnotationTextWidget supports multiline editing or not.
+        (WebKit::PDFPluginTextAnnotation::updateGeometry): Update the font size of the text widget given the current PDF scale.
+        (WebKit::PDFPluginTextAnnotation::commit): Save the current string in the form element into the PDFAnnotationTextWidget.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::focusedPluginViewForFrame): Return the PluginView for a Frame only if the Plugin's element is focused.
+        (WebKit::WebPage::executeEditingCommand): Only forward editing commands to PluginView if the plugin itself is focused.
+        (WebKit::WebPage::isEditingCommandEnabled): Ditto.
+        (WebKit::WebPage::validateCommand): Ditto.
+
 2012-10-30  Joseph Pecoraro  <pecoraro@apple.com>
 
         [Mac] Make WebKit2 Build with NETWORK_PROCESS disabled
index c9a1e0a..a1a13d3 100644 (file)
@@ -35,6 +35,8 @@ Class pdfDocumentClass();
 
 #if ENABLE(PDFKIT_PLUGIN)
 Class pdfLayerControllerClass();
+Class pdfAnnotationTextWidgetClass();
+Class pdfAnnotationChoiceWidgetClass();
 #endif
 
 }
index bccfbef..16697b4 100644 (file)
@@ -62,6 +62,20 @@ Class pdfLayerControllerClass()
     ASSERT(pdfLayerControllerClass);
     return pdfLayerControllerClass;
 }
+
+Class pdfAnnotationTextWidgetClass()
+{
+    static Class pdfAnnotationTextWidgetClass = classFromPDFKit(@"PDFAnnotationTextWidget");
+    ASSERT(pdfAnnotationTextWidgetClass);
+    return pdfAnnotationTextWidgetClass;
+}
+
+Class pdfAnnotationChoiceWidgetClass()
+{
+    static Class pdfAnnotationChoiceWidgetClass = classFromPDFKit(@"PDFAnnotationChoiceWidget");
+    ASSERT(pdfAnnotationChoiceWidgetClass);
+    return pdfAnnotationChoiceWidgetClass;
+}
 #endif
 
 }
index 3ee3993..d3fbb14 100644 (file)
                29CD55AB128E294F00133C85 /* WKAccessibilityWebPageObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29CD55A9128E294F00133C85 /* WKAccessibilityWebPageObject.mm */; };
                29D55DF1161BF9F10031A2E3 /* WebPageGroupProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29D55DEF161BF9F10031A2E3 /* WebPageGroupProxyMessageReceiver.cpp */; };
                29D55DF2161BF9F10031A2E3 /* WebPageGroupProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 29D55DF0161BF9F10031A2E3 /* WebPageGroupProxyMessages.h */; };
+               2D2ADF0916362DD500197E47 /* PDFPluginTextAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF0616362DC700197E47 /* PDFPluginTextAnnotation.mm */; };
+               2D2ADF0B16362DDB00197E47 /* PDFPluginAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF031636243500197E47 /* PDFPluginAnnotation.mm */; };
+               2D2ADF1016364D8200197E47 /* PDFPluginChoiceAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */; };
                2D870D1016234FFE000A3F20 /* PDFPlugin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D870D0E1622B7F9000A3F20 /* PDFPlugin.mm */; };
                31099973146C75A20029DEB9 /* WebNotificationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31099971146C759B0029DEB9 /* WebNotificationClient.cpp */; };
                310999C7146C9E3D0029DEB9 /* WebNotificationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 31099968146C71F50029DEB9 /* WebNotificationClient.h */; };
                29D55DEE161BF8780031A2E3 /* WebPageGroupProxy.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebPageGroupProxy.messages.in; sourceTree = "<group>"; };
                29D55DEF161BF9F10031A2E3 /* WebPageGroupProxyMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPageGroupProxyMessageReceiver.cpp; sourceTree = "<group>"; };
                29D55DF0161BF9F10031A2E3 /* WebPageGroupProxyMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageGroupProxyMessages.h; sourceTree = "<group>"; };
+               2D2ADF021636243500197E47 /* PDFPluginAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPluginAnnotation.h; path = PDF/PDFPluginAnnotation.h; sourceTree = "<group>"; };
+               2D2ADF031636243500197E47 /* PDFPluginAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginAnnotation.mm; path = PDF/PDFPluginAnnotation.mm; sourceTree = "<group>"; };
+               2D2ADF0516362DC700197E47 /* PDFPluginTextAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPluginTextAnnotation.h; path = PDF/PDFPluginTextAnnotation.h; sourceTree = "<group>"; };
+               2D2ADF0616362DC700197E47 /* PDFPluginTextAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginTextAnnotation.mm; path = PDF/PDFPluginTextAnnotation.mm; sourceTree = "<group>"; };
+               2D2ADF0C16363DEC00197E47 /* PDFLayerControllerDetails.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PDFLayerControllerDetails.h; path = PDF/PDFLayerControllerDetails.h; sourceTree = "<group>"; };
+               2D2ADF0D16364D8200197E47 /* PDFPluginChoiceAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPluginChoiceAnnotation.h; path = PDF/PDFPluginChoiceAnnotation.h; sourceTree = "<group>"; };
+               2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginChoiceAnnotation.mm; path = PDF/PDFPluginChoiceAnnotation.mm; sourceTree = "<group>"; };
                2D870D0D1622B7F9000A3F20 /* PDFPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPlugin.h; path = PDF/PDFPlugin.h; sourceTree = "<group>"; };
                2D870D0E1622B7F9000A3F20 /* PDFPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPlugin.mm; path = PDF/PDFPlugin.mm; sourceTree = "<group>"; };
                31099968146C71F50029DEB9 /* WebNotificationClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebNotificationClient.h; sourceTree = "<group>"; };
                E199875B142BF9CF00BB2DE7 /* PDF */ = {
                        isa = PBXGroup;
                        children = (
+                               2D2ADF0D16364D8200197E47 /* PDFPluginChoiceAnnotation.h */,
+                               2D2ADF0E16364D8200197E47 /* PDFPluginChoiceAnnotation.mm */,
+                               2D2ADF0C16363DEC00197E47 /* PDFLayerControllerDetails.h */,
+                               2D2ADF021636243500197E47 /* PDFPluginAnnotation.h */,
+                               2D2ADF031636243500197E47 /* PDFPluginAnnotation.mm */,
+                               2D2ADF0516362DC700197E47 /* PDFPluginTextAnnotation.h */,
+                               2D2ADF0616362DC700197E47 /* PDFPluginTextAnnotation.mm */,
                                2D870D0D1622B7F9000A3F20 /* PDFPlugin.h */,
                                2D870D0E1622B7F9000A3F20 /* PDFPlugin.mm */,
                                E199875C142BFC9700BB2DE7 /* SimplePDFPlugin.mm */,
                                517CF0DF163A444C00C2950E /* NetworkRequest.cpp in Sources */,
                                517CF0E3163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp in Sources */,
                                E1B78473163F253E0007B692 /* RemoteNetworkingContext.mm in Sources */,
+                               2D2ADF0916362DD500197E47 /* PDFPluginTextAnnotation.mm in Sources */,
+                               2D2ADF0B16362DDB00197E47 /* PDFPluginAnnotation.mm in Sources */,
+                               2D2ADF1016364D8200197E47 /* PDFPluginChoiceAnnotation.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerDetails.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerDetails.h
new file mode 100644 (file)
index 0000000..6e7b52a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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>
+
+@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)openWithPreview;
+- (void)saveToPDF;
+
+- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeActiveAnnotation:(PDFAnnotation *)annotation;
+
+@end
+
+@interface PDFLayerController : NSObject
+@end
+
+@interface PDFLayerController (Details)
+
+@property(retain) CALayer *parentLayer;
+@property(retain) PDFDocument *document;
+@property(retain) id<PDFLayerControllerDelegate> delegate;
+
+- (void)setFrameSize:(CGSize)size;
+
+- (void)setDisplayMode:(int)mode;
+- (void)setDisplaysPageBreaks:(BOOL)pageBreaks;
+
+- (CGFloat)tileScaleFactor;
+- (void)setTileScaleFactor:(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)mouseMoved:(NSEvent *)event;
+- (void)mouseUp:(NSEvent *)event;
+- (void)mouseDragged:(NSEvent *)event;
+- (void)mouseEntered:(NSEvent *)event;
+- (void)mouseExited:(NSEvent *)event;
+
+- (NSArray *)findString:(NSString *)string caseSensitive:(BOOL)isCaseSensitive highlightMatches:(BOOL)shouldHighlightMatches;
+
+- (id)currentSelection;
+- (void)copySelection;
+- (void)selectAll;
+
+- (bool)keyDown:(NSEvent *)event;
+
+- (void)setHUDEnabled:(BOOL)enabled;
+- (BOOL)hudEnabled;
+
+- (CGRect)boundsForAnnotation:(PDFAnnotation *)annotation;
+
+@end
index 49d0910..d3641b6 100644 (file)
@@ -38,15 +38,18 @@ typedef const struct OpaqueJSContext* JSContextRef;
 typedef struct OpaqueJSValue* JSObjectRef;
 typedef const struct OpaqueJSValue* JSValueRef;
 
+OBJC_CLASS PDFAnnotation;
 OBJC_CLASS PDFLayerController;
 OBJC_CLASS WKPDFLayerControllerDelegate;
 
 namespace WebCore {
+class Element;
 struct PluginInfo;
 }
 
 namespace WebKit {
 
+class PDFPluginAnnotation;
 class PluginView;
 class WebFrame;
 
@@ -56,6 +59,7 @@ public:
     ~PDFPlugin();
 
     void paintControlForLayerInContext(CALayer *, CGContextRef);
+    void setActiveAnnotation(PDFAnnotation *);
     
     using ScrollableArea::notifyScrollPositionChanged;
 
@@ -84,6 +88,8 @@ private:
     virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&) OVERRIDE;
     virtual void invalidateScrollCornerRect(const WebCore::IntRect&) OVERRIDE;
 
+    bool supportsForms();
+
     RetainPtr<CALayer> m_containerLayer;
     RetainPtr<CALayer> m_contentLayer;
     RetainPtr<CALayer> m_horizontalScrollbarLayer;
@@ -91,6 +97,9 @@ private:
     RetainPtr<CALayer> m_scrollCornerLayer;
     RetainPtr<PDFLayerController> m_pdfLayerController;
     
+    RefPtr<PDFPluginAnnotation> m_activeAnnotation;
+    RefPtr<WebCore::Element> m_annotationContainer;
+
     WebCore::AffineTransform m_rootViewToPluginTransform;
     WebCore::IntPoint m_lastMousePoint;
     
index b8e98b6..a55b669 100644 (file)
@@ -29,6 +29,8 @@
 #import "PDFPlugin.h"
 
 #import "PDFKitImports.h"
+#import "PDFLayerControllerDetails.h"
+#import "PDFPluginAnnotation.h"
 #import "PluginView.h"
 #import "ShareableBitmap.h"
 #import "WebEvent.h"
 #import <PDFKit/PDFKit.h>
 #import <QuartzCore/QuartzCore.h>
 #import <WebCore/ArchiveResource.h>
+#import <WebCore/CSSPrimitiveValue.h>
+#import <WebCore/CSSPropertyNames.h>
 #import <WebCore/Chrome.h>
 #import <WebCore/DocumentLoader.h>
 #import <WebCore/FocusController.h>
 #import <WebCore/Frame.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/GraphicsContext.h>
+#import <WebCore/HTMLElement.h>
 #import <WebCore/HTTPHeaderMap.h>
 #import <WebCore/LocalizedStrings.h>
 #import <WebCore/Page.h>
 #import <WebCore/ScrollAnimator.h>
 #import <WebCore/ScrollbarTheme.h>
 
-@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)openWithPreview;
-- (void)saveToPDF;
-
-@end
-
-@interface PDFLayerController : NSObject
-@end
-
-@interface PDFLayerController (Details)
-
-@property (retain) CALayer *parentLayer;
-@property (retain) PDFDocument *document;
-@property (retain) id<PDFLayerControllerDelegate> delegate;
-
-- (void)setFrameSize:(CGSize)size;
-
-- (void)setDisplayMode:(int)mode;
-- (void)setDisplaysPageBreaks:(BOOL)pageBreaks;
-
-- (CGFloat)tileScaleFactor;
-- (void)setTileScaleFactor:(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)mouseMoved:(NSEvent *)event;
-- (void)mouseUp:(NSEvent *)event;
-- (void)mouseDragged:(NSEvent *)event;
-- (void)mouseEntered:(NSEvent *)event;
-- (void)mouseExited:(NSEvent *)event;
-
-- (NSArray *)findString:(NSString *)string caseSensitive:(BOOL)isCaseSensitive highlightMatches:(BOOL)shouldHighlightMatches;
-
-- (id)currentSelection;
-- (void)copySelection;
-- (void)selectAll;
-
-- (bool)keyDown:(NSEvent *)event;
-
-- (void)setHUDEnabled:(BOOL)enabled;
-- (BOOL)hudEnabled;
-
-@end
-
 using namespace WebCore;
 
+// Set overflow: hidden on the annotation container so <input> elements scrolled out of view don't show
+// scrollbars on the body. We can't add annotations directly to the body, because overflow: hidden on the body
+// will break rubber-banding.
+static const char* annotationStyle = " \
+#annotationContainer { \
+    overflow: hidden; \
+    position: absolute; \
+    pointer-events: none; \
+    top: 0; \
+    left: 0; \
+    right: 0; \
+    bottom: 0; \
+} \
+.annotation { \
+    position: absolute; \
+    pointer-events: auto; \
+} \
+textarea.annotation { \
+    resize: none; \
+}";
+
 @interface WKPDFPluginScrollbarLayer : CALayer
 {
     WebKit::PDFPlugin* _pdfPlugin;
 }
 
-@property (assign) WebKit::PDFPlugin* pdfPlugin;
+@property(assign) WebKit::PDFPlugin* pdfPlugin;
 
 @end
 
@@ -152,7 +119,7 @@ using namespace WebCore;
     WebKit::PDFPlugin* _pdfPlugin;
 }
 
-@property (assign) WebKit::PDFPlugin* pdfPlugin;
+@property(assign) WebKit::PDFPlugin* pdfPlugin;
 
 @end
 
@@ -208,10 +175,17 @@ using namespace WebCore;
     // FIXME: Implement.
 }
 
+- (void)pdfLayerController:(PDFLayerController *)pdfLayerController didChangeActiveAnnotation:(PDFAnnotation *)annotation
+{
+    _pdfPlugin->setActiveAnnotation(annotation);
+}
+
 @end
 
 namespace WebKit {
 
+using namespace HTMLNames;
+
 PassRefPtr<PDFPlugin> PDFPlugin::create(WebFrame* frame)
 {
     return adoptRef(new PDFPlugin(frame));
@@ -227,7 +201,19 @@ PDFPlugin::PDFPlugin(WebFrame* frame)
 {
     m_pdfLayerController.get().delegate = m_pdfLayerControllerDelegate.get();
     m_pdfLayerController.get().parentLayer = m_contentLayer.get();
-    
+
+    if (supportsForms()) {
+        Document* document = webFrame()->coreFrame()->document();
+        m_annotationContainer = document->createElement(divTag, false);
+        m_annotationContainer->setAttribute(idAttr, "annotationContainer");
+
+        RefPtr<Element> m_annotationStyle = document->createElement(styleTag, false);
+        m_annotationStyle->setTextContent(annotationStyle, ASSERT_NO_EXCEPTION);
+
+        m_annotationContainer->appendChild(m_annotationStyle.get());
+        document->body()->appendChild(m_annotationContainer.get());
+    }
+
     [m_containerLayer.get() addSublayer:m_contentLayer.get()];
     [m_containerLayer.get() addSublayer:m_scrollCornerLayer.get()];
 }
@@ -301,6 +287,8 @@ void PDFPlugin::pdfDocumentDidLoad()
     if (handlesPageScaleFactor())
         pluginView()->setPageScaleFactor([m_pdfLayerController.get() tileScaleFactor], IntPoint());
 
+    notifyScrollPositionChanged(IntPoint([m_pdfLayerController.get() scrollPosition]));
+
     calculateSizes();
     updateScrollbars();
 
@@ -326,6 +314,9 @@ void PDFPlugin::destroy()
             frameView->removeScrollableArea(this);
     }
 
+    m_activeAnnotation = 0;
+    m_annotationContainer = 0;
+
     destroyScrollbar(HorizontalScrollbar);
     destroyScrollbar(VerticalScrollbar);
     
@@ -411,11 +402,14 @@ void PDFPlugin::geometryDidChange(const IntSize& pluginSize, const IntRect&, con
             [m_pdfLayerController.get() magnifyWithMagnification:magnification atPoint:m_lastMousePoint immediately:YES];
     }
 
-    [m_contentLayer.get() setSublayerTransform:transform];
-    [CATransaction commit];
-
     calculateSizes();
     updateScrollbars();
+
+    if (m_activeAnnotation)
+        m_activeAnnotation->updateGeometry();
+
+    [m_contentLayer.get() setSublayerTransform:transform];
+    [CATransaction commit];
 }
     
 static NSUInteger modifierFlagsFromWebEvent(const WebEvent& event)
@@ -567,7 +561,14 @@ bool PDFPlugin::isEditingCommandEnabled(const String& commandName)
 void PDFPlugin::setScrollOffset(const IntPoint& offset)
 {
     SimplePDFPlugin::setScrollOffset(offset);
+
+    [CATransaction begin];
     [m_pdfLayerController.get() setScrollPosition:offset];
+
+    if (m_activeAnnotation)
+        m_activeAnnotation->updateGeometry();
+
+    [CATransaction commit];
 }
 
 void PDFPlugin::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
@@ -588,6 +589,27 @@ bool PDFPlugin::handlesPageScaleFactor()
     return webFrame()->isMainFrame();
 }
 
+void PDFPlugin::setActiveAnnotation(PDFAnnotation *annotation)
+{
+    if (!supportsForms())
+        return;
+
+    if (m_activeAnnotation)
+        m_activeAnnotation->commit();
+
+    if (annotation) {
+        m_activeAnnotation = PDFPluginAnnotation::create(annotation, m_pdfLayerController.get(), this);
+        m_activeAnnotation->attach(m_annotationContainer.get());
+    } else
+        m_activeAnnotation = 0;
+}
+
+bool PDFPlugin::supportsForms()
+{
+    // FIXME: Should we support forms for inline PDFs? Since we touch the document, this might be difficult.
+    return webFrame()->isMainFrame();
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(PDFKIT_PLUGIN)
diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h
new file mode 100644 (file)
index 0000000..d6e3ee6
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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() = 0;
+
+    void attach(WebCore::Element*);
+
+protected:
+    PDFPluginAnnotation(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin)
+        : 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; }
+
+private:
+    virtual PassRefPtr<WebCore::Element> createAnnotationElement() = 0;
+
+    class PDFPluginAnnotationEventListener : public WebCore::EventListener {
+    public:
+        static PassRefPtr<PDFPluginAnnotationEventListener> create(PDFPluginAnnotation* annotation)
+        {
+            return adoptRef(new PDFPluginAnnotationEventListener(annotation));
+        }
+
+        virtual bool operator==(const EventListener& listener) OVERRIDE { return this == &listener; }
+
+    private:
+
+        PDFPluginAnnotationEventListener(PDFPluginAnnotation* annotation)
+            : WebCore::EventListener(WebCore::EventListener::CPPEventListenerType)
+            , m_annotation(annotation)
+        {
+        }
+
+        virtual 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/PDFPluginAnnotation.mm b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm
new file mode 100644 (file)
index 0000000..2bfb6cb
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#if ENABLE(PDFKIT_PLUGIN)
+
+#import "config.h"
+#import "PDFPluginAnnotation.h"
+
+#import "PDFKitImports.h"
+#import <PDFKit/PDFKit.h>
+#import "PDFLayerControllerDetails.h"
+#import "PDFPlugin.h"
+#import "PDFPluginChoiceAnnotation.h"
+#import "PDFPluginTextAnnotation.h"
+#import <WebCore/ColorMac.h>
+#import <WebCore/CSSPrimitiveValue.h>
+#import <WebCore/CSSPropertyNames.h>
+#import <WebCore/HTMLElement.h>
+#import <WebCore/HTMLInputElement.h>
+#import <WebCore/HTMLNames.h>
+#import <WebCore/HTMLOptionElement.h>
+#import <WebCore/HTMLSelectElement.h>
+#import <WebCore/HTMLTextAreaElement.h>
+#import <WebCore/Page.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+using namespace HTMLNames;
+
+PassRefPtr<PDFPluginAnnotation> PDFPluginAnnotation::create(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin)
+{
+    if ([annotation isKindOfClass:pdfAnnotationTextWidgetClass()])
+        return PDFPluginTextAnnotation::create(annotation, pdfLayerController, plugin);
+    if ([annotation isKindOfClass:pdfAnnotationChoiceWidgetClass()])
+        return PDFPluginChoiceAnnotation::create(annotation, pdfLayerController, plugin);
+
+    return 0;
+}
+
+void PDFPluginAnnotation::attach(Element* parent)
+{
+    ASSERT(!m_parent);
+
+    m_parent = parent;
+    m_element = createAnnotationElement();
+
+    m_element->setAttribute(classAttr, "annotation");
+    m_element->addEventListener("change", m_eventListener, false);
+    m_element->addEventListener("blur", m_eventListener, false);
+
+    updateGeometry();
+
+    m_parent->appendChild(m_element);
+
+    // FIXME: The text cursor doesn't blink after this. Why?
+    m_element->focus();
+}
+
+PDFPluginAnnotation::~PDFPluginAnnotation()
+{
+    m_element->removeEventListener(eventNames().changeEvent, m_eventListener.get(), false);
+    m_element->removeEventListener(eventNames().blurEvent, m_eventListener.get(), false);
+
+    m_parent->removeChild(element());
+}
+
+void PDFPluginAnnotation::updateGeometry()
+{
+    IntSize documentSize(m_pdfLayerController.contentSizeRespectingZoom);
+    IntPoint scrollPosition(m_pdfLayerController.scrollPosition);
+    NSRect annotationRect = [m_pdfLayerController boundsForAnnotation:m_annotation.get()];
+
+    StyledElement* styledElement = static_cast<StyledElement*>(element());
+    styledElement->setInlineStyleProperty(CSSPropertyWidth, annotationRect.size.width, CSSPrimitiveValue::CSS_PX);
+    styledElement->setInlineStyleProperty(CSSPropertyHeight, annotationRect.size.height, CSSPrimitiveValue::CSS_PX);
+    styledElement->setInlineStyleProperty(CSSPropertyLeft, annotationRect.origin.x - scrollPosition.x(), CSSPrimitiveValue::CSS_PX);
+    styledElement->setInlineStyleProperty(CSSPropertyTop, documentSize.height() - annotationRect.origin.y - annotationRect.size.height - scrollPosition.y(), CSSPrimitiveValue::CSS_PX);
+}
+
+void PDFPluginAnnotation::PDFPluginAnnotationEventListener::handleEvent(ScriptExecutionContext*, Event* event)
+{
+    if (event->type() == eventNames().blurEvent || event->type() == eventNames().changeEvent)
+        m_annotation->plugin()->setActiveAnnotation(0);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PDFKIT_PLUGIN)
diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.h
new file mode 100644 (file)
index 0000000..ea0e830
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 PassRefPtr<PDFPluginChoiceAnnotation> create(PDFAnnotation *, PDFLayerController *, PDFPlugin*);
+
+    virtual void updateGeometry() OVERRIDE;
+    virtual void commit() OVERRIDE;
+
+private:
+    PDFPluginChoiceAnnotation(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin)
+        : PDFPluginAnnotation(annotation, pdfLayerController, plugin)
+    {
+    }
+
+    virtual PassRefPtr<WebCore::Element> createAnnotationElement() OVERRIDE;
+
+    PDFAnnotationChoiceWidget *choiceAnnotation() { return static_cast<PDFAnnotationChoiceWidget *>(annotation()); }
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(PDFKIT_PLUGIN)
+
+#endif // PDFPluginChoiceAnnotation_h
diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.mm b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.mm
new file mode 100644 (file)
index 0000000..fe99696
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#if ENABLE(PDFKIT_PLUGIN)
+
+#import "config.h"
+#import "PDFPluginChoiceAnnotation.h"
+
+#import "PDFKitImports.h"
+#import "PDFLayerControllerDetails.h"
+#import <PDFKit/PDFKit.h>
+#import <WebCore/CSSPrimitiveValue.h>
+#import <WebCore/CSSPropertyNames.h>
+#import <WebCore/ColorMac.h>
+#import <WebCore/HTMLElement.h>
+#import <WebCore/HTMLNames.h>
+#import <WebCore/HTMLOptionElement.h>
+#import <WebCore/HTMLSelectElement.h>
+#import <WebCore/Page.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+using namespace HTMLNames;
+
+PassRefPtr<PDFPluginChoiceAnnotation> PDFPluginChoiceAnnotation::create(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin)
+{
+    return adoptRef(new PDFPluginChoiceAnnotation(annotation, pdfLayerController, plugin));
+}
+
+void PDFPluginChoiceAnnotation::updateGeometry()
+{
+    PDFPluginAnnotation::updateGeometry();
+
+    StyledElement* styledElement = static_cast<StyledElement*>(element());
+    styledElement->setInlineStyleProperty(CSSPropertyFontSize, choiceAnnotation().font.pointSize * pdfLayerController().tileScaleFactor, CSSPrimitiveValue::CSS_PX);
+}
+
+void PDFPluginChoiceAnnotation::commit()
+{
+    choiceAnnotation().stringValue = static_cast<HTMLSelectElement*>(element())->value();
+}
+
+PassRefPtr<Element> PDFPluginChoiceAnnotation::createAnnotationElement()
+{
+    Document* document = parent()->ownerDocument();
+    PDFAnnotationChoiceWidget *choiceAnnotation = this->choiceAnnotation();
+
+    RefPtr<Element> element = document->createElement(selectTag, false);
+
+    StyledElement* styledElement = static_cast<StyledElement*>(element.get());
+
+    // FIXME: Match font weight and style as well?
+    styledElement->setInlineStyleProperty(CSSPropertyColor, colorFromNSColor(choiceAnnotation.fontColor).serialized());
+    styledElement->setInlineStyleProperty(CSSPropertyFontFamily, choiceAnnotation.font.familyName);
+
+    NSArray *choices = choiceAnnotation.choices;
+    NSString *selectedChoice = choiceAnnotation.stringValue;
+
+    for (NSString *choice in choices) {
+        RefPtr<Element> choiceOption = document->createElement(optionTag, false);
+        choiceOption->setAttribute(valueAttr, choice);
+        choiceOption->setTextContent(choice, ASSERT_NO_EXCEPTION);
+
+        if (choice == selectedChoice)
+            choiceOption->setAttribute(selectedAttr, "selected");
+
+        styledElement->appendChild(choiceOption);
+    }
+
+    return element;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PDFKIT_PLUGIN)
diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.h
new file mode 100644 (file)
index 0000000..626628e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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"
+
+namespace WebCore {
+class Element;
+}
+
+OBJC_CLASS PDFAnnotationTextWidget;
+
+namespace WebKit {
+
+class PDFPluginTextAnnotation : public PDFPluginAnnotation {
+public:
+    static PassRefPtr<PDFPluginTextAnnotation> create(PDFAnnotation *, PDFLayerController *, PDFPlugin*);
+
+    virtual void updateGeometry() OVERRIDE;
+    virtual void commit() OVERRIDE;
+
+private:
+    PDFPluginTextAnnotation(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin)
+        : PDFPluginAnnotation(annotation, pdfLayerController, plugin)
+    {
+    }
+
+    virtual PassRefPtr<WebCore::Element> createAnnotationElement() OVERRIDE;
+
+    PDFAnnotationTextWidget * textAnnotation() { return static_cast<PDFAnnotationTextWidget *>(annotation()); }
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(PDFKIT_PLUGIN)
+
+#endif // PDFPluginTextAnnotation_h
diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm
new file mode 100644 (file)
index 0000000..95e2d35
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+#if ENABLE(PDFKIT_PLUGIN)
+
+#import "config.h"
+#import "PDFPluginTextAnnotation.h"
+
+#import "PDFKitImports.h"
+#import <PDFKit/PDFKit.h>
+#import "PDFLayerControllerDetails.h"
+#import <WebCore/ColorMac.h>
+#import <WebCore/CSSPrimitiveValue.h>
+#import <WebCore/CSSPropertyNames.h>
+#import <WebCore/HTMLElement.h>
+#import <WebCore/HTMLInputElement.h>
+#import <WebCore/HTMLNames.h>
+#import <WebCore/HTMLTextAreaElement.h>
+#import <WebCore/Page.h>
+
+@interface PDFAnnotationTextWidget (Details)
+- (BOOL)isMultiline;
+@end
+
+using namespace WebCore;
+
+namespace WebKit {
+
+using namespace HTMLNames;
+
+static const String cssAlignmentValueForNSTextAlignment(NSTextAlignment alignment)
+{
+    switch (alignment) {
+    case NSLeftTextAlignment:
+        return "left";
+    case NSRightTextAlignment:
+        return "right";
+    case NSCenterTextAlignment:
+        return "center";
+    case NSJustifiedTextAlignment:
+        return "justify";
+    case NSNaturalTextAlignment:
+        return "-webkit-start";
+    }
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+PassRefPtr<PDFPluginTextAnnotation> PDFPluginTextAnnotation::create(PDFAnnotation *annotation, PDFLayerController *pdfLayerController, PDFPlugin* plugin)
+{
+    return adoptRef(new PDFPluginTextAnnotation(annotation, pdfLayerController, plugin));
+}
+
+PassRefPtr<Element> PDFPluginTextAnnotation::createAnnotationElement()
+{
+    RefPtr<Element> element;
+
+    Document* document = parent()->ownerDocument();
+    PDFAnnotationTextWidget *textAnnotation = this->textAnnotation();
+    bool isMultiline = textAnnotation.isMultiline;
+
+    if (isMultiline)
+        element = document->createElement(textareaTag, false);
+    else
+        element = document->createElement(inputTag, false);
+
+    StyledElement* styledElement = static_cast<StyledElement*>(element.get());
+
+    // FIXME: Match font weight and style as well?
+    styledElement->setInlineStyleProperty(CSSPropertyColor, colorFromNSColor(textAnnotation.fontColor).serialized());
+    styledElement->setInlineStyleProperty(CSSPropertyFontFamily, textAnnotation.font.familyName);
+    styledElement->setInlineStyleProperty(CSSPropertyTextAlign, cssAlignmentValueForNSTextAlignment(textAnnotation.alignment));
+
+    if (isMultiline)
+        static_cast<HTMLTextAreaElement*>(styledElement)->setValue(textAnnotation.stringValue);
+    else
+        static_cast<HTMLInputElement*>(styledElement)->setValue(textAnnotation.stringValue);
+
+    return element;
+}
+
+void PDFPluginTextAnnotation::updateGeometry()
+{
+    PDFPluginAnnotation::updateGeometry();
+
+    StyledElement* styledElement = static_cast<StyledElement*>(element());
+    styledElement->setInlineStyleProperty(CSSPropertyFontSize, textAnnotation().font.pointSize * pdfLayerController().tileScaleFactor, CSSPrimitiveValue::CSS_PX);
+}
+
+void PDFPluginTextAnnotation::commit()
+{
+    PDFAnnotationTextWidget *textAnnotation = this->textAnnotation();
+
+    if (textAnnotation.isMultiline)
+        textAnnotation.stringValue = static_cast<HTMLTextAreaElement*>(element())->value();
+    else
+        textAnnotation.stringValue = static_cast<HTMLInputElement*>(element())->value();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PDFKIT_PLUGIN)
index 78cbaee..b1ee358 100644 (file)
@@ -666,6 +666,20 @@ PassRefPtr<ImmutableArray> WebPage::trackedRepaintRects()
     return ImmutableArray::adopt(vector);
 }
 
+static PluginView* focusedPluginViewForFrame(Frame* frame)
+{
+    if (!frame->document()->isPluginDocument())
+        return 0;
+
+    PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document());
+
+    if (pluginDocument->focusedNode() != pluginDocument->pluginNode())
+        return 0;
+
+    PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
+    return pluginView;
+}
+
 static PluginView* pluginViewForFrame(Frame* frame)
 {
     if (!frame->document()->isPluginDocument())
@@ -682,7 +696,7 @@ void WebPage::executeEditingCommand(const String& commandName, const String& arg
     if (!frame)
         return;
 
-    if (PluginView* pluginView = pluginViewForFrame(frame)) {
+    if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
         pluginView->handleEditingCommand(commandName, argument);
         return;
     }
@@ -696,7 +710,7 @@ bool WebPage::isEditingCommandEnabled(const String& commandName)
     if (!frame)
         return false;
 
-    if (PluginView* pluginView = pluginViewForFrame(frame))
+    if (PluginView* pluginView = focusedPluginViewForFrame(frame))
         return pluginView->isEditingCommandEnabled(commandName);
     
     Editor::Command command = frame->editor()->command(commandName);
@@ -1598,7 +1612,7 @@ void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
     int32_t state = 0;
     Frame* frame = m_page->focusController()->focusedOrMainFrame();
     if (frame) {
-        if (PluginView* pluginView = pluginViewForFrame(frame))
+        if (PluginView* pluginView = focusedPluginViewForFrame(frame))
             isEnabled = pluginView->isEditingCommandEnabled(commandName);
         else {
             Editor::Command command = frame->editor()->command(commandName);