add comment
parent
fb18b49a3c
commit
45f14baad0
|
@ -9,11 +9,11 @@ require "./form/select_list"
|
|||
require "./utils/element_matcher"
|
||||
|
||||
# THis class represents the form tag of html.
|
||||
class MechanizeCr::Form
|
||||
include MechanizeCr::ElementMatcher
|
||||
class Mechanize::Form
|
||||
include Mechanize::ElementMatcher
|
||||
|
||||
getter node : Node | Lexbor::Node
|
||||
# returns an array of `MechanizeCr::FormContent::Field` in the form.
|
||||
# returns an array of `Mechanize::FormContent::Field` in the form.
|
||||
getter fields : Array(FormContent::Field)
|
||||
# returns an array of input tags whose type is checkbox in the form.
|
||||
getter checkboxes : Array(FormContent::CheckBox)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
require "./page"
|
||||
|
||||
# This class represents the history of http response you sent.
|
||||
# This class represents the history of http response you sent.
|
||||
# If you send a request, mechanize saves the history.
|
||||
class Mechanize::History
|
||||
# max page size history can save. default is 100.
|
||||
# as same as `agent.max_history`.
|
||||
property max_size : Int32
|
||||
property array : Array(Mechanize::Page)
|
||||
class Mechanize
|
||||
class History
|
||||
# max page size history can save. default is 100.
|
||||
# as same as `agent.max_history`.
|
||||
property max_size : Int32
|
||||
property array : Array(Mechanize::Page)
|
||||
|
||||
delegate :size, :empty?, :last, to: array
|
||||
|
||||
|
@ -15,17 +16,21 @@ class Mechanize::History
|
|||
@array = array
|
||||
end
|
||||
|
||||
# add page to history.
|
||||
def push(page, uri = nil)
|
||||
@array.push(page)
|
||||
while size > @max_size
|
||||
@array.shift
|
||||
# add page to history.
|
||||
def push(page, uri = nil)
|
||||
@array.push(page)
|
||||
while size > @max_size
|
||||
@array.shift
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# take the last page out from history.
|
||||
def pop
|
||||
if size == 0
|
||||
# TODO: raise error
|
||||
# take the last page out from history.
|
||||
def pop
|
||||
if size == 0
|
||||
# TODO: raise error
|
||||
end
|
||||
page = @array.pop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,16 +2,15 @@ require "./file"
|
|||
require "./utils/element_matcher"
|
||||
require "./page/link"
|
||||
|
||||
# This class represents the result of http response.
|
||||
# If you send a request, it returns the instance of `Mechanize::Page`.
|
||||
# This class represents the result of http response.
|
||||
# If you send a request, it returns the instance of `Mechanize::Page`.
|
||||
# You can get status code, title, and page body, and search html node using css selector from page instance.
|
||||
class Mechanize::Page < Mechanize::File
|
||||
include Mechanize::ElementMatcher
|
||||
class Mechanize
|
||||
class Page < Mechanize::File
|
||||
include Mechanize::ElementMatcher
|
||||
|
||||
# look at lexbor document.(https://github.com/kostya/lexbor#readme)
|
||||
delegate :css, to: parser
|
||||
|
||||
property mech : Mechanize
|
||||
# look at lexbor document.(https://github.com/kostya/lexbor#readme)
|
||||
delegate :css, to: parser
|
||||
|
||||
property mech : Mechanize
|
||||
|
||||
|
@ -20,41 +19,48 @@ class Mechanize::Page < Mechanize::File
|
|||
super(uri, response, body, code)
|
||||
end
|
||||
|
||||
# return page title.
|
||||
# ```
|
||||
# page.title # => String
|
||||
# ```
|
||||
def title : String
|
||||
title_node = css("title")
|
||||
if title_node.empty?
|
||||
""
|
||||
else
|
||||
title_node.first.inner_text
|
||||
# parser to parse response body.
|
||||
# TODO: now it's Lexbor::Parser. I want to also support other parsers like JSON.
|
||||
def parser : Lexbor::Parser
|
||||
@parser ||= Lexbor::Parser.new(@body)
|
||||
end
|
||||
|
||||
# return all forms(`Mechanize::Form`) in the page.
|
||||
# ```
|
||||
# page.forms # => Array(Mechanize::Form)
|
||||
# ```
|
||||
def forms : Array(Mechanize::Form)
|
||||
forms = css("form").map do |html_form|
|
||||
form = Form.new(html_form, self)
|
||||
form.action ||= @uri.to_s
|
||||
form
|
||||
end.to_a
|
||||
end
|
||||
|
||||
# return all links(`Mechanize::PageContent::Link`) in the page.
|
||||
# ```
|
||||
# page.links # => Array(Mechanize::PageContent::Link)
|
||||
# ```
|
||||
def links : Array(Mechanize::PageContent::Link)
|
||||
links = %w{a area}.map do |tag|
|
||||
css(tag).map do |node|
|
||||
PageContent::Link.new(node, @mech, self)
|
||||
# return page title.
|
||||
# ```
|
||||
# page.title # => String
|
||||
# ```
|
||||
def title : String
|
||||
title_node = css("title")
|
||||
if title_node.empty?
|
||||
""
|
||||
else
|
||||
title_node.first.inner_text
|
||||
end
|
||||
end.flatten
|
||||
end
|
||||
end
|
||||
|
||||
# return all forms(`Mechanize::Form`) in the page.
|
||||
# ```
|
||||
# page.forms # => Array(Mechanize::Form)
|
||||
# ```
|
||||
def forms : Array(Mechanize::Form)
|
||||
forms = css("form").map do |html_form|
|
||||
form = Form.new(html_form, self)
|
||||
form.action ||= @uri.to_s
|
||||
form
|
||||
end.to_a
|
||||
end
|
||||
|
||||
# return all links(`Mechanize::PageContent::Link`) in the page.
|
||||
# ```
|
||||
# page.links # => Array(Mechanize::PageContent::Link)
|
||||
# ```
|
||||
def links : Array(Mechanize::PageContent::Link)
|
||||
links = %w{a area}.map do |tag|
|
||||
css(tag).map do |node|
|
||||
PageContent::Link.new(node, @mech, self)
|
||||
end
|
||||
end.flatten
|
||||
end
|
||||
|
||||
elements_with "form"
|
||||
end
|
||||
|
|
|
@ -1,71 +1,71 @@
|
|||
class Mechanize
|
||||
module ElementMatcher
|
||||
macro elements_with(singular, plural = "")
|
||||
{% plural = "#{singular.id}s" if plural.empty? %}
|
||||
# search {{ plural.id }} which match condition.
|
||||
#
|
||||
# Examples
|
||||
# ```
|
||||
# # if you specify String like "foo", it searches form which name is "foo".
|
||||
{% if ["form", "button"].includes?("#{singular.id}") %}
|
||||
# # like <{{ singular.id }} name="foo"></{{ singular.id }}>
|
||||
{% elsif "#{singular.id}" == "field" %}
|
||||
# # like <input name="foo"></input>
|
||||
{% elsif "#{singular.id}" == "radiobutton" %}
|
||||
# # like <input type="radio" name="foo"></input>
|
||||
{% else %}
|
||||
# # like <input type="{{ singular.id }}" name="foo"></input>
|
||||
{% end %}
|
||||
# page.{{ plural.id }}_with("foo")
|
||||
# # you can also specify tag's attribute and its' value by NamedTuple or Hash(String, String).
|
||||
{% if ["form", "button"].includes?("#{singular.id}") %}
|
||||
# # ex) <{{ singular.id }} class="foo"></{{ singular.id }}>
|
||||
{% elsif "#{singular.id}" == "field" %}
|
||||
# # ex) <input class="foo"></input>
|
||||
{% elsif "#{singular.id}" == "radiobutton" %}
|
||||
# # ex) <input type="radio" class="foo"></input>
|
||||
{% else %}
|
||||
# # ex) <input type="{{ singular.id }}" class="foo"></input>
|
||||
{% end %}
|
||||
# page.{{ plural.id }}_with("class" => "foo")
|
||||
# page.{{ plural.id }}_with(class: "foo")
|
||||
# ```
|
||||
def {{plural.id}}_with(criteria : String | NamedTuple | Hash(String,String))
|
||||
{{plural.id}}_with(criteria){}
|
||||
end
|
||||
{% plural = "#{singular.id}s" if plural.empty? %}
|
||||
# search {{ plural.id }} which match condition.
|
||||
#
|
||||
# Examples
|
||||
# ```
|
||||
# # if you specify String like "foo", it searches form which name is "foo".
|
||||
{% if ["form", "button"].includes?("#{singular.id}") %}
|
||||
# # like <{{ singular.id }} name="foo"></{{ singular.id }}>
|
||||
{% elsif "#{singular.id}" == "field" %}
|
||||
# # like <input name="foo"></input>
|
||||
{% elsif "#{singular.id}" == "radiobutton" %}
|
||||
# # like <input type="radio" name="foo"></input>
|
||||
{% else %}
|
||||
# # like <input type="{{ singular.id }}" name="foo"></input>
|
||||
{% end %}
|
||||
# page.{{ plural.id }}_with("foo")
|
||||
# # you can also specify tag's attribute and its' value by NamedTuple or Hash(String, String).
|
||||
{% if ["form", "button"].includes?("#{singular.id}") %}
|
||||
# # ex) <{{ singular.id }} class="foo"></{{ singular.id }}>
|
||||
{% elsif "#{singular.id}" == "field" %}
|
||||
# # ex) <input class="foo"></input>
|
||||
{% elsif "#{singular.id}" == "radiobutton" %}
|
||||
# # ex) <input type="radio" class="foo"></input>
|
||||
{% else %}
|
||||
# # ex) <input type="{{ singular.id }}" class="foo"></input>
|
||||
{% end %}
|
||||
# page.{{ plural.id }}_with("class" => "foo")
|
||||
# page.{{ plural.id }}_with(class: "foo")
|
||||
# ```
|
||||
def {{plural.id}}_with(criteria : String | NamedTuple | Hash(String,String))
|
||||
{{plural.id}}_with(criteria){}
|
||||
end
|
||||
|
||||
def {{plural.id}}_with(criteria, &block)
|
||||
if criteria.is_a?(NamedTuple)
|
||||
criteria = criteria.to_h
|
||||
end
|
||||
if criteria.is_a?(String)
|
||||
criteria = {"name" => criteria}
|
||||
else
|
||||
criteria = criteria.each_with_object(Hash(String,String).new) do |(k, v), h|
|
||||
k = k.to_s
|
||||
h[k] = v
|
||||
def {{plural.id}}_with(criteria, &block)
|
||||
if criteria.is_a?(NamedTuple)
|
||||
criteria = criteria.to_h
|
||||
end
|
||||
end
|
||||
f = {{plural.id}}.select do |elm|
|
||||
criteria.all? do |k,v|
|
||||
if k == "text"
|
||||
v == elm.node.inner_text
|
||||
else
|
||||
v == elm.node.fetch(k,"")
|
||||
if criteria.is_a?(String)
|
||||
criteria = {"name" => criteria}
|
||||
else
|
||||
criteria = criteria.each_with_object(Hash(String,String).new) do |(k, v), h|
|
||||
k = k.to_s
|
||||
h[k] = v
|
||||
end
|
||||
end
|
||||
f = {{plural.id}}.select do |elm|
|
||||
criteria.all? do |k,v|
|
||||
if k == "text"
|
||||
v == elm.node.inner_text
|
||||
else
|
||||
v == elm.node.fetch(k,"")
|
||||
end
|
||||
end
|
||||
end
|
||||
yield f
|
||||
f
|
||||
end
|
||||
yield f
|
||||
f
|
||||
end
|
||||
|
||||
# returns first element of `#{{ plural.id }}_with`
|
||||
def {{singular.id}}_with(criteria)
|
||||
f = {{plural.id}}_with(criteria)
|
||||
# TODO: Write correct error message.
|
||||
raise Mechanize::ElementNotFoundError.new(:{{singular.id}}, "") if f.empty?
|
||||
f.first
|
||||
# returns first element of `#{{ plural.id }}_with`
|
||||
def {{singular.id}}_with(criteria)
|
||||
f = {{plural.id}}_with(criteria)
|
||||
# TODO: Write correct error message.
|
||||
raise Mechanize::ElementNotFoundError.new(:{{singular.id}}, "") if f.empty?
|
||||
f.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue