Permalink
Browse files

Get the rest of form parsing working, inputs, labels, selects

  • Loading branch information...
1 parent 92977c7 commit d31f920da521d76a987c8f7b1ced31913bbe664b lastcraft committed Jul 30, 2009
Showing with 94 additions and 41 deletions.
  1. +23 −24 form.php
  2. +1 −0 page.php
  3. +11 −0 tag.php
  4. +59 −17 tidy_parser.php
View
@@ -5,7 +5,7 @@
* @subpackage WebTester
* @version $Id$
*/
-
+
/**#@+
* include SimpleTest files
*/
@@ -30,7 +30,7 @@ class SimpleForm {
private $widgets;
private $radios;
private $checkboxes;
-
+
/**
* Starts with no held controls/widgets.
* @param SimpleTag $tag Form tag to read.
@@ -48,7 +48,7 @@ function __construct($tag, $page) {
$this->radios = array();
$this->checkboxes = array();
}
-
+
/**
* Creates the request packet to be sent by the form.
* @param SimpleTag $tag Form tag to read.
@@ -64,7 +64,7 @@ protected function setEncodingClass($tag) {
}
return 'SimpleGetEncoding';
}
-
+
/**
* Sets the frame target within a frameset.
* @param string $frame Name of frame.
@@ -73,7 +73,7 @@ protected function setEncodingClass($tag) {
function setDefaultTarget($frame) {
$this->default_target = $frame;
}
-
+
/**
* Accessor for method of form submission.
* @return string Either get or post.
@@ -82,7 +82,7 @@ function setDefaultTarget($frame) {
function getMethod() {
return ($this->method ? strtolower($this->method) : 'get');
}
-
+
/**
* Combined action attribute with current location
* to get an absolute form target.
@@ -96,7 +96,7 @@ protected function createAction($action, $page) {
}
return $page->expandUrl(new SimpleUrl($action));;
}
-
+
/**
* Absolute URL of the target.
* @return SimpleUrl URL target.
@@ -109,7 +109,7 @@ function getAction() {
}
return $url;
}
-
+
/**
* Creates the encoding for the current values in the
* form.
@@ -124,7 +124,7 @@ protected function encode() {
}
return $encoding;
}
-
+
/**
* ID field of form for unique identification.
* @return string Unique tag ID.
@@ -133,11 +133,10 @@ protected function encode() {
function getId() {
return $this->id;
}
-
+
/**
* Adds a tag contents to the form.
* @param SimpleWidget $tag Input tag to add.
- * @access public
*/
function addWidget($tag) {
if (strtolower($tag->getAttribute('type')) == 'submit') {
@@ -148,7 +147,7 @@ function addWidget($tag) {
$this->setWidget($tag);
}
}
-
+
/**
* Sets the widget into the form, grouping radio
* buttons if any.
@@ -164,7 +163,7 @@ protected function setWidget($tag) {
$this->widgets[] = &$tag;
}
}
-
+
/**
* Adds a radio button, building a group if necessary.
* @param SimpleRadioButtonTag $tag Incoming form control.
@@ -177,7 +176,7 @@ protected function addRadioButton($tag) {
}
$this->widgets[$this->radios[$tag->getName()]]->addWidget($tag);
}
-
+
/**
* Adds a checkbox, making it a group on a repeated name.
* @param SimpleCheckboxTag $tag Incoming form control.
@@ -197,7 +196,7 @@ protected function addCheckbox($tag) {
$this->widgets[$index]->addWidget($tag);
}
}
-
+
/**
* Extracts current value from form.
* @param SimpleSelector $selector Criteria to apply.
@@ -218,7 +217,7 @@ function getValue($selector) {
}
return null;
}
-
+
/**
* Sets a widget value within the form.
* @param SimpleSelector $selector Criteria to apply.
@@ -243,7 +242,7 @@ function setField($selector, $value, $position=false) {
}
return $success;
}
-
+
/**
* Used by the page object to set widgets labels to
* external label tags.
@@ -260,7 +259,7 @@ function attachLabelBySelector($selector, $label) {
}
}
}
-
+
/**
* Test to see if a form has a submit button.
* @param SimpleSelector $selector Criteria to apply.
@@ -275,7 +274,7 @@ function hasSubmit($selector) {
}
return false;
}
-
+
/**
* Test to see if a form has an image control.
* @param SimpleSelector $selector Criteria to apply.
@@ -290,7 +289,7 @@ function hasImage($selector) {
}
return false;
}
-
+
/**
* Gets the submit values for a selected button.
* @param SimpleSelector $selector Criteria to apply.
@@ -309,12 +308,12 @@ function submitButton($selector, $additional = false) {
if ($additional) {
$encoding->merge($additional);
}
- return $encoding;
+ return $encoding;
}
}
return false;
}
-
+
/**
* Gets the submit values for an image.
* @param SimpleSelector $selector Criteria to apply.
@@ -335,12 +334,12 @@ function submitImage($selector, $x, $y, $additional = false) {
if ($additional) {
$encoding->merge($additional);
}
- return $encoding;
+ return $encoding;
}
}
return false;
}
-
+
/**
* Simply submits the form without the submit button
* value. Used when there is only one button or it
View
@@ -532,6 +532,7 @@ function getField($selector) {
static function normalise($html) {
$text = preg_replace('|<!--.*?-->|', '', $html);
$text = preg_replace('|<script[^>]*>.*?</script>|', '', $text);
+ $text = preg_replace('|<option[^>]*>.*?</option>|', '', $text);
$text = preg_replace('|<img[^>]*alt\s*=\s*"([^"]*)"[^>]*>|', ' \1 ', $text);
$text = preg_replace('|<img[^>]*alt\s*=\s*\'([^\']*)\'[^>]*>|', ' \1 ', $text);
$text = preg_replace('|<img[^>]*alt\s*=\s*([a-zA-Z_]+)[^>]*>|', ' \1 ', $text);
View
11 tag.php
@@ -174,6 +174,16 @@ function addTag($tag) {
}
/**
+ * Adds multiple enclosed tags to the content.
+ * @param array List of SimpleTag objects to be added.
+ */
+ function addTags($tags) {
+ foreach ($tags as $tag) {
+ $this->addTag($tag);
+ }
+ }
+
+ /**
* Accessor for tag name.
* @return string Name of tag.
* @access public
@@ -404,6 +414,7 @@ function resetValue() {
*/
function setLabel($label) {
$this->label = trim($label);
+ return $this;
}
/**
View
@@ -69,43 +69,85 @@ private function createEmptyForm($node) {
return new SimpleForm($this->tags()->createTag($node->name, (array)$node->attribute), $this->page);
}
- private function walkForm($node, $form) {
+ private function walkForm($node, $form, $enclosing_label = '') {
if ($node->name == 'a') {
$this->page->addLink($this->tags()->createTag($node->name, (array)$node->attribute)
- ->addContent($this->innerHtml($node)));
- } elseif ($node->name == 'input') {
- $form->addWidget($this->tags()->createTag($node->name, (array)$node->attribute));
- } elseif ($node->name == 'button' || $node->name == 'textarea') {
- $form->addWidget($this->tags()->createTag($node->name, (array)$node->attribute)
- ->addContent($this->innerHtml($node)));
- } elseif ($node->name == 'label') {
+ ->addContent($this->innerHtml($node)));
+ } elseif (in_array($node->name, array('input', 'button', 'textarea', 'select'))) {
+ $this->addWidgetToForm($node, $form, $enclosing_label);
+ } elseif ($node->name == 'label' and $this->hasFor($node)) {
$this->labels[] = $this->tags()->createTag($node->name, (array)$node->attribute)
->addContent($this->innerHtml($node));
- } elseif ($node->name == 'select') {
- $select = $this->tags()->createTag($node->name, (array)$node->attribute);
- $form->addWidget($this->collectSelectOptions($select, $node));
+ } elseif ($node->name == 'label' and ! $this->hasFor($node)) {
+ if ($node->hasChildren()) {
+ foreach ($node->child as $child) {
+ $this->walkForm($child, $form, SimplePage::normalise($this->innerHtml($node)));
+ }
+ }
}
- if ($node->hasChildren()) {
+ else if ($node->hasChildren()) {
foreach ($node->child as $child) {
$this->walkForm($child, $form);
}
}
return $form;
}
- private function collectSelectOptions($select, $node) {
+ private function hasFor($node) {
+ return isset($node->attribute) and $node->attribute['for'];
+ }
+
+ private function addWidgetToForm($node, $form, $enclosing_label) {
+ $widget = $this->tags()->createTag($node->name, $this->attributes($node))
+ ->setLabel($enclosing_label)
+ ->addContent($this->innerHtml($node));
+ if ($node->name == 'select') {
+ $widget->addTags($this->collectSelectOptions($node));
+ }
+ $form->addWidget($widget);
+ }
+
+ private function collectSelectOptions($node) {
+ $options = array();
if ($node->name == 'option') {
- $select->addTag($this->tags()->createTag($node->name, (array)$node->attribute)
- ->addContent($this->innerHtml($node)));
+ $options[] = $this->tags()->createTag($node->name, $this->attributes($node))
+ ->addContent($this->innerHtml($node));
}
if ($node->hasChildren()) {
foreach ($node->child as $child) {
- $this->collectSelectOptions($select, $child);
+ $options = array_merge($options, $this->collectSelectOptions($child));
}
}
- return $select;
+ return $options;
}
+ private function attributes($node) {
+ if (! preg_match('|<.*?\s(.*?)/?>|', $node->value, $first_tag_contents)) {
+ return array();
+ }
+ $attributes = array();
+ preg_match_all('/(\S+\s*=\s*\'[^\']*\'|\S+?\s*=\s*"[^"]*"|[^ =]+\s*=\s*[^ "\']+?|[^ "\']+)/', $first_tag_contents[1], $matches);
+ foreach($matches[1] as $unparsed) {
+ $attributes = $this->mergeAttribute($attributes, $unparsed);
+ }
+ return $attributes;
+ }
+
+ private function mergeAttribute($attributes, $raw) {
+ $parts = explode('=', $raw);
+ list($name, $value) = count($parts) == 1 ? array($parts[0], $parts[0]) : $parts;
+ $attributes[trim($name)] = $this->dequote($value);
+ return $attributes;
+ }
+
+ private function dequote($quoted) {
+ if (preg_match('/^(\'([^\']*)\'|"([^"]*)")$/', $quoted, $matches)) {
+ return $matches[2] ? $matches[2] : $matches[3];
+ }
+ return $quoted;
+ }
+
+
private function collectFrames($node) {
if ($node->name == 'frame') {
$frames = array($this->tags()->createTag($node->name, (array)$node->attribute));

0 comments on commit d31f920

Please sign in to comment.