Class: MetaRuby::GUI::HTML::Page
- Inherits:
-
Qt::Object
- Object
- Qt::Object
- MetaRuby::GUI::HTML::Page
- Defined in:
- lib/metaruby/gui/html/page.rb
Overview
Direct Known Subclasses
Defined Under Namespace
Classes: Fragment
Constant Summary collapse
- PAGE_TEMPLATE =
The ERB template for a page
File.join(RESSOURCES_DIR, "page.rhtml")
- PAGE_BODY_TEMPLATE =
The ERB template for a page body
File.join(RESSOURCES_DIR, "page_body.rhtml")
- FRAGMENT_TEMPLATE =
The ERB template for a page fragment
File.join(RESSOURCES_DIR, "fragment.rhtml")
- LIST_TEMPLATE =
The ERB template for a list
File.join(RESSOURCES_DIR, "list.rhtml")
- ASSETS =
Assets (CSS, javascript) that are included in every page
%w{page.css jquery.min.js jquery.selectfilter.js}
Instance Attribute Summary collapse
-
#exception_rendering ⇒ #render
readonly
Object used to render exceptions in #push_exception.
-
#fragments ⇒ Array<Fragment>
readonly
List of fragments.
-
#head ⇒ Array<String>
readonly
Content to be rendered in the page head.
-
#object_uris ⇒ Object
Static mapping of objects to URIs.
-
#page ⇒ Qt::WebPage, HTMLPage
readonly
The underlying page rendering object.
-
#page_name ⇒ String?
The content of the <title> tag.
-
#scripts ⇒ Array<String>
readonly
Scripts to be loaded in the page.
-
#title ⇒ String?
The content of a toplevel <h1> tag.
Class Method Summary collapse
-
.copy_assets_to(target_dir, assets = ASSETS) ⇒ Object
Copy the assets to a target directory.
-
.main_doc(text) ⇒ String
Converts the given text from markdown to HTML and generates the necessary <div> context.
-
.to_html(object, renderer, ressource_dir: RESSOURCES_DIR, **options) ⇒ String
Renders an object into a HTML page.
-
.to_html_body(object, renderer, ressource_dir: RESSOURCES_DIR, **options) ⇒ String
Renders an object into a HTML body.
-
.to_html_page(object, renderer, **options) ⇒ Page
Renders an object into a HTML page.
Instance Method Summary collapse
-
#add_script(html) ⇒ Object
Add content to #scripts.
-
#add_to_head(html) ⇒ Object
Add content to #head.
-
#add_to_setup(obj) ⇒ Object
Add content to the page setup (head and scripts).
-
#auto_id ⇒ Object
Automatic generation of a fragment ID.
-
#clear ⇒ Object
Removes all existing displays.
-
#enable_exception_rendering(renderer = ExceptionRendering.new(self)) ⇒ Object
Enable rendering of exceptions using the given renderer.
-
#find_button_by_url(url) ⇒ Button?
Find a button from its URI.
- #find_first_element(selector) ⇒ Object
-
#html(ressource_dir: RESSOURCES_DIR) ⇒ Object
Generate the HTML.
-
#html_body(ressource_dir: RESSOURCES_DIR) ⇒ Object
Generate the body of the HTML document.
-
#html_fragment(fragment, ressource_dir: RESSOURCES_DIR) ⇒ Object
Generate the HTML of a fragment.
-
#initialize(page) ⇒ Page
constructor
Creates a new Page object.
-
#link_to(object, text = nil, **args) ⇒ String
Helper that generates a HTML link to a given object.
-
#load_javascript(file) ⇒ Object
Load a javascript file in the head.
-
#load_template(*path) ⇒ ERB
Lazy loads a template.
- #main_doc(text) ⇒ Object
-
#pageLinkClicked(url) ⇒ Object
private
Slot that catches the page’s link-clicked signal and dispatches into the buttonClicked signal (for buttons), fileClicked for files and linkClicked for links.
-
#path_in_resource(path) ⇒ String
Resolves a relative path to a path in the underlying application’s resource folder.
-
#push(title, html, id: auto_id, **view_options) ⇒ Object
Adds a fragment to this page, with the given title and HTML content.
-
#push_exception(title, e, id: auto_id, **options) ⇒ Object
Push a fragment that represents the given exception.
-
#render_item(name, value = nil) ⇒ Object
Create an item for the rendering in tables.
-
#render_list(title, items, filter: false, id: nil, **push_options) ⇒ Object
Render a list of objects into HTML and push it to this page.
-
#restore ⇒ Object
Restore the page at the state it was at the last call to #save.
-
#save ⇒ Object
Save the current state of the page, so that it can be restored by calling #restore.
- #scale_attribute(node, name, scale) ⇒ Object
-
#update_html ⇒ Object
Generate the HTML and update the underlying #page.
-
#uri_for(object) ⇒ Object
Generate a URI for an object.
Constructor Details
#initialize(page) ⇒ Page
Creates a new Page object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/metaruby/gui/html/page.rb', line 65 def initialize(page) super() @page = page @head = Array.new @scripts = Array.new @fragments = [] @templates = Hash.new @auto_id = 0 if defined?(Qt::WebPage) && page.kind_of?(Qt::WebPage) page.link_delegation_policy = Qt::WebPage::DelegateAllLinks Qt::Object.connect(page, SIGNAL('linkClicked(const QUrl&)'), self, SLOT('pageLinkClicked(const QUrl&)')) end @object_uris = Hash.new end |
Instance Attribute Details
#exception_rendering ⇒ #render (readonly)
Object used to render exceptions in #push_exception
It is set by #enable_exception_rendering
60 61 62 |
# File 'lib/metaruby/gui/html/page.rb', line 60 def exception_rendering @exception_rendering end |
#fragments ⇒ Array<Fragment> (readonly)
List of fragments
38 39 40 |
# File 'lib/metaruby/gui/html/page.rb', line 38 def fragments @fragments end |
#head ⇒ Array<String> (readonly)
Content to be rendered in the page head
48 49 50 |
# File 'lib/metaruby/gui/html/page.rb', line 48 def head @head end |
#object_uris ⇒ Object
Static mapping of objects to URIs
43 44 45 |
# File 'lib/metaruby/gui/html/page.rb', line 43 def object_uris @object_uris end |
#page ⇒ Qt::WebPage, HTMLPage (readonly)
The underlying page rendering object
33 34 35 |
# File 'lib/metaruby/gui/html/page.rb', line 33 def page @page end |
#page_name ⇒ String?
The content of the <title> tag
24 25 26 |
# File 'lib/metaruby/gui/html/page.rb', line 24 def page_name @page_name end |
#scripts ⇒ Array<String> (readonly)
Scripts to be loaded in the page
53 54 55 |
# File 'lib/metaruby/gui/html/page.rb', line 53 def scripts @scripts end |
#title ⇒ String?
The content of a toplevel <h1> tag
28 29 30 |
# File 'lib/metaruby/gui/html/page.rb', line 28 def title @title end |
Class Method Details
.copy_assets_to(target_dir, assets = ASSETS) ⇒ Object
Copy the assets to a target directory
This can be used to create self-contained HTML pages using the Page class, by providing a different ressource dir to e.g. #html or #html_body and copying the assets to it.
208 209 210 211 212 213 |
# File 'lib/metaruby/gui/html/page.rb', line 208 def self.copy_assets_to(target_dir, assets = ASSETS) FileUtils.mkdir_p target_dir assets.each do |file| FileUtils.cp File.join(RESSOURCES_DIR, file), target_dir end end |
.main_doc(text) ⇒ String
Converts the given text from markdown to HTML and generates the necessary <div> context.
176 177 178 |
# File 'lib/metaruby/gui/html/page.rb', line 176 def self.main_doc(text) "<div class=\"doc-main\">#{Kramdown::Document.new(text).to_html}</div>" end |
.to_html(object, renderer, ressource_dir: RESSOURCES_DIR, **options) ⇒ String
Renders an object into a HTML page
467 468 469 470 |
# File 'lib/metaruby/gui/html/page.rb', line 467 def self.to_html(object, renderer, ressource_dir: RESSOURCES_DIR, **) to_html_page(object, renderer, **). html(ressource_dir: ressource_dir) end |
.to_html_body(object, renderer, ressource_dir: RESSOURCES_DIR, **options) ⇒ String
Renders an object into a HTML body
476 477 478 479 |
# File 'lib/metaruby/gui/html/page.rb', line 476 def self.to_html_body(object, renderer, ressource_dir: RESSOURCES_DIR, **) to_html_page(object, renderer, **). html_body(ressource_dir: ressource_dir) end |
Instance Method Details
#add_script(html) ⇒ Object
Add content to #scripts
124 125 126 |
# File 'lib/metaruby/gui/html/page.rb', line 124 def add_script(html) scripts << html end |
#add_to_head(html) ⇒ Object
Add content to #head
117 118 119 |
# File 'lib/metaruby/gui/html/page.rb', line 117 def add_to_head(html) head << html end |
#add_to_setup(obj) ⇒ Object
Add content to the page setup (head and scripts)
109 110 111 112 |
# File 'lib/metaruby/gui/html/page.rb', line 109 def add_to_setup(obj) add_to_head(obj.head) add_script(obj.scripts) end |
#auto_id ⇒ Object
Automatic generation of a fragment ID
393 394 395 |
# File 'lib/metaruby/gui/html/page.rb', line 393 def auto_id "metaruby-html-page-fragment-#{@auto_id += 1}" end |
#clear ⇒ Object
Removes all existing displays
244 245 246 247 |
# File 'lib/metaruby/gui/html/page.rb', line 244 def clear page.main_frame.html = "" fragments.clear end |
#enable_exception_rendering(renderer = ExceptionRendering.new(self)) ⇒ Object
Enable rendering of exceptions using the given renderer
400 401 402 403 |
# File 'lib/metaruby/gui/html/page.rb', line 400 def enable_exception_rendering(renderer = ExceptionRendering.new(self)) add_to_setup(renderer) @exception_rendering = renderer end |
#find_button_by_url(url) ⇒ Button?
Find a button from its URI
287 288 289 290 291 292 293 294 295 |
# File 'lib/metaruby/gui/html/page.rb', line 287 def (url) id = url.path fragments.each do |fragment| if result = fragment..find { |b| b.id == id } return result end end nil end |
#find_first_element(selector) ⇒ Object
297 298 299 |
# File 'lib/metaruby/gui/html/page.rb', line 297 def find_first_element(selector) page.main_frame.find_first_element(selector) end |
#html(ressource_dir: RESSOURCES_DIR) ⇒ Object
Generate the HTML
264 265 266 |
# File 'lib/metaruby/gui/html/page.rb', line 264 def html(ressource_dir: RESSOURCES_DIR) load_template(PAGE_TEMPLATE).result(binding) end |
#html_body(ressource_dir: RESSOURCES_DIR) ⇒ Object
Generate the body of the HTML document
272 273 274 |
# File 'lib/metaruby/gui/html/page.rb', line 272 def html_body(ressource_dir: RESSOURCES_DIR) load_template(PAGE_BODY_TEMPLATE).result(binding) end |
#html_fragment(fragment, ressource_dir: RESSOURCES_DIR) ⇒ Object
Generate the HTML of a fragment
280 281 282 |
# File 'lib/metaruby/gui/html/page.rb', line 280 def html_fragment(fragment, ressource_dir: RESSOURCES_DIR) load_template(FRAGMENT_TEMPLATE).result(binding) end |
#link_to(object, text = nil, **args) ⇒ String
Helper that generates a HTML link to a given object
The object URI is resolved using #uri_for. If there is no known link to the object, it is returned as text
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/metaruby/gui/html/page.rb', line 154 def link_to(object, text = nil, **args) text = HTML.escape_html(text || object.name || "<anonymous>") if uri = uri_for(object) if uri !~ /^\w+:\/\// if uri[0, 1] != '/' uri = "/#{uri}" end uri = Qt::Url.new("link://metaruby#{uri}") else uri = Qt::Url.new(uri) end args.each { |k, v| uri.add_query_item(k.to_s, v.to_s) } "<a href=\"#{uri.to_string}\">#{text}</a>" else text end end |
#load_javascript(file) ⇒ Object
Load a javascript file in the head
141 142 143 144 |
# File 'lib/metaruby/gui/html/page.rb', line 141 def load_javascript(file) add_to_head( "<script type=\"text/javascript\" src=\"#{path_in_resource(file)}\"></script>") end |
#load_template(*path) ⇒ ERB
Lazy loads a template
218 219 220 221 222 223 |
# File 'lib/metaruby/gui/html/page.rb', line 218 def load_template(*path) path = File.join(*path) @templates[path] ||= ERB.new(File.read(path)) @templates[path].filename = path @templates[path] end |
#main_doc(text) ⇒ Object
180 181 182 |
# File 'lib/metaruby/gui/html/page.rb', line 180 def main_doc(text) self.class.main_doc(text) end |
#pageLinkClicked(url) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Slot that catches the page’s link-clicked signal and dispatches into the buttonClicked signal (for buttons), fileClicked for files and linkClicked for links
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/metaruby/gui/html/page.rb', line 306 def pageLinkClicked(url) if url.scheme == 'btn' && url.host == 'metaruby' if btn = (url) new_state = if url.fragment == 'on' then true else false end btn.state = new_state new_text = btn.text element = find_first_element("a##{btn.html_id}") element.replace(btn.render) emit (btn.id, new_state) else MetaRuby.warn "invalid button URI #{url.to_string}: could not find corresponding handler (known buttons are #{fragments.flat_map { |f| f..map { |btn| btn.id.to_string } }.sort.join(", ")})" end elsif url.scheme == 'link' && url.host == 'metaruby' emit linkClicked(url) elsif url.scheme == "file" emit fileOpenClicked(url) else MetaRuby.warn "MetaRuby::GUI::HTML::Page: ignored link #{url.toString}" end end |
#path_in_resource(path) ⇒ String
Resolves a relative path to a path in the underlying application’s resource folder
132 133 134 135 136 137 138 |
# File 'lib/metaruby/gui/html/page.rb', line 132 def path_in_resource(path) if Pathname.new(path).absolute? path else File.join('${RESOURCE_DIR}', path) end end |
#push(title, html, id: auto_id, **view_options) ⇒ Object
Adds a fragment to this page, with the given title and HTML content
The added fragment is enclosed in a div block to allow for dynamic replacement
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/metaruby/gui/html/page.rb', line 373 def push(title, html, id: auto_id, **) if id # Check whether we should replace the existing content or # push it new fragment = fragments.find do |fragment| fragment.id == id end if fragment fragment.html = html element = find_first_element("div##{fragment.id}") element.replace(html_fragment(fragment)) return end end fragments << Fragment.new(title, html, id: id, **) update_html end |
#push_exception(title, e, id: auto_id, **options) ⇒ Object
Push a fragment that represents the given exception
#enable_exception_rendering must have been called first
413 414 415 416 |
# File 'lib/metaruby/gui/html/page.rb', line 413 def push_exception(title, e, id: auto_id, **) html = exception_rendering.render(e, nil, id) push(title, html, id: id, **) end |
#render_item(name, value = nil) ⇒ Object
Create an item for the rendering in tables
419 420 421 422 423 424 425 |
# File 'lib/metaruby/gui/html/page.rb', line 419 def render_item(name, value = nil) if value "<li><b>#{name}</b>: #{value}</li>" else "<li>#{name}</li>" end end |
#render_list(title, items, filter: false, id: nil, **push_options) ⇒ Object
Render a list of objects into HTML and push it to this page
438 439 440 441 442 443 444 |
# File 'lib/metaruby/gui/html/page.rb', line 438 def render_list(title, items, filter: false, id: nil, **) if filter && !id raise ArgumentError, ":filter is true, but no :id has been given" end html = load_template(LIST_TEMPLATE).result(binding) push(title, html, .merge(id: id)) end |
#restore ⇒ Object
Restore the page at the state it was at the last call to #save
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/metaruby/gui/html/page.rb', line 340 def restore return if !@saved_state fragments_by_id = Hash.new @saved_state.each do |fragment| fragments_by_id[fragment.id] = fragment end # Delete all fragments that are not in the saved state fragments.delete_if do |fragment| element = find_first_element("div##{fragment.id}") if old_fragment = fragments_by_id[fragment.id] if old_fragment.html != fragment.html element.replace(old_fragment.html) end else element.replace("") true end end end |
#save ⇒ Object
Save the current state of the page, so that it can be restored by calling #restore
335 336 337 |
# File 'lib/metaruby/gui/html/page.rb', line 335 def save @saved_state = fragments.map(&:dup) end |
#scale_attribute(node, name, scale) ⇒ Object
249 250 251 252 253 |
# File 'lib/metaruby/gui/html/page.rb', line 249 def scale_attribute(node, name, scale) node.attributes[name] = node.attributes[name].gsub /[\d\.]+/ do |n| (Float(n) * scale).to_s end end |
#update_html ⇒ Object
Generate the HTML and update the underlying #page
256 257 258 |
# File 'lib/metaruby/gui/html/page.rb', line 256 def update_html page.main_frame.html = html end |
#uri_for(object) ⇒ Object
Generate a URI for an object
The method must either return a string that is a URI representing the object, or nil if there is none. The choice of the URI is application-specific, used by the application to recognize links
The default application returns a file:/// URI for a Pathname object, and then uses #object_uris
235 236 237 238 239 240 241 |
# File 'lib/metaruby/gui/html/page.rb', line 235 def uri_for(object) if object.kind_of?(Pathname) "file://#{object.}" else object_uris[object] end end |