Issue Details (XML | Word | Printable)

Key: MBS-2689
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Normal Normal
Assignee: Ian McEwen
Reporter: nikki
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
MusicBrainz Server

Timeline isn't working in Opera 10

Created: 10/Jun/11 06:58 AM   Updated: 11/Jul/11 11:28 AM   Resolved: 11/Jul/11 11:28 AM
Component/s: Misc features
Affects Version/s: None
Fix Version/s: Schema Change, 2011-07-11


 Description  « Hide

The timeline isn't working in Opera 10 even though examples Ian showed me worked fine.

The error console says:

JavaScript - http://musicbrainz.org/statistics/timeline
Event thread: DOMContentLoaded
Error:
name: TypeError
message: Statement on line 33: Type mismatch (usually non-object value supplied where object required)
stacktrace: Line 33 of linked script http://musicbrainz.org/static/b0738ce8fe545e7ece534cfa6f1dc8a7.js: In function measureTickLabels
"\n").split("\n");for(var j=0;j<lines.length;++j){var line={text:lines[j]},m=ctx.measureText(line.text);line.width=m.width;line.height=m.height!=null?m.height:f.size;line.height+=Math.round(f.size*0.15);t.width=Math.max(line.width,t.width);t.height+=line.height;t.lines.push(line)}if(opts.labelWidth==null)axisw=Math.max(axisw,t.width);if(opts.labelHeight==null)axish=Math.max(axish,t.height)}ctx.restore()}axis.labelWidth=Math.ceil(axisw);axis.labelHeight=Math.ceil(axish)}
Line 39 of linked script http://musicbrainz.org/static/b0738ce8fe545e7ece534cfa6f1dc8a7.js
function(_,axis){setupTickGeneration(axis);setTicks(axis);snapRangeToTicks(axis,axis.ticks);axis.font=$.extend({},fontDefaults,axis.options.font);measureTickLabels(axis)}
... Line 15 of linked script http://musicbrainz.org/static/6feb2a1ed54658f808b32653b13fa1bb.js
function(object,callback,args){var name,i=0,length=object.length,isObj=length===undefined||jQuery.isFunction(object);if(args)if(isObj)for(name in object){if(callback.apply(object[name],args)===false)break}else for(;i<length{if(callback.apply(object[i++],args)===false)break}else if(isObj)for(name in object){if(callback.call(object[name],name,object[name])===false)break}else for(var value=
Line 39 of linked script http://musicbrainz.org/static/b0738ce8fe545e7ece534cfa6f1dc8a7.js: In function setupGrid
size:Math.round(0.8*(+placeholder.css("font-size").replace("px","")||13)),variant:placeholder.css("font-variant"),weight:placeholder.css("font-weight"),family:placeholder.css("font-family")};var allocatedAxes=$.grep(axes,function(axis){return axis.reserveSpace});$.each(allocatedAxes,function(_,axis){setupTickGeneration(axis);setTicks(axis);snapRangeToTicks(axis,axis.ticks);axis.font=$.extend({},fontDefaults,axis.options.font);measureTickLabels(axis)});for(i=allocatedAxes.length-1;i>=0;--i)allocateAxisBoxFirstPhase(allocatedAxes[i]);
Line 12 of linked script http://musicbrainz.org/static/b0738ce8fe545e7ece534cfa6f1dc8a7.js: In function Plot
plot.pointOffset=function(point){return{left:parseInt(xaxes[axisNumber(point,"x")-1].p2c(+point.x)+plotOffset.left),top:parseInt(yaxes[axisNumber(point,"y")-1].p2c(+point.y)+plotOffset.top)}};plot.shutdown=shutdown;plot.resize=function(){getCanvasDimensions();resizeCanvas(canvas);resizeCanvas(overlay)};plot.hooks=hooks;initPlugins(plot);parseOptions(options_);setupCanvases();setData(data_);setupGrid();draw();bindEvents();function executeHooks(hook,args){args=[plot].concat(args);for(var i=0;i<hook.length;++i)hook[i].apply(this,
Line 92 of linked script http://musicbrainz.org/static/b0738ce8fe545e7ece534cfa6f1dc8a7.js
function(placeholder,data,options){var plot=new Plot($(placeholder),data,options,$.plot.plugins);return plot}
Line 148 of inline#3 script in http://musicbrainz.org/statistics/timeline: In function resetPlot
plot = $.plot($("#graph-container"), graph_data(), options);
Line 152 of inline#3 script in http://musicbrainz.org/statistics/timeline
resetPlot();
... Line 20 of linked script http://musicbrainz.org/static/6feb2a1ed54658f808b32653b13fa1bb.js
function(context,args){if(!cancelled&&!fired&&!firing){firing=1;try{while(callbacks[0])callbacks.shift().apply(context,
Line 10 of linked script http://musicbrainz.org/static/6feb2a1ed54658f808b32653b13fa1bb.js
wait!==true&&Unable to render embedded object: File (jQuery.isReady){if(!document.body)return setTimeout(jQuery.ready,1);jQuery.isReady=true;if(wait) not found.==true&&--jQuery.readyWait>0)return;readyList.resolveWith(document,[jQuery]);if(jQuery.fn.trigger)jQuery(document).trigger("ready").unbind("ready")}}
Line 27 of linked script http://musicbrainz.org/static/6feb2a1ed54658f808b32653b13fa1bb.js
DOMContentLoaded,false);jQuery.ready()}
...



Sort Order: Ascending order - Click to sort in descending order
Ian McEwen added a comment - 10/Jun/11 06:35 PM - edited

Presto < 2.6 doesn't support CanvasRenderingContext2D's measureText(); see: http://www.opera.com/docs/specs/presto26/canvas/

Previous versions don't even mention measureText() other than 2.1, which says it doesn't support it. Presto 2.6 started being used for Opera 10.60: http://www.opera.com/docs/history/#o10

The jquery.flot.js version that was being used on the example pages doesn't happen to include the call to measureText() that the version we have does. The change was made: https://github.com/flot/flot/commit/89bbfef5170376247e65dcf70710609d25467b16 and it appears it was made so that flot was using canvas's text, rather than overlaying divs, which seems like a good goal for the canvas-based graphing library!

I don't know that we want to downgrade our version of jquery.flot.js to not use canvas text, which leads me to believe this might be a wontfix, unless somebody has a clever idea about how to get around this.


Ian McEwen added a comment - 10/Jun/11 08:12 PM

Added to an upstream issue http://code.google.com/p/flot/issues/detail?id=546 (talks about Konqueror, but it's the same problem we're running into with Opera 10). Hopefully it gets fixed soon!


Ian McEwen added a comment - 10/Jun/11 08:57 PM

Workaround for now; add this script to your userjs folder:

if (location.hostname.indexOf('musicbrainz.org') != -1)
{
window.opera.addEventListener('BeforeScript', function(event)
{
if (event.element.getAttribute("src").indexOf('b0738ce8fe545e7ece534cfa6f1dc8a7.js') != -1)

{ event.preventDefault(); var script1 = document.createElement('script'); script1.setAttribute("src", "http://people.iola.dk/olau/flot/jquery.flot.js"); var script2 = document.createElement('script'); script2.setAttribute("src", "http://people.iola.dk/olau/flot/jquery.flot.selection.js"); event.element.parentNode.insertBefore(script1, event.element.nextSibling); event.element.parentNode.insertBefore(script2, event.element.nextSibling); }

}, false);
}


Ian McEwen added a comment - 14/Jun/11 08:51 PM

Since I changed what's in the manifest, script should now be:

if (location.hostname.indexOf('musicbrainz.org') != -1)
{
window.opera.addEventListener('BeforeScript', function(event)
{
if (event.element.getAttribute("src").indexOf('b0a05208d344418bb14026741de2ceb4.js') != -1)

{ event.preventDefault(); var script1 = document.createElement('script'); script1.setAttribute("src", "http://people.iola.dk/olau/flot/jquery.flot.js"); var script2 = document.createElement('script'); script2.setAttribute("src", "http://people.iola.dk/olau/flot/jquery.flot.selection.js"); var script3 = document.createElement('script'); script2.setAttribute("src", "http://musicbrainz.org/static/lib/jquery/jquery.ba-hashchange.js"); event.element.parentNode.insertBefore(script1, event.element.nextSibling); event.element.parentNode.insertBefore(script2, event.element.nextSibling); event.element.parentNode.insertBefore(script3, event.element.nextSibling); }

}, false);
}


Ian McEwen added a comment - 24/Jun/11 08:30 PM

Note to self: http://code.google.com/p/canvas-text/ – needs some tinkering to make it work, but should make it possible to use the timeline graph and Opera 10 without a userscript.