Inline JavaScript detected; move to external files with CSP for security and maintainability
<script>
1<script src="../../dist/vue.min.js"></script>2<link3 rel="stylesheet"4 href="../../node_modules/todomvc-app-css/index.css"5/>67<div id="app">8 <section class="todoapp">9 <header class="header">10 <h1>todos</h1>11 <input12 class="new-todo"13 autofocus14 autocomplete="off"15 placeholder="What needs to be done?"16 v-model="state.newTodo"17 @keyup.enter="addTodo"18 />19 </header>20 <section class="main" v-show="state.todos.length">21 <input22 id="toggle-all"23 class="toggle-all"24 type="checkbox"25 v-model="state.allDone"26 />27 <label for="toggle-all">Mark all as complete</label>28 <ul class="todo-list">29 <li30 v-for="todo in state.filteredTodos"31 class="todo"32 :key="todo.id"33 :class="{ completed: todo.completed, editing: todo === state.editedTodo }"34 >35 <div class="view">36 <input class="toggle" type="checkbox" v-model="todo.completed" />37 <label @dblclick="editTodo(todo)">{{ todo.title }}</label>38 <button class="destroy" @click="removeTodo(todo)"></button>39 </div>40 <input41 class="edit"42 type="text"43 v-model="todo.title"44 v-todo-focus="todo === state.editedTodo"45 @blur="doneEdit(todo)"46 @keyup.enter="doneEdit(todo)"47 @keyup.escape="cancelEdit(todo)"48 />49 </li>50 </ul>51 </section>52 <footer class="footer" v-show="state.todos.length">53 <span class="todo-count">54 <strong>{{ state.remaining }}</strong>55 <span>{{ state.remainingText }}</span>56 </span>57 <ul class="filters">58 <li>59 <a href="#/all" :class="{ selected: state.visibility === 'all' }"60 >All</a61 >62 </li>63 <li>64 <a65 href="#/active"66 :class="{ selected: state.visibility === 'active' }"67 >Active</a68 >69 </li>70 <li>71 <a72 href="#/completed"73 :class="{ selected: state.visibility === 'completed' }"74 >Completed</a75 >76 </li>77 </ul>7879 <button80 class="clear-completed"81 @click="removeCompleted"82 v-show="state.todos.length > state.remaining"83 >84 Clear completed85 </button>86 </footer>87 </section>88</div>8990<script>91 const { reactive, computed, watchEffect, onMounted, onUnmounted } = Vue9293 const STORAGE_KEY = 'todos-vuejs-3.x-composition'94 const todoStorage = {95 fetch() {96 const todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')97 todos.forEach((todo, index) => {98 todo.id = index99 })100 todoStorage.uid = todos.length101 return todos102 },103 save(todos) {104 localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))105 }106 }107108 const filters = {109 all(todos) {110 return todos111 },112 active(todos) {113 return todos.filter(todo => {114 return !todo.completed115 })116 },117 completed(todos) {118 return todos.filter(function (todo) {119 return todo.completed120 })121 }122 }123124 function pluralize(n) {125 return n === 1 ? 'item' : 'items'126 }127128 new Vue({129 setup() {130 const state = reactive({131 todos: todoStorage.fetch(),132 editedTodo: null,133 newTodo: '',134 beforeEditCache: '',135 visibility: 'all',136 remaining: computed(() => {137 return filters.active(state.todos).length138 }),139 remainingText: computed(() => {140 return ` ${pluralize(state.remaining)} left`141 }),142 filteredTodos: computed(() => {143 return filters[state.visibility](state.todos)144 }),145 allDone: computed({146 get: function () {147 return state.remaining === 0148 },149 set: function (value) {150 state.todos.forEach(todo => {151 todo.completed = value152 })153 }154 })155 })156157 watchEffect(() => {158 todoStorage.save(state.todos)159 })160161 onMounted(() => {162 window.addEventListener('hashchange', onHashChange)163 onHashChange()164 })165166 onUnmounted(() => {167 window.removeEventListener('hashchange', onHashChange)168 })169170 function onHashChange() {171 const visibility = window.location.hash.replace(/#\/?/, '')172 if (filters[visibility]) {173 state.visibility = visibility174 } else {175 window.location.hash = ''176 state.visibility = 'all'177 }178 }179180 function addTodo() {181 const value = state.newTodo && state.newTodo.trim()182 if (!value) {183 return184 }185 state.todos.push({186 id: todoStorage.uid++,187 title: value,188 completed: false189 })190 state.newTodo = ''191 }192193 function removeTodo(todo) {194 state.todos.splice(state.todos.indexOf(todo), 1)195 }196197 function editTodo(todo) {198 state.beforeEditCache = todo.title199 state.editedTodo = todo200 }201202 function doneEdit(todo) {203 if (!state.editedTodo) {204 return205 }206 state.editedTodo = null207 todo.title = todo.title.trim()208 if (!todo.title) {209 removeTodo(todo)210 }211 }212213 function cancelEdit(todo) {214 state.editedTodo = null215 todo.title = state.beforeEditCache216 }217218 function removeCompleted() {219 state.todos = filters.active(state.todos)220 }221222 return {223 state,224 addTodo,225 removeTodo,226 editTodo,227 doneEdit,228 cancelEdit,229 removeCompleted230 }231 },232233 directives: {234 'todo-focus': (el, { value }) => {235 if (value) {236 el.focus()237 }238 }239 }240 }).$mount('#app')241</script>
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.