diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 57f91a57ca522b00a6d247a2baab4c488ddf30b2..210321653668bce67350d3b781d18cfffc42f385 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -144,6 +144,7 @@ void LLPluginClassMedia::reset()
 	mStatusText.clear();
 	mProgressPercent = 0;	
 	mClickURL.clear();
+	mClickNavType.clear();
 	mClickTarget.clear();
 	mClickUUID.clear();
 	mStatusCode = 0;
@@ -1025,6 +1026,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 		else if(message_name == "click_nofollow")
 		{
 			mClickURL = message.getValue("uri");
+			mClickNavType = message.getValue("nav_type");
 			mClickTarget.clear();
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW);
 		}
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index a940633b8898328004c74c0acd88751481c17e9c..cf8d8b26b9a3bc7e33bacb0e1cdd84f2dfe73694 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -226,6 +226,9 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	// This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW
 	std::string getClickURL() const { return mClickURL; };
 
+	// This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW
+	std::string getClickNavType() const { return mClickNavType; };
+
 	// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
 	std::string getClickTarget() const { return mClickTarget; };
 
@@ -380,6 +383,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	int				mProgressPercent;
 	std::string		mLocation;
 	std::string		mClickURL;
+	std::string		mClickNavType;
 	std::string		mClickTarget;
 	std::string		mClickUUID;
 	S32				mGeometryX;
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index c1bc9adec0de490aa4981c71c168ba17194f9448..61548a1ab4b6bc3e82bfe88ade41703dfc1d25d2 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -528,6 +528,11 @@ class MediaPluginWebKit :
 	{
 		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
 		message.setValue("uri", event.getEventUri());
+#if LLQTWEBKIT_API_VERSION >= 7
+		message.setValue("nav_type", event.getNavigationType());
+#else
+		message.setValue("nav_type", "clicked");
+#endif
 		sendMessage(message);
 	}
 	
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
index d520debc31f9f37e70b53f552b815f2c75661b09..e6f1c0467520738b426863f011b38247ca082e3e 100644
--- a/indra/newview/llagentlistener.cpp
+++ b/indra/newview/llagentlistener.cpp
@@ -64,7 +64,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const
 		params.append(event_data["x"]);
 		params.append(event_data["y"]);
 		params.append(event_data["z"]);
-		LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true);
+		LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, "clicked", true);
 		// *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat"
 		// should we just compose LLCommandHandler and LLDispatchListener?
 	}
@@ -74,7 +74,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const
 								  LLVector3(event_data["x"].asReal(), 
 											event_data["y"].asReal(), 
 											event_data["z"].asReal())).getSLURLString();
-		LLURLDispatcher::dispatch(url, NULL, false);
+		LLURLDispatcher::dispatch(url, "clicked", NULL, false);
 	}
 }
 
diff --git a/indra/newview/llcommanddispatcherlistener.cpp b/indra/newview/llcommanddispatcherlistener.cpp
index 5744d055a91db0907f6dc94d43f0e05837c5fccf..586f45fd8f41c8b7dc028c4f2e667cce9b71b3d0 100644
--- a/indra/newview/llcommanddispatcherlistener.cpp
+++ b/indra/newview/llcommanddispatcherlistener.cpp
@@ -65,7 +65,7 @@ void LLCommandDispatcherListener::dispatch(const LLSD& params) const
         trusted_browser = params["trusted"].asBoolean();
     }
     LLCommandDispatcher::dispatch(params["cmd"], params["params"], params["query"], NULL,
-                                  trusted_browser);
+                                  "clicked", trusted_browser);
 }
 
 void LLCommandDispatcherListener::enumerate(const LLSD& params) const
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 1b6ba02aacda5a85174dbc51c60fbab7a92b4faa..bb1fb41fae13972fd5e4f15c347c0348a1c50c46 100755
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -35,7 +35,7 @@
 // system includes
 #include <boost/tokenizer.hpp>
 
-#define THROTTLE_PERIOD    5    // required secs between throttled commands
+#define THROTTLE_PERIOD    20    // required secs between throttled commands
 
 static LLCommandDispatcherListener sCommandDispatcherListener;
 
@@ -59,6 +59,7 @@ class LLCommandHandlerRegistry
 				  const LLSD& params,
 				  const LLSD& query_map,
 				  LLMediaCtrl* web,
+				  const std::string& nav_type,
 				  bool trusted_browser);
 
 private:
@@ -91,6 +92,7 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
 										const LLSD& params,
 										const LLSD& query_map,
 										LLMediaCtrl* web,
+										const std::string& nav_type,
 										bool trusted_browser)
 {
 	static bool slurl_blocked = false;
@@ -120,6 +122,14 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
 			return true;
 
 		case LLCommandHandler::UNTRUSTED_THROTTLE:
+			// if users actually click on a link, we don't need to throttle it
+			// (throttling mechanism is used to prevent an avalanche of clicks via
+			// javascript
+			if ( nav_type == "clicked" )
+			{
+				break;
+			}
+
 			cur_time = LLTimer::getElapsedSeconds();
 			if (cur_time < last_throttle_time + THROTTLE_PERIOD)
 			{
@@ -166,10 +176,11 @@ bool LLCommandDispatcher::dispatch(const std::string& cmd,
 								   const LLSD& params,
 								   const LLSD& query_map,
 								   LLMediaCtrl* web,
+								   const std::string& nav_type,
 								   bool trusted_browser)
 {
 	return LLCommandHandlerRegistry::instance().dispatch(
-		cmd, params, query_map, web, trusted_browser);
+		cmd, params, query_map, web, nav_type, trusted_browser);
 }
 
 static std::string lookup(LLCommandHandler::EUntrustedAccess value);
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 1e65b6de239add3af088bd60c7015b31eb911fb8..1e0895565afc13b94de1ac0db0fdfa7d12289b2a 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -95,6 +95,7 @@ class LLCommandDispatcher
 						 const LLSD& params,
 						 const LLSD& query_map,
 						 LLMediaCtrl* web,
+						 const std::string& nav_type,
 						 bool trusted_browser);
 		// Execute a command registered via the above mechanism,
 		// passing string parameters.
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 8fccb35886c658c976ae0d08e76ac18551ed80e6..bfa8cf09fd13d9791c6cac37ba57be160ca6aba0 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2717,7 +2717,7 @@ bool LLStartUp::dispatchURL()
 			|| (dx*dx > SLOP*SLOP)
 			|| (dy*dy > SLOP*SLOP) )
 		{
-			LLURLDispatcher::dispatch(getStartSLURL().getSLURLString(), 
+			LLURLDispatcher::dispatch(getStartSLURL().getSLURLString(), "clicked",
 						  NULL, false);
 		}
 		return true;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index ebbb045f0a33e75a9260c2ab5dc3ef281515317b..ed4d278e90656aec1ffa3025f16dd74ba84ea54d 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -53,6 +53,7 @@ class LLURLDispatcherImpl
 {
 public:
 	static bool dispatch(const LLSLURL& slurl,
+						 const std::string& nav_type,
 						 LLMediaCtrl* web,
 						 bool trusted_browser);
 		// returns true if handled or explicitly blocked.
@@ -61,6 +62,7 @@ class LLURLDispatcherImpl
 
 private:
 	static bool dispatchCore(const LLSLURL& slurl, 
+							 const std::string& nav_type,
 							 bool right_mouse,
 							 LLMediaCtrl* web,
 							 bool trusted_browser);
@@ -71,6 +73,7 @@ class LLURLDispatcherImpl
 		// Returns true if handled.
 
 	static bool dispatchApp(const LLSLURL& slurl,
+							const std::string& nav_type,
 							bool right_mouse,
 							LLMediaCtrl* web,
 							bool trusted_browser);
@@ -78,7 +81,7 @@ class LLURLDispatcherImpl
 		// by showing panel in Search floater.
 		// Returns true if handled or explicitly blocked.
 
-	static bool dispatchRegion(const LLSLURL& slurl, bool right_mouse);
+	static bool dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse);
 		// handles secondlife://Ahern/123/45/67/
 		// Returns true if handled.
 
@@ -97,6 +100,7 @@ class LLURLDispatcherImpl
 
 // static
 bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
+									   const std::string& nav_type,
 									   bool right_mouse,
 									   LLMediaCtrl* web,
 									   bool trusted_browser)
@@ -105,9 +109,9 @@ bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
 	switch(slurl.getType())
 	{
 		case LLSLURL::APP: 
-			return dispatchApp(slurl, right_mouse, web, trusted_browser);
+			return dispatchApp(slurl, nav_type, right_mouse, web, trusted_browser);
 		case LLSLURL::LOCATION:
-			return dispatchRegion(slurl, right_mouse);
+			return dispatchRegion(slurl, nav_type, right_mouse);
 		default:
 			return false;
 	}
@@ -122,11 +126,12 @@ bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
 
 // static
 bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl,
+								   const std::string& nav_type,
 								   LLMediaCtrl* web,
 								   bool trusted_browser)
 {
 	const bool right_click = false;
-	return dispatchCore(slurl, right_click, web, trusted_browser);
+	return dispatchCore(slurl, nav_type, right_click, web, trusted_browser);
 }
 
 // static
@@ -135,11 +140,12 @@ bool LLURLDispatcherImpl::dispatchRightClick(const LLSLURL& slurl)
 	const bool right_click = true;
 	LLMediaCtrl* web = NULL;
 	const bool trusted_browser = false;
-	return dispatchCore(slurl, right_click, web, trusted_browser);
+	return dispatchCore(slurl, "clicked", right_click, web, trusted_browser);
 }
 
 // static
 bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl, 
+									  const std::string& nav_type,
 									  bool right_mouse,
 									  LLMediaCtrl* web,
 									  bool trusted_browser)
@@ -147,7 +153,7 @@ bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl,
 	llinfos << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << llendl;
 	const LLSD& query_map = LLURI::queryMap(slurl.getAppQuery());
 	bool handled = LLCommandDispatcher::dispatch(
-			slurl.getAppCmd(), slurl.getAppPath(), query_map, web, trusted_browser);
+			slurl.getAppCmd(), slurl.getAppPath(), query_map, web, nav_type, trusted_browser);
 
 	// alert if we didn't handle this secondlife:///app/ SLURL
 	// (but still return true because it is a valid app SLURL)
@@ -159,7 +165,7 @@ bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl,
 }
 
 // static
-bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, bool right_mouse)
+bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse)
 {
   if(slurl.getType() != LLSLURL::LOCATION)
     {
@@ -287,10 +293,11 @@ LLTeleportHandler gTeleportHandler;
 
 // static
 bool LLURLDispatcher::dispatch(const std::string& slurl,
+							   const std::string& nav_type,
 							   LLMediaCtrl* web,
 							   bool trusted_browser)
 {
-	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), web, trusted_browser);
+	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), nav_type, web, trusted_browser);
 }
 
 // static
@@ -310,7 +317,7 @@ bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
 	// *TODO: Make this trust model more refined.  JC
 	const bool trusted_browser = true;
 	LLMediaCtrl* web = NULL;
-	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), web, trusted_browser);
+	return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_browser);
 }
 
 
diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h
index b07db4da3f4591c3023c2f7f958aaab2968be1f3..6309a97af532dd4e63e283d34ed6471f2d901286 100644
--- a/indra/newview/llurldispatcher.h
+++ b/indra/newview/llurldispatcher.h
@@ -33,6 +33,7 @@ class LLURLDispatcher
 public:
 	
 	static bool dispatch(const std::string& slurl,
+						 const std::string& nav_type,
 						 LLMediaCtrl* web,
 						 bool trusted_browser);	
 		// At startup time and on clicks in internal web browsers,
@@ -41,6 +42,8 @@ class LLURLDispatcher
 		//   secondlife://RegionName/123/45/67/
 		//   secondlife:///app/agent/3d6181b0-6a4b-97ef-18d8-722652995cf1/show
 		//   sl://app/foo/bar
+		// @param nav_type
+		//   type of navigation type (see LLQtWebKit::LLWebPage::acceptNavigationRequest)
 		// @param web
 		//	 Pointer to LLMediaCtrl sending URL, can be NULL
 		// @param trusted_browser
diff --git a/indra/newview/llurldispatcherlistener.cpp b/indra/newview/llurldispatcherlistener.cpp
index d0441d7bfaa1a113ae93ca190567aac80828c138..c7b9afafefc2286fc61b99a89ef53c3ee9290c80 100644
--- a/indra/newview/llurldispatcherlistener.cpp
+++ b/indra/newview/llurldispatcherlistener.cpp
@@ -61,7 +61,7 @@ void LLURLDispatcherListener::dispatch(const LLSD& params) const
         // But for testing, allow a caller to specify untrusted.
         trusted_browser = params["trusted"].asBoolean();
     }
-    LLURLDispatcher::dispatch(params["url"], NULL, trusted_browser);
+    LLURLDispatcher::dispatch(params["url"], "clicked", NULL, trusted_browser);
 }
 
 void LLURLDispatcherListener::dispatchRightClick(const LLSD& params) const
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index c2d630ece2f31810e1446c1cb08adeb04abb14f1..037e22584f31c1764f1b6742f427b8ef1678b26b 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -2984,7 +2984,8 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 		{
 			LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; 
 			std::string url = plugin->getClickURL();
-			LLURLDispatcher::dispatch(url, NULL, mTrustedBrowser);
+			std::string nav_type = plugin->getClickNavType();
+			LLURLDispatcher::dispatch(url, nav_type, NULL, mTrustedBrowser);
 		}
 		break;
 		case MEDIA_EVENT_CLICK_LINK_HREF:
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e1d3e8a0b326bdf0fbbe926919c43d77cd4b011e..6ae143d299314883966c030ef61381f94b413405 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -111,7 +111,7 @@ class LLRegionHandler : public LLCommandHandler
 		}
 
 		// Process the SLapp as if it was a secondlife://{PLACE} SLurl
-		LLURLDispatcher::dispatch(url, web, true);
+		LLURLDispatcher::dispatch(url, "clicked", web, true);
 		return true;
 	}
 };
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 014d64176a12e89555d2413b472e68b1d7be32f0..cd19d0c5cd8a67fbfe0121f2d78d4ad47bf851c3 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -915,7 +915,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
 					{
 						if (drop)
 						{
-							LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), NULL, true );
+							LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), "clicked", NULL, true );
 							return LLWindowCallbacks::DND_MOVE;
 						}
 						return LLWindowCallbacks::DND_COPY;
@@ -1306,7 +1306,7 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
 		std::string url = (const char*)data;
 		LLMediaCtrl* web = NULL;
 		const bool trusted_browser = false;
-		if (LLURLDispatcher::dispatch(url, web, trusted_browser))
+		if (LLURLDispatcher::dispatch(url, "clicked", web, trusted_browser))
 		{
 			// bring window to foreground, as it has just been "launched" from a URL
 			mWindow->bringToFront();
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 8ef3a3b839330c34d32282d1d69aacb6402d03e9..8cdb615686ca4aa4838a4149ca705b24adec26f6 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1745,7 +1745,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
 				// Invoke the event details floater if someone is clicking on an event.
 				LLSD params(LLSD::emptyArray());
 				params.append(event_id);
-				LLCommandDispatcher::dispatch("event", params, LLSD(), NULL, true);
+				LLCommandDispatcher::dispatch("event", params, LLSD(), NULL, "clicked", true);
 				break;
 			}
 		case MAP_ITEM_LAND_FOR_SALE: