[banshee] Support remote fixup JavaScript on Amazon



commit 9647abe6e81be9b5db56d48692159e8a8709774f
Author: Aaron Bockover <abockover novell com>
Date:   Tue Jul 13 13:18:08 2010 -0400

    Support remote fixup JavaScript on Amazon
    
    Download amz-fixups.js, which is executed on page loads for Amazon MP3
    store. This JavaScript simply removes the "Install Flash" messages since
    we disable plugins.
    
    The JavaScript is stored and fetched remotely so it can be updated if
    necessary to reflect future changes in the Amazon MP3 page structure.

 .../Banshee.WebBrowser/NavigationControl.cs        |   18 ++++---
 .../Banshee.WebBrowser/OssiferWebView.cs           |   13 +++++
 .../libossifer/ossifer-web-view.c                  |   44 ++++++++++-----
 .../Banshee.AmazonMp3.Store/StoreView.cs           |   58 +++++++++++++++++++-
 .../Banshee.AmazonMp3.Store/WebBrowserShell.cs     |    3 +-
 5 files changed, 111 insertions(+), 25 deletions(-)
---
diff --git a/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/NavigationControl.cs b/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/NavigationControl.cs
index a052e1b..e8787cc 100644
--- a/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/NavigationControl.cs
+++ b/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/NavigationControl.cs
@@ -99,15 +99,17 @@ namespace Banshee.WebBrowser
 
         public void UpdateNavigation ()
         {
-            if (web_view == null) {
-                Sensitive = false;
-                return;
+            if (web_view != null) {
+                back_button.Sensitive = web_view.CanGoBack;
+                forward_button.Sensitive = web_view.CanGoForward;
+                home_button.Sensitive = true;
+                reload_button.Sensitive = true;
+            } else {
+                back_button.Sensitive = false;
+                forward_button.Sensitive = false;
+                home_button.Sensitive = false;
+                reload_button.Sensitive = false;
             }
-
-            Sensitive = true;
-
-            back_button.Sensitive = web_view.CanGoBack;
-            forward_button.Sensitive = web_view.CanGoForward;
         }
 
         private void OnOssiferWebViewLoadStatusChanged (object o, EventArgs args)
diff --git a/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/OssiferWebView.cs b/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/OssiferWebView.cs
index 36c0120..61e3c27 100644
--- a/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/OssiferWebView.cs
+++ b/src/Core/Banshee.WebBrowser/Banshee.WebBrowser/OssiferWebView.cs
@@ -227,6 +227,19 @@ namespace Banshee.WebBrowser
         }
 
         [DllImport (LIBOSSIFER)]
+        private static extern void ossifer_web_view_execute_script (IntPtr ossifer, IntPtr script);
+
+        public void ExecuteScript (string script)
+        {
+            var script_raw = IntPtr.Zero;
+            try {
+                ossifer_web_view_execute_script (Handle, script_raw = GLib.Marshaller.StringToPtrGStrdup (script));
+            } finally {
+                GLib.Marshaller.Free (script_raw);
+            }
+        }
+
+        [DllImport (LIBOSSIFER)]
         private static extern IntPtr ossifer_web_view_get_uri (IntPtr ossifer);
 
         public virtual string Uri {
diff --git a/src/Core/Banshee.WebBrowser/libossifer/ossifer-web-view.c b/src/Core/Banshee.WebBrowser/libossifer/ossifer-web-view.c
index 4c96f88..2fda2b2 100644
--- a/src/Core/Banshee.WebBrowser/libossifer/ossifer-web-view.c
+++ b/src/Core/Banshee.WebBrowser/libossifer/ossifer-web-view.c
@@ -66,7 +66,7 @@ ossifer_web_view_download_get_mimetype (WebKitDownload *download)
 }
 
 static WebKitWebView *
-ossifer_web_view_create_web_view (WebKitWebView *web_view, WebKitWebFrame *web_frame)
+ossifer_web_view_create_web_view (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data)
 {
     return WEBKIT_WEB_VIEW (g_object_new (OSSIFER_TYPE_WEB_VIEW, NULL));
 }
@@ -149,27 +149,30 @@ ossifer_web_view_notify_load_status (GObject* object, GParamSpec* pspec, gpointe
     }
 }
 
+static GtkWidget *
+ossifer_web_view_create_plugin_widget (WebKitWebView *web_view, gchar *mime_type,
+    gchar *uri, GHashTable *param, gpointer user_data)
+{
+    // FIXME: this is just a useless stub, but could be used to provide
+    // overriding plugins that hook directly into Banshee - e.g. provide
+    // in-page controls that match the functionality of Amazon's MP3
+    // preview Flash control.
+    //
+    // I'm opting not to do this now, because this requires setting
+    // "enable-plugins" to TRUE, which causes all the plugins to be
+    // loaded, which can introduce instability. There should be a fix
+    // to avoid building the plugin registry at all in libwebkit.
+    return NULL;
+}
+
 // ---------------------------------------------------------------------------
 // OssiferWebView Class/Object Implementation
 // ---------------------------------------------------------------------------
 
 static void
-ossifer_web_view_finalize (GObject *object)
-{
-    G_OBJECT_CLASS (ossifer_web_view_parent_class)->finalize (object);
-}
-
-static void
 ossifer_web_view_class_init (OssiferWebViewClass *klass)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-    WebKitWebViewClass *web_view_class = WEBKIT_WEB_VIEW_CLASS (klass);
-
     g_type_class_add_private (klass, sizeof (OssiferWebViewPrivate));
-
-    object_class->finalize = ossifer_web_view_finalize;
-
-    web_view_class->create_web_view = ossifer_web_view_create_web_view;
 }
 
 static void
@@ -193,6 +196,12 @@ ossifer_web_view_init (OssiferWebView *ossifer)
 
     g_signal_connect (ossifer, "notify::load-status",
         G_CALLBACK (ossifer_web_view_notify_load_status), NULL);
+
+    g_signal_connect (ossifer, "create-plugin-widget",
+        G_CALLBACK (ossifer_web_view_create_plugin_widget), NULL);
+
+    g_signal_connect (ossifer, "create-web-view",
+        G_CALLBACK (ossifer_web_view_create_web_view), NULL);
 }
 
 // ---------------------------------------------------------------------------
@@ -282,4 +291,11 @@ ossifer_web_view_reload_bypass_cache (OssiferWebView *ossifer)
 {
     g_return_if_fail (OSSIFER_WEB_VIEW (ossifer));
     return webkit_web_view_reload_bypass_cache (WEBKIT_WEB_VIEW (ossifer));
+}
+
+void
+ossifer_web_view_execute_script (OssiferWebView *ossifer, const gchar *script)
+{
+    g_return_if_fail (OSSIFER_WEB_VIEW (ossifer));
+    return webkit_web_view_execute_script (WEBKIT_WEB_VIEW (ossifer), script);
 }
\ No newline at end of file
diff --git a/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/StoreView.cs b/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/StoreView.cs
index 3f78bac..bd61ddf 100644
--- a/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/StoreView.cs
+++ b/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/StoreView.cs
@@ -40,9 +40,14 @@ namespace Banshee.AmazonMp3.Store
 {
     public class StoreView : OssiferWebView
     {
+        private string fixup_javascript;
+        private bool fixup_javascript_fetched;
+
         public bool IsSignedIn { get; private set; }
+        public bool IsReady { get; private set; }
 
         public event EventHandler SignInChanged;
+        public event EventHandler Ready;
 
         public StoreView ()
         {
@@ -59,6 +64,20 @@ namespace Banshee.AmazonMp3.Store
             FullReload ();
         }
 
+        protected override void OnLoadStatusChanged (OssiferLoadStatus status)
+        {
+            if ((status == OssiferLoadStatus.FirstVisuallyNonEmptyLayout ||
+                status == OssiferLoadStatus.Finished) && Uri != "about:blank") {
+                // Hide "Install Flash" messages on Amazon since we
+                // play content previews natively in Banshee
+                if (fixup_javascript != null) {
+                    ExecuteScript (fixup_javascript);
+                }
+            }
+
+            base.OnLoadStatusChanged (status);
+        }
+
         protected override OssiferNavigationResponse OnMimeTypePolicyDecisionRequested (string mimetype)
         {
             // We only explicitly accept (render) text/html types, and only
@@ -109,12 +128,12 @@ namespace Banshee.AmazonMp3.Store
 
         public void GoHome ()
         {
-            LoadUri ("http://amz-proxy.banshee.fm/";);
+            LoadUri ("http://amz-proxy.banshee.fm/do/home/";);
         }
 
         public void GoSearch (string query)
         {
-            LoadUri (new Uri ("http://amz-proxy.banshee.fm/search/"; + query).AbsoluteUri);
+            LoadUri (new Uri ("http://amz-proxy.banshee.fm/do/search/"; + query).AbsoluteUri);
         }
 
         public void SignOut ()
@@ -134,10 +153,45 @@ namespace Banshee.AmazonMp3.Store
             LoadString (AssemblyResource.GetFileContents ("loading.html"),
                 "text/html", "UTF-8", null);
 
+            // Here we download and save for later injection some JavaScript
+            // to fix-up the Amazon pages. We don't store this locally since
+            // it may need to be updated if Amazon's page structure changes.
+            // We're mainly concerned about hiding the "You don't have Flash"
+            // messages, since we do the streaming of previews natively.
+            if (!fixup_javascript_fetched) {
+                fixup_javascript_fetched = true;
+                new Hyena.Downloader.HttpStringDownloader () {
+                    Uri = new Uri ("http://amz-proxy.banshee.fm/amz-fixups.js";),
+                    Finished = (d) => {
+                        if (d.State.Success) {
+                            fixup_javascript = d.Content;
+                        }
+                        LoadHome ();
+                    },
+                    AcceptContentTypes = new [] { "text/javascript" }
+                }.Start ();
+            } else {
+                LoadHome ();
+            }
+        }
+
+        private void LoadHome ()
+        {
             // We defer this to another main loop iteration, otherwise
             // our load placeholder document will never be rendered.
             GLib.Idle.Add (delegate {
                 GoHome ();
+
+                // Emit the Ready event once we are first allowed
+                // to load the home page (ensures we've downloaded
+                // the fixup javascript, etc.).
+                if (!IsReady) {
+                    IsReady = true;
+                    var handler = Ready;
+                    if (handler != null) {
+                        handler (this, EventArgs.Empty);
+                    }
+                }
                 return false;
             });
         }
diff --git a/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/WebBrowserShell.cs b/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/WebBrowserShell.cs
index 38ca3a2..e68f3d0 100644
--- a/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/WebBrowserShell.cs
+++ b/src/Extensions/Banshee.AmazonMp3.Store/Banshee.AmazonMp3.Store/WebBrowserShell.cs
@@ -64,7 +64,8 @@ namespace Banshee.AmazonMp3.Store
                 }
             };
 
-            navigation_control.WebView = store_view;
+            store_view.Ready += (o, e) => navigation_control.WebView = store_view;
+
             navigation_control.GoHomeEvent += (o, e) => store_view.GoHome ();
 
             Attach (navigation_control, 0, 1, 0, 1,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]