title: WebKit on 10.8: How to programmatically set the value of an input[type=file] field?
body: <p><strong>Setup</strong>:<br></p>
  
  <ul>
  <li>Mac OS X  10.8.2<br/></li>
  <li>Normal Cocoa app which links against OS-provided version of WebKit framework. Specifically, the contents of: <code>/System/Library/Frameworks/WebKit.framework/Versions/A/Resources/version.plist</code> are:</li>
  </ul>
  
  <pre>
      &lt;plist version="1.0">
      &lt;dict>
          &lt;key>BuildVersion&lt;/key>
          &lt;string>5&lt;/string>
          &lt;key>CFBundleShortVersionString&lt;/key>
          &lt;string>8536&lt;/string>
          &lt;key>CFBundleVersion&lt;/key>
          &lt;string>8536.26.14&lt;/string>
          &lt;key>ProjectName&lt;/key>
          &lt;string>WebKit&lt;/string>
          &lt;key>SourceVersion&lt;/key>
          &lt;string>7536026014000000&lt;/string>
      &lt;/dict>
      &lt;/plist>
  </pre>
  
  <hr>
  
  <p>I have a WebKit-based Cocoa app which loads an HTML document containing a normal HTML form in a WebView. The HTML form contains a file chooser input field like this:</p>
  
  <pre><code>&lt;form name="foo"&gt;
      &lt;input type="file" name="bar"&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>I'd like to set the value of this file chooser programmatically (from Objective-C if possible, but I'll do whatever works).</p>
  
  <p>As far as I can tell, this method has never worked:</p>
  
  <pre><code>DOMHTMLInputElement *inputEl = ... // fetch input element
  [inputEl setValue:@"some/file.txt"];
  </code></pre>
  
  <p>I assume there is some security restriction/policy in WebKit which prevents this from working. I assume this is an intentional security feature in WebKit, not a bug.</p>
  
  <hr>
  
  <p>However, in OS X 10.7 Lion, I <strong>was</strong> able to work around this restriction with a bit of a hack.</p>
  
  <p>In Lion, you could programmatically <strong>click</strong> the <code>input</code> element:</p>
  
  <pre><code>#pragma mark -
  #pragma mark WebFrameLoadDelegate
  
  - (void)webView:(WebView *)wv didFinishLoadForFrame:(WebFrame *)frame {
      if (frame != [wv mainFrame]) return;
  
      DOMAbstractView *win = (id)[frame windowObject];
      DOMDocument *doc = [win document];
      DOMHTMLFormElement *formEl = (id)[[doc forms] namedItem:@"foo"];
      DOMHTMLInputElement *inputEl = (id)[[formEl elements] namedItem:@"bar"];
      [inputEl click];
  }
  </code></pre>
  
  <p>Which would produce a call to <code>-[WebUIDelegate webView:runOpenPanelForFileButtonWithResultListener:]</code>. Then, you could implement that delegate method to programmatically set the value of the result listener immediately:</p>
  
  <pre><code>#pragma mark -
  #pragma mark WebUIDelegate
  
  - (void)webView:(WebView *)wv runOpenPanelForFileButtonWithResultListener:(id&lt;WebOpenPanelResultListener&gt;)listener {
      [listener chooseFilename:@"some/file.txt"];
  }
  </code></pre>
  
  <p>Although this was an ugly hack, it worked perfectly. It had the desired effect of immedately setting the value of the file upload <code>input</code> element. No "open panel" would appear on screen.</p>
  
  <hr>
  
  <p>I'm afraid WebKit has stopped allowing this in the version which shipped with 10.8. The part that has changed is:</p>
  
  <pre><code>[inputEl click];
  </code></pre>
  
  <p>This no longer produces a click event on the element in the WebKit shipping with 10.8. </p>
  
  <p>I have tried other methods of clicking which worked on 10.7, but no longer work on 10.8:</p>
  
  <pre><code>DOMUIEvent *evt = (id)[doc createEvent:@"UIEvents"];
  [evt initUIEvent:@"click" canBubble:YES cancelable:YES view:win detail:1];
  [inputEl dispatchEvent:evt];
  </code></pre>
  
  <p>These methods worked in 10.7, but none work in 10.8. </p>
  
  <hr>
  
  <p><strong>So</strong>, Is there any way to programmatically set the value of this file chooser in 10.8? </p>
  
  <p><strong>NOTE</strong>: I <strong>DO NOT</strong> want to ship a custom version of WebKit with my app. Other than that, I'm open to any suggestion (ObjC or JS or whatever).</p>
  
  <p>How can you programmatically set the value of a file chooser in WebKit which ships with 10.8?</p>
  
  <p>I have an example test project (reduced test case) available for your convenience here: <a href="http://tod.nu/FileUploadTest.zip" rel="nofollow">http://tod.nu/FileUploadTest.zip</a></p>