Namespace mojox
#rem monkeydoc The HtmlView class.
#end
Class HtmlView Extends ScrollableView
#rem monkeydoc Invoked when an anchor is clicked.
#end
Field AnchorClicked:Void( url:String )
#rem monkeydoc Creates a new HtmlView.
#end
Method New()
Layout="fill"
Style=GetStyle( "HtmlView" )
_context=New litehtml.context
_context.load_master_stylesheet( stringio.LoadString( "theme::htmlview_master_css.css" ) )
_container=New document_container( Self )
_baseUrl=filesystem.CurrentDir()
AnchorClicked=Go
End
#rem monkeydoc Base URL.
This is used as the root directory for relative anchors in the page.
#end
Property BaseUrl:String()
Return _baseUrl
Setter( baseUrl:String )
If Not baseUrl.EndsWith( "/" ) baseUrl+="/"
_baseUrl=baseUrl
End
#rem monkeydoc HTML source.
#end
Property HtmlSource:String()
Return _source
Setter( htmlSource:String )
_source=htmlSource
_document=New litehtml.document( _source,_container,_context )
_layoutSize=New Vec2i( 0,0 )
_renderSize=New Vec2i( 0,0 )
RequestRender()
End
#rem monkeydoc Goto a url.
#end
Method Go( url:String )
If url.Contains( "#" )
Return
Endif
Local root:=ExtractRootDir( url )
If root="http://" Or root="https://"
#if __TARGET__="desktop"
requesters.OpenUrl( url )
#endif
Return
Endif
If Not root
url=BaseUrl+url
Endif
Local src:=stringio.LoadString( url )
If ExtractExt( url )=".md"
src=hoedown.MarkdownToHtml( src )
Local wrapper:=stringio.LoadString( "theme::markdown_wrapper.html" )
src=wrapper.Replace( "${CONTENT}",src )
End
BaseUrl=ExtractDir( url )
HtmlSource=src
End
Private
Field _context:litehtml.context
Field _container:litehtml.document_container
Field _anchorClicked:String
Field _baseUrl:String
Field _source:String
Field _document:litehtml.document
Field _layoutSize:Vec2i
Field _renderSize:Vec2i
Method OnMeasureContent2:Vec2i( size:Vec2i ) Override
If Not _document Return New Vec2i( 0,0 )
If size.x=_layoutSize.x Return _renderSize
_layoutSize=size
_document.render( size.x )
_renderSize=New Vec2i( _document.width(),_document.height() )
Return _renderSize
End
Method OnRenderContent( canvas:Canvas ) Override
If Not _document Return
Local clip:litehtml.position
clip.x=canvas.Scissor.X
clip.y=canvas.Scissor.Y
clip.width=canvas.Scissor.Width
clip.height=canvas.Scissor.Height
_document.draw( canvas,0,0,Varptr clip )
End
Method OnContentMouseEvent( event:MouseEvent ) Override
If Not _document Return
Local x:=event.Location.X
Local y:=event.Location.Y
_anchorClicked=""
Select event.Type
Case EventType.MouseDown
_document.on_lbutton_down( x,y,x,y )
Case EventType.MouseMove
_document.on_mouse_over( x,y,x,y )
Case EventType.MouseUp
_document.on_lbutton_up( x,y,x,y )
_document.on_mouse_leave()
Case EventType.MouseWheel
Return
End
event.Eat()
RequestRender() 'Not ideal, but necessary for link highlighting...
If _anchorClicked AnchorClicked( _anchorClicked )
End
End
Class document_container Extends litehtml.document_container
Field _view:HtmlView
Global _fontScale:=1
Global _imageCache:=New StringMap
Method New( view:HtmlView )
_view=view
End
Method set_color( canvas:Canvas,color:litehtml.web_color )
canvas.Color=New Color( color.red/255.0,color.green/255.0,color.blue/255.0,1 )
End
Method make_url:String( href:String )
Return _view._baseUrl+href
End
Method create_font:Object( faceName:String,size:Int,weight:Int,style:litehtml.font_style,decoration:UInt,fm:litehtml.font_metrics Ptr ) Override
Local font:Font
If faceName.Contains( "monospace" )
font=Font.Open( "font::DejaVuSansMono.ttf",size )
Else
font=Font.Open( "font::DejaVuSans.ttf",size )
Endif
Local height:=size
fm[0].height=height
fm[0].ascent=height
fm[0].descent=0
fm[0].x_height=height
fm[0].draw_spaces=True
Return font
End
Method delete_font( font:Object ) Override
End
Method text_width:Int( text:String,hfont:Object ) Override
Local font:=Cast( hfont )
Return font.TextWidth( text ) * _fontScale
End
Method draw_text( hdc:Object,text:String,hfont:Object,color:litehtml.web_color Ptr,pos:litehtml.position Ptr ) Override
Local canvas:=Cast