Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#1634 closed Bug (fixed)

JavaScript errors in internet explorer when clicking on menu when piwik is in a frame

Reported by: GadgetMaster Owned by: vipsoft
Priority: low Milestone: Piwik 1.1
Component: UI - UX (AngularJS, twig, less) Keywords:
Cc: greg Sensitive: no

Description

When Piwik is loaded inside a frame, JavaScript errors occur at the following location:

Message: Object doesn't support this property or method
Line: 256087035
Char: 3
Code: 0
URI: http://piwik.*****.com/index.php?module=CoreHome&action=index&idSite=40&period=day&date=today
User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)

I don't have further details on what goes at line 256087035. Trying to debug/break into the problem area crashes my debugger.

You may ask, why frames anyways? Well, I am working on a Virtualmin (Webmin) plugin to integrate Piwik with virtual servers hosted inside. Framed interface is the only option there in Virtualmin.

Change History (45)

comment:1 Changed 4 years ago by vipsoft (robocoder)

  • Milestone changed from Third Party Piwik Plugins to 4 - Piwik 1.0 - Stable release
  • Resolution set to invalid
  • Status changed from new to closed

comment:2 Changed 4 years ago by GadgetMaster

Would you kindly explain why this is marked "invalid"? I am very new here.

comment:3 Changed 4 years ago by GadgetMaster

Here's a screenshot of what I tried to describe. Hope it helps. Thanks!

http://img838.imageshack.us/img838/4372/capturetv.png

comment:4 Changed 4 years ago by matt (mattab)

  • Resolution invalid deleted
  • Status changed from closed to reopened

Do you have errors with Firefox, Chrome ?

Could you try using SVN trunk ?
Thanks

comment:5 Changed 4 years ago by vipsoft (robocoder)

Sorry, I reported this problem before as a comment in another ticket (now closed).

I seem to recall disabling/re-enabling the PDFReports plugin. I'll re-test from a fresh install.

comment:6 Changed 4 years ago by GadgetMaster

No problem in Firefox or Safari.

And I can't try the latest trunk as of now. I did check demo.piwik.org though. Not sure which build your demo site is running on.

I was able to reproduce and trace the problem in IE by clicking on Goals (no goals set) from the Dashboard area:

'null' is null or not an object  JScript - script block, line 1 character 178 (x2)
try { document.getElementById("VisitsSummarygetEvolutionGraphChart_swf").SetReturnValue(__flash__toXML(ofc_resize([34,-76,34,-56,"VisitsSummarygetEvolutionGraphChart_swf"])) ); } catch (e) { document.getElementById("VisitsSummarygetEvolutionGraphChart_swf").SetReturnValue("<undefined/>"); }
'null' is null or not an object  JScript - script block, line 1 character 200 (x2)
try { document.getElementById("VisitTimegetVisitInformationPerServerTimeChart_swf").SetReturnValue(__flash__toXML(ofc_resize([16,-33,36,-57,"VisitTimegetVisitInformationPerServerTimeChart_swf"])) ); } catch (e) { document.getElementById("VisitTimegetVisitInformationPerServerTimeChart_swf").SetReturnValue("<undefined/>"); }

Randomly switching through the tabs seem to trigger similar errors. Turning on Script Debugger in IE Developer Toolbar (F12) may help spot the issue.

Update: This is not limited to framed pages.

comment:7 Changed 4 years ago by vipsoft (robocoder)

  • Status changed from reopened to new

comment:8 Changed 4 years ago by vipsoft (robocoder)

  • Keywords frame javascript removed
  • Priority changed from major to low

Clicking on the menu vs. initially loading the dashboard appear to be two different issues (judging from the call stack).

comment:9 Changed 4 years ago by matt (mattab)

  • Owner set to matt
  • Summary changed from JavaScript errors when Piwik is loaded inside frameset/frame to JavaScript errors in internet explorer when clicking on menu

comment:10 Changed 4 years ago by matt (mattab)

  • Resolution set to fixed
  • Status changed from new to closed

(In [2984]) Fixes #1634 (found issue using MS IE debugger)

comment:11 Changed 4 years ago by matt (mattab)

(In [2985]) Refs #1634 merging r2984 from trunk

comment:12 Changed 4 years ago by matt (mattab)

can you please apply patch and confirm it fixes all issues with IE? thx

comment:13 Changed 4 years ago by GadgetMaster

Much better now.. Seems like there's no more errors in normal IE window.

But, my initially reported problems are still there, when loaded inside frameset. Like before, I am unable to trace the exact line of error. IE script debugger responds with something like "source code not available for this location". And yes, I already have "disable_merged_assets = 1".

While you read this, I am going to try debugging this once more with Visual Studio this time.

Thanks!

comment:14 Changed 4 years ago by matt (mattab)

when I load the '/piwik' in an iframe in IE, it doesnt display errors. How to replicate your issue (IE version, exact code used to load piwik in frameset, etc.) ?

comment:15 Changed 4 years ago by matt (mattab)

Btw, I also got the error you have with ie debugger. What i did is to go in the call stack and look at each line until you find the one that belongs to piwik (you should see a lot of jquery related calls, which are not interesting). If you down the list you will end up in a piwik javascript file (assuming disable_merged_assets = 1)

comment:16 Changed 4 years ago by GadgetMaster

IE 8.0.7600.16385 WOW64

Please try loading into a frame (not iframe).

<html>
<head> <title>Virtualmin 3.80.gpl on ***.com (CentOS Linux 5.5)</title> </head>
<frameset cols='300,*' border=0>
<frame name=left src='left.cgi' scrolling=auto>
<frame name=right src='http://demo.piwik.org/index.php?module=CoreHome&action=index&idSite=1&period=week&date=today#module=Dashboard&action=embeddedIndex&idSite=1&period=week&date=today' noresize scrolling=auto>
<noframes>
<body>
<p>This page uses frames, but your browser doesn't support them.</p>
</body>
</noframes>
</frameset>
</html>

BTW, I just loaded demo.piwik.org directly in my browser (no frame) to get the above url and there was several errors, all hitting a particular jQuery line. Also, I should add that I have enabled both IE debugging and external debugging. This is where those errors are caught. Normal users usually have them disabled, and just get the small yellow icon on the bottom left corner. They rarely notice it, let alone report.

http://img52.imageshack.us/img52/4536/jqueryinvalidarguments.png

This line clearly signals us about invalid syntax or arguments passed to jQuery.

And I can share my debugger screen (over teamviewer) with you if you like. Please let me know.

comment:17 Changed 4 years ago by matt (mattab)

(In [2996]) Refs #1634
does it fix all issues for you now?

comment:18 Changed 4 years ago by matt (mattab)

(In [2997]) Refs #1634 merging r2996 from trunk

comment:19 Changed 4 years ago by GadgetMaster

Not really. In fact, those if statements in line 137 and 139 always evaluate to true (empty jQuery object with no elements).

I have tried rewriting all these codes nearby but they don't make any difference. I belive that problem lies deep inside Superfish (which is quite old and was last packaged for jQuery 1.2.6), graph or in menu.

Another new information is that, resizing the window always triggers the same error with previous statement being (handler.apply(this,arguments)).

If you don't have already, try turning on script debugging (http://blogs.msdn.com/b/ie/archive/2004/10/26/247912.aspx) and you will see the frequency and details of script errors.

I just checked two other Win7/IE8 machines in our workplace while writing this. Since debugging is disabled there, yellow icon with same error messages appear. And, later, when debugging was turned on, modal debug dialogs started to appear - no different from what I see on my machine.

Lastly, please don't see these as "my" issues (in case you are. no offense). Actually, I am here 1) to help the community, within my limited capabilities, on the way to a solid 1.0 release, and 2) I am going to release a couple of Piwik related plugins soon, and I thought it would great to get introduced and keep in touch with you.

comment:20 Changed 4 years ago by matt (mattab)

Of course I don't see these as 'your' issues. your help and explanations are very appreciated!!

I'm not sure how to fix this bug, my previous commit was actually wrong, sorry about that. If you find a patch please let us know :)

comment:21 Changed 4 years ago by vipsoft (robocoder)

Instead of:

if($ul){

try:

if($ul && $ul.length){

comment:22 Changed 4 years ago by vipsoft (robocoder)

(In [3058]) refs #1634 - use .length to check result of .find()

comment:23 Changed 4 years ago by vipsoft (robocoder)

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:24 Changed 4 years ago by vipsoft (robocoder)

  • Owner changed from matt to vipsoft
  • Status changed from reopened to new

I'm not sure how we'll tackle the errors pointing to open-flash-chart.swf.

try { document.getElementById("VisitsSummarygetEvolutionGraphChart_swf").SetReturnValue(__flash__toXML(ofc_resize([34,-76,34,-56,"VisitsSummarygetEvolutionGraphChart_swf"])) ); } catch (e) { document.getElementById("VisitsSummarygetEvolutionGraphChart_swf").SetReturnValue("<undefined/>"); }

comment:25 Changed 4 years ago by vipsoft (robocoder)

  • Milestone changed from Piwik 0.9.9 - Stable release to 1.1 - Piwik 1.1

comment:26 Changed 4 years ago by GadgetMaster

I don't have any supporting information, but it seems like:

  • Flash objects from Open Flash Chart (OFC) and other plugins like VisitorCountryMap are registering listener functions, through Flash Player, for the "resize" event. I can't say exactly which element they are getting attached to. Flash Player is above our control or observation, I think.
  • Initially I thought that this problem could be solved by fixing and recompiling OFC. Turning off or rewriting the event related codes seemed to solve this for a while. But, when I went back to Dashboard, another flash object from VisitorCountryMap produced the same error. Then, I realized that the problem is not specific to OFC or just another module like VisitorCountryMap. I have strong feeling that the problem lies deep inside Flash Player. May be, the way Flash Player registers event listeners, or where it attaches them, are not well planned and tested thoroughly.
  • In broadcast.loadAjaxContent (broadcast.js:185), we are removing objects from the document. We are also replacing the #content div later once the AJAX call succeeds. Nothing wrong - that is what need after all. But, what happens here is that, previously registered listener functions, with references to the Flash objects, get broken as the original objects are deleted from DOM.
  • After a menu entry is clicked, the "resize" event gets triggered from several sources. This may include modifying DOM, deleting/adding Flash objects, scrollbar state and Flash player itself. Some or all of those events try to call the previously registered listener functions which do not exist anymore. And thus, we see JS errors when jQuery event management code fails to apply the missing functions on the window object. (Debugger says, “source code not available for this location” and falls back to the immediately previous statement in the call stack).

Based on the above assumptions, adding the following piece of code somewhere before calling SWFObject (or before any flash object appears) seems to solve the problem:

jQuery(window).bind('resize', function(e) {
    e.stopImmediatePropagation();
});

A good place to put this can be common.js, near the end. I had similar results by adding this at the very beginning of broadcast.loadAjaxContent (broadcast.js), but I would prefer common.js if you ask me.

Although it works, I am not sure if this breaks any Piwik functionality. From my limited tests, it seems to work without breaking anything. Please test from your end and let me know if any other issue gets introduced.

comment:27 Changed 4 years ago by vipsoft (robocoder)

That would seem to tackle a symptom rather than the root cause.

comment:28 Changed 4 years ago by vipsoft (robocoder)

This is a regression of [1235] ... it's caused by jquery ui redefining .remove(). Should be fixed in 1.8.5.

Reference: http://forum.jquery.com/topic/jquery-empty-does-not-destroy-ui-widgets-whereas-jquery-remove-does-using-ui-1-8-4

comment:29 Changed 4 years ago by vipsoft (robocoder)

scratch that last comment; that's not the fix.

comment:30 Changed 4 years ago by vipsoft (robocoder)

  • Resolution set to fixed
  • Status changed from new to closed

(In [3073]) fixes #1634 - comment out the window.resize handler

comment:31 Changed 4 years ago by vipsoft (robocoder)

(In [3074]) refs #1634 - revert [3073] and unbind all resize handlers

comment:32 Changed 4 years ago by vipsoft (robocoder)

(In [3076]) refs #1634 - spurious errors when adding/deleting this widget from the dashboard

comment:33 Changed 4 years ago by GadgetMaster

I think we are looking at the wrong place(s). Event handlers in Piwik/JS are not any problem. I was referring to the event handlers registered from inside ActionScript in OFC and other flash modules.

Reference: http://books.google.com/books?id=Rkm8vNoqlv8C&lpg=PA73&ots=ZrXuF9SFIe&dq=deregistering%20flash%20player%20event%20listeners&pg=PA73#v=onepage&q&f=false

According to this Flex 3 book, Flash Player do not garbage-collect on its own.

comment:34 Changed 4 years ago by GadgetMaster

This fixes OFC:

--- D:/Projects/Piwik/site/libs/open-flash-chart/open-flash-chart/main.as.original	Tue Sep  7 17:24:18 2010
+++ D:/Projects/Piwik/site/libs/open-flash-chart/open-flash-chart/main.as	Tue Sep  7 17:25:05 2010
@@ -451,8 +451,20 @@
 			this.stage.addEventListener(Event.RESIZE, this.resizeHandler);
 			this.stage.addEventListener(Event.MOUSE_LEAVE, this.mouseOut);
 			this.addEventListener(MouseEvent.MOUSE_OVER, this.mouseMove);
+			
+			// Cleanup
+			this.addEventListener(Event.UNLOAD, this.cleanup_event_listeners);
+			this.addEventListener(Event.REMOVED, this.cleanup_event_listeners);
+			this.addEventListener(Event.REMOVED_FROM_STAGE, this.cleanup_event_listeners);
 		}
 		
+		private function cleanup_event_listeners():void {
+			this.stage.removeEventListener(Event.ACTIVATE, this.activateHandler);
+			this.stage.removeEventListener(Event.RESIZE, this.resizeHandler);
+			this.stage.removeEventListener(Event.MOUSE_LEAVE, this.mouseOut);
+			this.removeEventListener(MouseEvent.MOUSE_OVER, this.mouseMove);
+		}		
+		
 		private function mouseMove( event:Event ):void {
 			// tr.ace( 'over ' + event.target );
 			// tr.ace('move ' + Math.random().toString());

Can I have the source code of other flash based modules?

comment:35 Changed 4 years ago by GadgetMaster

Just got the source code of UserCountryMap from this trac system. Possible fix is:

--- C:/Users/GadgetMaster/AppData/Local/Temp/PiwikMap.as-revBASE.svn000.tmp.as	Tue Sep  7 17:59:11 2010
+++ D:/Projects/Piwik/site/plugins/UserCountryMap/mapRenderer/src/PiwikMap.as	Tue Sep  7 17:49:42 2010
@@ -265,8 +265,13 @@
 			initToolTip();
 			
 			onResize();
-		}	
+			
+			stage.addEventListener(Event.UNLOAD, cleanup_event_listeners);
+		}
 		
+		private function cleanup_event_listeners():void {
+			stage.removeEventListener(Event.RESIZE, onResize);
+		}
 	
 		/**
 		 * parses the loaded data xml file

However, I cannot test this because FlashDevelop fails with:

ChartLegend.as(110): col: 33 Error: Type was not found or was not a compile-time constant: Metric.

Please advise how to proceed.

comment:36 follow-up: Changed 4 years ago by GadgetMaster

How do I get this working?

import org.piwik.data.Metric;

comment:37 Changed 4 years ago by GadgetMaster

I was about to suggest the following code, but what you have did (http://dev.piwik.org/trac/changeset/3076) is also okay.

	$(window).resize(function() {
        var newHeight;
        if(newHeight = Math.round($('#UserCountryMap').width() *.55))
		    $("#UserCountryMap").height(height);
	});

It's best not to access elements directly with "...[0]".

comment:38 Changed 4 years ago by GadgetMaster

Sorry for the typo. Fixed here:

	$(window).resize(function() {
        var newHeight;
        if(newHeight = Math.round($('#UserCountryMap').width() *.55))
		    $("#UserCountryMap").height(newHeight);
	});

I can't believe that this small change fixed everything. Spent almost two days on the ActionScripts - added garbage-collection codes to OFC and PiwikMap. Didn't help much. Then, I finally had a look here as the problem persisted in the Dashboard.

comment:39 Changed 4 years ago by vipsoft (robocoder)

(In [3079]) refs #1634 - using .height()

comment:40 Changed 4 years ago by vipsoft (robocoder)

  • Cc greg added

I've cc'd our resident Flash expert, greg, to assess the proposed changes in comment:34 and comment:35.

comment:41 Changed 4 years ago by vipsoft (robocoder)

GadgetMaster: your persistence and feedback was very helpful; I wouldn't have pulled an all-nighter otherwise.

comment:42 in reply to: ↑ 36 Changed 3 years ago by joez82

Replying to GadgetMaster:

How do I get this working?

import org.piwik.data.Metric;

Hi GadgetMaster,
how did you resolve that dependency?
I'm trying to get familiar with worldmap renderer sourcecode, but I am not able to compile, yet.

Thanks in advance!

comment:43 Changed 3 years ago by GadgetMaster

I think I just decompiled the SWF to find this. It's not there in the source tree.

Put this code as src/org/piwik/Metric.as:

package org.piwik.data
{

    public class Metric extends Object
    {
        private var _name:String;
        private var _totalRawValue:Number;
        private var _countryPrettyValues:Object;
        private var _countryRawValues:Object;
        private var _maxRawValue:Number;
        private var _id:String;
        private var _minRawValue:Number;
        private static var _intReg:RegExp = new RegExp(/(\d+)""(\d+)/);
        private static var _floatReg:RegExp = new RegExp(/(\d+\.\d+)""(\d+\.\d+)/);
        private static var _timeReg:RegExp = new RegExp(/(\d\d):(\d\d):(\d\d)""(\d\d):(\d\d):(\d\d)/);

        public function Metric(param1:String, param2:String, param3:XML)
        {
            this._id = param1;
            this._name = param2;
            this._minRawValue = Number.POSITIVE_INFINITY;
            this._maxRawValue = Number.NEGATIVE_INFINITY;
            this._countryRawValues = {};
            this._countryPrettyValues = {};
            this.parseDataXML(param3);
            trace("read metric " + this._id + " (" + this._name + ")");
            return;
        }// end function

        private function parseDataXML(param1:XML) : void
        {
            var _loc_3:XML = null;
            var _loc_4:String = null;
            var _loc_5:Number = NaN;
            var _loc_2:uint = 0;
            this._totalRawValue = 0;
            for each (_loc_3 in param1.reportData.row)
            {
                
                _loc_4 = param1.reportMetadata.row[_loc_2].code[0].toString().toUpperCase();
                _loc_5 = parseRawValue(_loc_3[this._id]);
                if (!isNaN(_loc_5))
                {
                    this._minRawValue = Math.min(this._minRawValue, _loc_5);
                    this._maxRawValue = Math.max(this._maxRawValue, _loc_5);
                    this._totalRawValue = this._totalRawValue + _loc_5;
                    this._countryRawValues[_loc_4] = _loc_5;
                }
                this._countryPrettyValues[_loc_4] = String(_loc_3[this._id].toString());
                _loc_2 = _loc_2 + 1;
            }
            return;
        }// end function

        public function get totalRawValue() : Number
        {
            return this._totalRawValue;
        }// end function

        public function get id() : String
        {
            return this._id;
        }// end function

        public function get maxRawValue() : Number
        {
            return this._maxRawValue;
        }// end function

        public function get rawValues() : Object
        {
            return this._countryRawValues;
        }// end function

        public function get name() : String
        {
            return this._name;
        }// end function

        public function get showPercent() : Boolean
        {
            return this._id.substr(0, 3) == "nb_";
        }// end function

        public function get minRawValue() : Number
        {
            return this._minRawValue;
        }// end function

        public function get prettyValues() : Object
        {
            return this._countryPrettyValues;
        }// end function

        private static function parseRawValue(param1:String) : Number
        {
            var _loc_2:Array = null;
            var _loc_3:Number = NaN;
            if (_timeReg.test(param1))
            {
                _loc_2 = _timeReg.exec(param1);
                _loc_3 = uint(_loc_2[1]) * 3600 + uint(_loc_2[2]) * 60 + uint(_loc_2[3]);
            }
            else if (_floatReg.test(param1))
            {
                _loc_2 = _floatReg.exec(param1);
                _loc_3 = Number(_loc_2[1]);
            }
            else if (_intReg.test(param1))
            {
                _loc_2 = _intReg.exec(param1);
                _loc_3 = Number(_loc_2[1]);
            }
            return _loc_3;
        }// end function

    }
}

comment:44 Changed 3 years ago by vipsoft (robocoder)

(In [3420]) fixes #1875, refs #1634 - recovered from r2725

comment:45 Changed 3 years ago by matt (mattab)

  • Summary changed from JavaScript errors in internet explorer when clicking on menu to JavaScript errors in internet explorer when clicking on menu when piwik is in a frame
Note: See TracTickets for help on using tickets.