HTML Control - Clicking on website links query

Started by Danner, March 18, 2011, 08:10:03 AM

Previous topic - Next topic

Danner

Hi,

When using an HTML Control to browse a (3rd party) website.  If you click on a menu/link (set to open a new Window) - Internet Explorer launches and browses to the page.

I was wondering if there was a clever way to suppress this behaviour and instead make the new window open within the HTML Control?

Many thanks for any advice

Dan

Fred Tomke

Hi, danner,

Quote from: Danner on March 18, 2011, 08:10:03 AMset to open a new Window

I think you answered your question by yourself. ;)
New window means a new instance of IE window.
You can have a try with the IE ActiveX control, but I don't believe that this would mean a different behaviour.

Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

Danner

Thanks Fred,

That's what I feared.  I posted more in hope than expectation.

Have a good weekend.

owenwengerd

Quote from: Danner on March 18, 2011, 08:10:03 AM
I was wondering if there was a clever way to suppress this behaviour and instead make the new window open within the HTML Control?

I think the only way to change the behavior is to change the HTML.
Owen Wengerd (Outside The Box) / ManuSoft

techjunkie80

#4
Edited to reflect owenwengerd's suggestions.

Your mileage using this will vary, but in the OnNavigationComplete event of the html object set the url to

javascript:(function(){var a=document.getElementsByTagName('a');for(var i=0;i<a.length;i++){a.target='_top';}})();
eg
Code (autolisp) Select
(defun c:my_object_OnNavigationComplete(url / )
   (dcl_Html_Navigate my_browser "javascript:(function(){var a=document.getElementsByTagName('a');for(var i=0;i&lt;a.length;i++){a.target='_top';}})();")
)


basically changes all <a> tags to have a target of "_top" meaning they affect the current page

owenwengerd

Modifying HTML after it is loaded should be done in OnNavigationComplete.
Owen Wengerd (Outside The Box) / ManuSoft

Danner

Thanks Owen and Techjunkie.

Techjunkie - That is a really nice trick, thanks for sharing.  Sadly doesn't work for me, but perhaps I'm using it wrong.  It just gives me a blank page. 

Owen - Before Techjunkie's trick - I was looking also playing with "dcl_Html_ReplaceText".  It works great when I paste it on the command line however when used in an OnNavigationComplete event  it seems to throw up an error message box saying  "Exception in dcl_Html_ReplaceText ARX command - Unhandled exception Exception c0000005 (Access Violation Reading 0x0000) at address 28859CAFh".  I'm not sure if its a bug, a limitation or user error.

I attach my simple test project.  The OnNavigationComplete event/dcl_Html_ReplaceText has been commented out, but can be uncommented to test rather than Techjunkie's javascript option.

Any thoughts greatly appreciated.

owenwengerd

I was able to reproduce the crash with ReplaceText during OnNavigationComplete. It looks like the document model has not yet been completely initialized at that point. I've now fixed the code to prevent the crash, but the call still fails, so it doesn't solve the problem. I also tried testjunkie's trick and like you, ended up with a blank document. It's an awful kludge, but I got it working by using (dcl_DelayedInvoke 500 "X") from within OnNavigationComplete to invoke the (X) function, which then called ReplaceText.
Owen Wengerd (Outside The Box) / ManuSoft

techjunkie80

#8
Just noticed I had a small typo in the javascript. Inside the for loop I was calling a.target instead of a[ i ].target (the array index). However even with that fix on un-cached pages I'm stuck with the same issue as your replace text, the DOM just isn't ready yet. Got this to work using Owen's delay idea

Code (autolisp) Select
(defun c:HtmlTest_HtmlTest_OnInitialize( / )  
(dcl_Html_Navigate HtmlTest_HtmlTest_Html1 "http://google.com")
)

(defun c:HtmlTest_HtmlTest_Html1_OnNavigationComplete(url / )  
(dcl_DelayedInvoke 500 "linkfix")
)

(defun c:linkfix()
(dcl_Html_Navigate HtmlTest_HtmlTest_Html1 "javascript:(function(){var a=document.getElementsByTagName('a');for(var i=0;i&lt;a.length;i++){a[i].target='_top';}})();")
)


navigated to the News section and then clicked on an article to test, usually the articles open in a new window/tab but with this script they open over the current page.

Danner

Thanks guys,

Brilliant stuff. Wish I asked for help earlier now.  I'm using the following subroutine to fix the links.  Whilst not 100% fool proof, it will try to ascertain when the page has finished loaded and fix the links once the html control ceases to be busy.  It tries to take into account variable time periods that a page takes to load.

Techjunkie best of luck with your mission on the other Html Control - thread, looks really exciting and imaginative what you are doing!

(defun c:HtmlTest_HtmlTest_Html1_OnNavigationComplete (url / )
   (HTMLCONTROL_LINKFIX HtmlTest_HtmlTest_Html1 2000 500)
   (princ)
);endfun
                 

;;subroutine to ascertain when a page has finished loading and then run Techjunkie's javascript trick to change the links
;reference http://www.opendcl.com/forum/index.php?topic=1602.0
;;credits to Techjunkie for the genius javascript trick
;;arguements:
;;1. HtmlControl - the name of the ODCL HtmlControl eg HtmlTest_HtmlTest_Html1
;;2. MaxDelay - the maximum acceptable delay in milliseconds before the routine gives up eg 2000
;;3. TimeInterval - The intervals that the routine tries to correct the links with javascript (MaxDelay should be divisible by TimeInterval)
(defun HTMLCONTROL_LINKFIX (HtmlControl MaxDelay TimeInterval / TimeElapsed)
   (setq TimeElapsed 0)
   (while (< TimeElapsed MaxDelay)
      (if (not (dcl_Html_GetBusy HtmlControl))
         (progn;then
            (dcl_Html_Navigate HtmlControl "javascript:(function(){var a=document.getElementsByTagName('a');for(var i=0;i<a.length;i++){a.target='_top';}})();")
            (setq TimeElapsed MaxDelay)
         );endprogn
         (progn;else
            (vl-cmdf "_.delay" TimeInterval)
            (setq TimeElapsed (+ TimeElapsed TimeInterval))
         );endprogn
      );endif
   );endwhile
);endfun

owenwengerd

The underlying HtmlView control also has an event called OnDocumentComplete; when I get a chance I'll test that event to see if it would resolve the problem.  In any case, it would be a good idea to add a feature request for an event that fires after the control is quiescent.
Owen Wengerd (Outside The Box) / ManuSoft

Danner