Class: Dommy::HTMLCanvasElement

Inherits:
HTMLElement show all
Includes:
Bridge::Methods
Defined in:
lib/dommy/html_canvas_element.rb

Overview

<canvas> — Dommy has no raster backend, so the API surface is implemented as inert stubs: getContext('2d') returns a CanvasRenderingContext2D whose draw operations are no-ops and whose read-backs are zeroed. The point is not to draw but to keep the many sites that merely touch a canvas from crashing: sprite/asset loaders, "am I a bot" canvas fingerprints, and chart libraries that feature-detect 2D support all call getContext then fillRect / createImageData / measureText. With no canvas element those are undefined, so the call throws "getContext is not a function" and aborts the whole bundle — exactly what hatena's bookmark.js does, which silently broke the page's bookmark button. WebGL is reported as genuinely unsupported (getContext returns null) so callers take their fallback path.

Constant Summary collapse

DEFAULT_WIDTH =
300
DEFAULT_HEIGHT =
150
BLANK_PNG =

A 1x1 transparent PNG — a constant so a canvas fingerprint reads a stable value instead of crashing; we render nothing into it.

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lE" \
"QVR42mNk+M8AAAMBAQDJ/pLvAAAAAElFTkSuQmCC"

Constants inherited from Element

Element::ADJACENT_POSITIONS, Element::APPROX_CHAR_PX, Element::APPROX_LINE_PX, Element::ATTRIBUTE_NODE, Element::CDATA_SECTION_NODE, Element::COMMENT_NODE, Element::DOCUMENT_FRAGMENT_NODE, Element::DOCUMENT_NODE, Element::DOCUMENT_POSITION_CONTAINED_BY, Element::DOCUMENT_POSITION_CONTAINS, Element::DOCUMENT_POSITION_DISCONNECTED, Element::DOCUMENT_POSITION_FOLLOWING, Element::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, Element::DOCUMENT_POSITION_PRECEDING, Element::DOCUMENT_TYPE_NODE, Element::ELEMENT_NODE, Element::HTML_NAMESPACE, Element::INLINE_TAGS, Element::PROCESSING_INSTRUCTION_NODE, Element::REFLECTED_TOKEN_LIST_HOSTS, Element::SHADOW_HOST_TAGS, Element::SVG_NAMESPACE, Element::TEXT_NODE

Constants included from Node

Node::ATTRIBUTE_NODE, Node::CDATA_SECTION_NODE, Node::COMMENT_NODE, Node::DOCUMENT_FRAGMENT_NODE, Node::DOCUMENT_NODE, Node::DOCUMENT_POSITION_CONTAINED_BY, Node::DOCUMENT_POSITION_CONTAINS, Node::DOCUMENT_POSITION_DISCONNECTED, Node::DOCUMENT_POSITION_FOLLOWING, Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, Node::DOCUMENT_POSITION_PRECEDING, Node::DOCUMENT_TYPE_NODE, Node::ELEMENT_NODE, Node::HTML_NAMESPACE, Node::PROCESSING_INSTRUCTION_NODE, Node::TEXT_NODE, Node::XMLNS_NAMESPACE, Node::XML_NAMESPACE

Instance Attribute Summary

Attributes inherited from Element

#document

Instance Method Summary collapse

Methods included from Bridge::Methods

included

Methods inherited from HTMLElement

#case_sensitive_attribute_names?, #disabled_by_ancestor_fieldset?, #labels_node_list, #parse_non_negative_reflected, #set_non_negative_reflected

Methods included from Internal::ReflectedAttributes

included

Methods inherited from Element

#[], #[]=, #__dommy_backend_node__, #__internal_approx_box, #__internal_case_sensitive_attribute_names__?, #__internal_created_namespace__, #__internal_normalize_attr_key__, #__internal_set_namespace__, #__internal_shadow_root__, #__js_attribute_snapshot__, #__run_click_activation_behavior__, #__test_scroll_log__, #access_key_label, #accessibility_tree, #activation_behavior, #activation_target, #activation_target?, #after, #anchor_href, #animate, #approximate_layout?, #aria_content_attr, #aria_element_attr, #aria_element_get, #aria_element_set, #aria_elements_attr, #aria_elements_current, #aria_elements_get, #aria_elements_set, #aria_find_in_root, #aria_get, #aria_ref_in_valid_scope?, #aria_set, #aria_snapshot, #assigned_slot, #at_xpath, #attach_shadow, #attributes, #base_uri, #before, #blur, #child_element_count, #child_nodes, #children, #class_list, #class_name, #class_name=, #clear_aria_element_ref_for, #click, #clone_node, #closest, #computed_description, #computed_label, #computed_role, #contains?, #dataset, #element_prefix, #equal_node?, #first_child, #first_element_child, #focus, #get_animations, #get_attribute, #get_attribute_names, #get_attribute_node, #get_attribute_node_ns, #get_attribute_ns, #get_bounding_client_rect, #get_client_rects, #get_elements_by_class_name, #get_elements_by_tag_name, #get_elements_by_tag_name_ns, #get_html, #get_inner_html, #has_attribute?, #has_attribute_ns?, #has_attributes?, #has_child_nodes?, #hide_popover, #id, #id=, #initialize, #inner_html, #inner_html=, #insert_adjacent_element, #insert_adjacent_html, #insert_adjacent_text, #insert_before, #insertion_parent!, #is_connected?, #last_child, #last_element_child, #live_child_nodes, #local_name, #mark_fragment_scripts_started, #matches?, #namespace_uri, #next_element_sibling, #next_sibling, #on, #outer_html, #outer_html=, #owner_document, #parent_element, #parent_node, #path, #pre_click_activation_state, #previous_element_sibling, #previous_sibling, #query_selector, #query_selector_all, #reflected_attr_name, #reflected_token_list, #remove, #remove_attribute, #remove_attribute_node, #remove_attribute_ns, #remove_child, #replace_child, #replace_with_nodes, #request_fullscreen, #restore_pre_click_activation, #role, #role=, #root_node, #run_post_click_activation, #same_node?, #set_attribute, #set_attribute_node, #set_attribute_ns, #shadow_root, #show_popover, #slot, #slot=, #style, #tag_name, #text_content, #text_content=, #to_s, #toggle_attribute, #toggle_popover, #translate_mode?, #validate_adjacent_document_insert!, #with_selector_errors, #xpath

Methods included from Internal::ParentNode

#append, #append_child, #normalize, #prepend, #replace_children

Methods included from Internal::ChildNode

#child_node_after, #child_node_before, #child_node_replace_with, #nullable_dom_string, #validate_insert_before_ref!

Methods included from Node

#compare_document_position, #get_root_node, #is_default_namespace, #is_equal_node, #is_same_node, #lookup_namespace_uri, #lookup_prefix

Methods included from EventTarget

#__dommy_dump_event_failure__, #__internal_deliver_event__, #__internal_event_parent__, #__internal_process_event_handler_return__, #add_event_listener, capture_flag, #deliver_at, #dispatch_event, #event_name_from_on, #invoke_listener_isolated, js_truthy?, #on_handler, #remove_event_listener, #set_on_handler

Constructor Details

This class inherits a constructor from Dommy::Element

Instance Method Details

#__js_call__(method, args) ⇒ Object



70
71
72
73
74
75
76
77
# File 'lib/dommy/html_canvas_element.rb', line 70

def __js_call__(method, args)
  case method
  when "getContext" then get_context(args[0], *args[1..])
  when "toDataURL" then to_data_url(*args)
  when "toBlob" then to_blob(*args)
  else super
  end
end

#__js_get__(key) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/dommy/html_canvas_element.rb', line 53

def __js_get__(key)
  case key
  when "width" then width
  when "height" then height
  else super
  end
end

#__js_set__(key, value) ⇒ Object



61
62
63
64
65
66
# File 'lib/dommy/html_canvas_element.rb', line 61

def __js_set__(key, value)
  case key
  when "width", "height" then set_reflected_string(key, value.to_s)
  else super
  end
end

#get_context(context_id, *_options) ⇒ Object

Spec: getContext returns the SAME object across calls for one context id. Only '2d' is backed; webgl/webgl2/bitmaprenderer return null so feature detection cleanly fails over.



38
39
40
41
42
# File 'lib/dommy/html_canvas_element.rb', line 38

def get_context(context_id, *_options)
  return nil unless context_id.to_s == "2d"

  @__context_2d ||= CanvasRenderingContext2D.new(self)
end

#heightObject



25
# File 'lib/dommy/html_canvas_element.rb', line 25

def height = int_dimension("height", DEFAULT_HEIGHT)

#height=(value) ⇒ Object



31
32
33
# File 'lib/dommy/html_canvas_element.rb', line 31

def height=(value)
  set_reflected_string("height", value.to_s)
end

#to_blob(callback = nil, *_args) ⇒ Object



46
47
48
49
50
51
# File 'lib/dommy/html_canvas_element.rb', line 46

def to_blob(callback = nil, *_args)
  return nil unless callback.respond_to?(:call)

  callback.call(Blob.new([], {"type" => "image/png"}))
  nil
end

#to_data_url(*_args) ⇒ Object



44
# File 'lib/dommy/html_canvas_element.rb', line 44

def to_data_url(*_args) = BLANK_PNG

#widthObject



24
# File 'lib/dommy/html_canvas_element.rb', line 24

def width = int_dimension("width", DEFAULT_WIDTH)

#width=(value) ⇒ Object



27
28
29
# File 'lib/dommy/html_canvas_element.rb', line 27

def width=(value)
  set_reflected_string("width", value.to_s)
end