Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save zw/901883 to your computer and use it in GitHub Desktop.
Save zw/901883 to your computer and use it in GitHub Desktop.
Patch to r102 of http://code.google.com/p/firefox-mac-pdf to support http://example.com/my.pdf#page=123 (with a failed attempt to respond to subsequent fragment edits)
Index: prebuilt/extension/components/PDFService.js
===================================================================
--- prebuilt/extension/components/PDFService.js (revision 102)
+++ prebuilt/extension/components/PDFService.js (working copy)
@@ -145,6 +145,9 @@
chromeWindow.goDoCommand = createGoDoCommand(chromeWindow, chromeWindow.goDoCommand);
+ // "hash" == RFC 3986 section 3.5 fragment.
+ window.onhashchange = createScrollToNewFragment(chromeWindow, window.onhashchange);
+
chromeWindow.edu_mit_sgross_pdfplugin_swizzled = true;
}
},
@@ -281,6 +284,18 @@
}
}
+function createScrollToNewFragment(chromeWindow, orig) {
+ // "hash" == RFC 3986 section 3.5 fragment.
+ return function(hashChangeEvent) {
+ var plugin = getPluginShim(chromeWindow);
+ if (plugin) {
+ plugin.ScrollToNewFragment(hashChangeEvent.newURL);
+ } else {
+ orig.call(this, hashChangeEvent);
+ }
+ }
+}
+
function createGoDoCommand(chromeWindow, orig) {
return function(cmd) {
var plugin;
Index: src/PDFPluginShim.mm
===================================================================
--- src/PDFPluginShim.mm (revision 102)
+++ src/PDFPluginShim.mm (working copy)
@@ -72,6 +72,17 @@
return NS_OK;
}
+/* void ScrollToNewFragment (in ACString newURI); */
+NS_IMETHODIMP PDFPluginShim::ScrollToNewFragment(const nsACString & newURI)
+{
+ const char* data; // not null terminated
+ PRUint32 len = NS_CStringGetData(newURI, &data);
+ NSString* newURINS = [NSString stringWithCString:data length:len];
+
+ [_plugin scrollToNewFragment:newURINS];
+ return NS_OK;
+}
+
/* void Zoom (in long arg); */
NS_IMETHODIMP PDFPluginShim::Zoom(PRInt32 arg)
{
Index: src/PluginInstance.mm
===================================================================
--- src/PluginInstance.mm (revision 102)
+++ src/PluginInstance.mm (working copy)
@@ -185,8 +185,57 @@
PDFDocument* document = [[[PDFDocument alloc] initWithData:pdfData] autorelease];
[document setDelegate:self];
[pdfView setDocument:document];
+ [self scrollToNewFragment:_url];
}
+- (void)scrollToNewFragment:(NSString*)newURI
+{
+ // Reference for fragment syntax is:
+ // http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf
+ // There's also the less featureful but slightly more standard RFC:
+ // http://tools.ietf.org/html/rfc3778#section-3
+ // FIXME: support more general URI (without authority part) as well as URL.
+ NSString *fragment = [[NSURL URLWithString:newURI] fragment];
+
+ // I *think* complete removal of a fragment has a larger-scale effect than
+ // just an onHashChange, so we don't need to skip to the top like hacking the
+ // fragment off an HTML page does.
+ if (fragment == nil) {
+ return;
+ }
+ NSArray *parameterList = [fragment componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"#&"]];
+ for (NSString *parameter in parameterList) {
+ NSArray *nameValuePair = [parameter componentsSeparatedByString:@"="];
+ if ([nameValuePair count] != 2) {
+ continue;
+ }
+ NSString *name = [nameValuePair objectAtIndex:0];
+ NSString *value = [nameValuePair objectAtIndex:1];
+
+ PDFDocument* document = [pdfView document];
+
+ // Only support page numbers at the moment (no nameddest etc).
+ if ([name isEqualToString:@"page"]) {
+ // PDFOpenParameters says "Specifies a numbered page in the document,
+ // using an integer value. The document\u2019s first page has a pagenum
+ // value of 1." PDFView indices are zero-based.
+ //
+ // It'd be nice if the standard supported more abstraction --
+ // "#pagelabel=X" (or "#folio=X") -- to eliminate mental arithmetic when
+ // linking to front matter (e.g. "xi") or pages in the main text that are
+ // more than just integers (e.g. "2-1").
+ @try {
+ NSUInteger targetPageIndex = (NSUInteger)[value integerValue] - 1;
+ [pdfView goToPage:[document pageAtIndex:targetPageIndex]];
+ } @catch (NSException *exception) {
+ // Ignore malformed page number.
+ }
+ }
+ // Another useful abstraction might be "#annotation=box1". Perhaps
+ // annotations could be included when '#search="term"' gets implemented?
+ }
+}
+
- (void)_applyDefaults
{
bool autoScales = [Preferences getBoolPreference:"autoScales"];
Index: src/PluginInstance.h
===================================================================
--- src/PluginInstance.h (revision 102)
+++ src/PluginInstance.h (working copy)
@@ -57,6 +57,7 @@
- (void)findPrevious;
- (void)save;
- (void)setData:(NSData*)data;
+- (void)scrollToNewFragment:(NSString*)newURI;
- (void)setUrl:(NSString*)url;
- (void)setVisible:(bool)visible;
//- (void)loadURL:(NSString*)url;
Index: idl/PDFPlugin.idl
===================================================================
--- idl/PDFPlugin.idl (revision 102)
+++ idl/PDFPlugin.idl (working copy)
@@ -8,4 +8,5 @@
void FindAll( in ACString str, in boolean caseSensitive );
void RemoveHighlights();
void Zoom( in long arg );
+ void ScrollToNewFragment( in ACString newURI );
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment