I pointed out the following problem in #820770: iFrame Theme not sticking on form submissions:
Of course now I have a new problem: the search result links are not FB-ized, they send the user to the site. This happens on the drupalforfacebook.org site as well:
- Go to http://apps.facebook.com/drupalforfacebook/node/2000
- Search for something on the small search form (not the one up top).
- Results are returned in the canvas page.
- Click on any link and you go to the drupalforfacebook.org site instead of staying in the canvas page.

To which Dave responded:
Thanks for pointing out the links presented by search results. I consider this another problem. (Probably a bug in fb_canvas_process(). I think that is the function adding target=_top to those links, but failing to make the links start with apps.facebook.com/....)

This got me to do some investigating and figured since we both considered this a problem that a new issue was in order.

After looking at the fb_canvas_process() function the relative bit of code to this issue is this:

   elseif (fb_canvas_is_iframe()) {
      // Add target=_top so that entire pages do not appear within an iframe.
      // TODO: make these pattern replacements more sophisticated, detect whether target is already set.
      if (isset($options['add_target']) && $options['add_target']) {
        // Add target=_top to all links
        $patterns[] = "|<a ([^>]*)href=\"|";
        $replacements[] = "<a $1 target=\"_top\" href=\"";
        // Do not change local forms, but do change external ones
        $patterns[] = "|<form([^>]*)action=\"([^:\"]*):|";
        $replacements[] = "<form target=\"_top\" $1 action=\"$2:";
        
        // Make internal links point to canvas pages
        $patterns[] = "|<a([^>]*)href=\"{$base}|";
        $replacements[] = "<a $1 href=\"http://apps.facebook.com/{$_fb_app->canvas}/";
      }
      else {
        // Add target=_top to only external links
        $patterns[] = "|<a([^>]*)href=\"([^:\"]*):|";
        $replacements[] = "<a target=\"_top\" $1 href=\"$2:";
        $patterns[] = "|<form([^>]*)action=\"([^:\"]*):|";
        $replacements[] = "<form target=\"_top\" $1 action=\"$2:";
      }
      
    }

The problem arises because the search results by default return full-fledged URLs (http://...) which fb_canvas_process() doesn't see as a form or an internal link so it's just adds the 'target=\"_top\"' as expected.

The two approaches I can see to this is to either add additional code to fb_canvas_process() to look for full URLs that go to the Drupal site and modify them to go to the app.facebook.com/... style link or to write a custom theming function for search results that makes the internal links internal URLs.

I'm thinking adding additional code to fb_canvas_process() to process full URLs might have the additional benefit of solving some of the other problems of links breaking out of the FB chrome. I could be wrong.

I have tried adding this code:

        // Make internal links point to canvas pages
        $patterns[] = "|<a([^>]*)href=\"{$base}|";
        $replacements[] = "<a $1 href=\"http://apps.facebook.com/{$_fb_app->canvas}/";

right after this code:

        // Make internal links point to canvas pages
        $patterns[] = "|<a([^>]*)href=\"{$base}|";
        $replacements[] = "<a $1 href=\"http://apps.facebook.com/{$_fb_app->canvas}/";

and that seems to do the trick for me.

Now I don't know the full implications of this change and this would need testing and such. I also need to learn how to turn it into a patch file...

CommentFileSizeAuthor
#2 fb_canvas.module.patch677 bytesironsizide

Comments

ironsizide’s picture

*sigh* the code I added *should* read:

        // Make external links to site point to canvas pages
        $patterns[] = "|<a([^>]*)href=\"{$base_url}|";
        $replacements[] = "<a $1 href=\"http://apps.facebook.com/{$_fb_app->canvas}/";
ironsizide’s picture

StatusFileSize
new677 bytes

I hope I did this right (the patch file and attaching it).

Dave Cohen’s picture

Yeah I was just playing with a change like that. Testing it on apps.facebook.com/drupalforfacebook right now, seems to be working.

I think to get this into the modules I'll need to make it optional. I'm not sure everyone would want fully-qualified links being changed this way.