<commit_before>package components

import (
	"github.com/gopherjs/vecty"
	"github.com/gopherjs/vecty/elem"
	"github.com/gopherjs/vecty/event"
	"github.com/gopherjs/vecty/examples/todomvc/actions"
	"github.com/gopherjs/vecty/examples/todomvc/dispatcher"
	"github.com/gopherjs/vecty/examples/todomvc/store/model"
	"github.com/gopherjs/vecty/prop"
	"github.com/gopherjs/vecty/style"
)

type ItemView struct {
	vecty.Composite

	Index     int
	Item      *model.Item
	editing   bool
	editTitle string
}

// Apply implements the vecty.Markup interface.
func (p *ItemView) Apply(element *vecty.Element) {
	element.AddChild(p)
}

func (p *ItemView) Reconcile(oldComp vecty.Component) {
	if oldComp, ok := oldComp.(*ItemView); ok {
		p.Body = oldComp.Body
		p.editing = oldComp.editing
		p.editTitle = oldComp.editTitle
	}
	p.RenderFunc = p.render
	p.ReconcileBody()
}

func (p *ItemView) onDestroy(event *vecty.Event) {
	dispatcher.Dispatch(&actions.DestroyItem{
		Index: p.Index,
	})
}

func (p *ItemView) onToggleCompleted(event *vecty.Event) {
	dispatcher.Dispatch(&actions.SetCompleted{
		Index:     p.Index,
		Completed: event.Target.Get("checked").Bool(),
	})
}

func (p *ItemView) onStartEdit(event *vecty.Event) {
	p.editing = true
	p.editTitle = p.Item.Title
	p.ReconcileBody()
}

func (p *ItemView) onEditInput(event *vecty.Event) {
	p.editTitle = event.Target.Get("value").String()
	p.ReconcileBody()
}

func (p *ItemView) onStopEdit(event *vecty.Event) {
	p.editing = false
	p.ReconcileBody()
	dispatcher.Dispatch(&actions.SetTitle{
		Index: p.Index,
		Title: p.editTitle,
	})
}

func (p *ItemView) render() vecty.Component {
	return elem.ListItem(
		vecty.ClassMap{
			"completed": p.Item.Completed,
			"editing":   p.editing,
		},

		elem.Div(
			prop.Class("view"),

			elem.Input(
				prop.Class("toggle"),
				prop.Type(prop.TypeCheckbox),
				prop.Checked(p.Item.Completed),
				event.Change(p.onToggleCompleted),
			),
			elem.Label(
				vecty.Text(p.Item.Title),
				event.DoubleClick(p.onStartEdit),
			),
			elem.Button(
				prop.Class("destroy"),
				event.Click(p.onDestroy),
			),
		),
		elem.Form(
			style.Margin(style.Px(0)),
			event.Submit(p.onStopEdit).PreventDefault(),
			elem.Input(
				prop.Class("edit"),
				prop.Value(p.editTitle),
				event.Input(p.onEditInput),
			),
		),
	)
}
<commit_msg>examples/todomvc: properly focus the text input when double clicking on an item<commit_after>package components

import (
	"github.com/gopherjs/vecty"
	"github.com/gopherjs/vecty/elem"
	"github.com/gopherjs/vecty/event"
	"github.com/gopherjs/vecty/examples/todomvc/actions"
	"github.com/gopherjs/vecty/examples/todomvc/dispatcher"
	"github.com/gopherjs/vecty/examples/todomvc/store/model"
	"github.com/gopherjs/vecty/prop"
	"github.com/gopherjs/vecty/style"
)

type ItemView struct {
	vecty.Composite

	Index     int
	Item      *model.Item
	editing   bool
	editTitle string
	input     *vecty.Element
}

// Apply implements the vecty.Markup interface.
func (p *ItemView) Apply(element *vecty.Element) {
	element.AddChild(p)
}

func (p *ItemView) Reconcile(oldComp vecty.Component) {
	if oldComp, ok := oldComp.(*ItemView); ok {
		p.Body = oldComp.Body
		p.editing = oldComp.editing
		p.editTitle = oldComp.editTitle
	}
	p.RenderFunc = p.render
	p.ReconcileBody()
}

func (p *ItemView) onDestroy(event *vecty.Event) {
	dispatcher.Dispatch(&actions.DestroyItem{
		Index: p.Index,
	})
}

func (p *ItemView) onToggleCompleted(event *vecty.Event) {
	dispatcher.Dispatch(&actions.SetCompleted{
		Index:     p.Index,
		Completed: event.Target.Get("checked").Bool(),
	})
}

func (p *ItemView) onStartEdit(event *vecty.Event) {
	p.editing = true
	p.editTitle = p.Item.Title
	p.ReconcileBody()
	p.input.Node().Call("focus")
}

func (p *ItemView) onEditInput(event *vecty.Event) {
	p.editTitle = event.Target.Get("value").String()
	p.ReconcileBody()
}

func (p *ItemView) onStopEdit(event *vecty.Event) {
	p.editing = false
	p.ReconcileBody()
	dispatcher.Dispatch(&actions.SetTitle{
		Index: p.Index,
		Title: p.editTitle,
	})
}

func (p *ItemView) render() vecty.Component {
	p.input = elem.Input(
		prop.Class("edit"),
		prop.Value(p.editTitle),
		event.Input(p.onEditInput),
	)

	return elem.ListItem(
		vecty.ClassMap{
			"completed": p.Item.Completed,
			"editing":   p.editing,
		},

		elem.Div(
			prop.Class("view"),

			elem.Input(
				prop.Class("toggle"),
				prop.Type(prop.TypeCheckbox),
				prop.Checked(p.Item.Completed),
				event.Change(p.onToggleCompleted),
			),
			elem.Label(
				vecty.Text(p.Item.Title),
				event.DoubleClick(p.onStartEdit),
			),
			elem.Button(
				prop.Class("destroy"),
				event.Click(p.onDestroy),
			),
		),
		elem.Form(
			style.Margin(style.Px(0)),
			event.Submit(p.onStopEdit).PreventDefault(),
			p.input,
		),
	)
}

{'fraction_non_alphanumeric': 0.1544579321892005, 'fraction_numerical': 0.0004185851820845542, 'mean_word_length': 3.881511746680286, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '511916', 'n_tokens_mistral': 2040, 'n_tokens_neox': 1880, 'n_words': 284}