How to use ReferrerPolicy method of html Package

Best K6 code snippet using html.ReferrerPolicy

templates.go

Source:templates.go Github

copy

Full Screen

1//2// Author: Vinhthuy Phan, 20183//4package main5var STUDENT_MESSAGING_TEMPLATE = `6<html>7 <head>8 <title>Student messaging</title>9 <meta http-equiv="refresh" content="10" />10 </head>11 <style>12 .bottom {13 position: fixed;14 bottom: 0;15 font-size: 150%;16 color: red;17 }18 </style>19 <body>20 <div class="bottom">{{.Message}}</div>21 </body>22</html>23`24var TEACHER_MESSAGING_TEMPLATE = `25<html>26 <head>27 <title>Teacher messaging</title>28 <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?autoload=true&skin=sons-of-obsidian"></script>29 <script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>30 <script type="text/javascript">31 var updateInterval = 5000; // 5 sec update interval32 var maxUpdateTime = 1800000; // no longer update after 30 min.33 var totalUpdateTime = 0;34 function getData() {35 var url = "http://{{.Address}}/bulletin_board_data";36 $.getJSON(url, function( data ) {37 console.log(data);38 $("#p1").html(data["P1"]);39 $("#p2").html(data["P2"]);40 $("#p1u").html(data["P1Ungraded"]);41 $("#p1g").html(data["P1Graded"]);42 $("#p2u").html(data["P2Unanswered"]);43 $("#p2a").html(data["P2Answered"]);44 });45 }46 $(document).ready(function(){47 getData();48 handle = setInterval(getData, updateInterval);49 });50 </script>51 </head>52 <style>53 .bottom {54 position: fixed;55 bottom: 0;56 text-align: center;57 width: 100%;58 }59 .bottom_left {60 position: fixed;61 bottom: 0;62 text-align: left,63 width: 50%;64 }65 .bottom_right {66 position: fixed;67 bottom: 0;68 right: 50px;69 text-align: right,70 width: 50%;71 }72 .label{ display: inline; }73 #p1, #p2, #p1g, #p1u, #p2a, #p2u, #ans, #ap, #bu, #at {74 padding: 0.75em;75 display: inline;76 }77 #p1g, #p2a { color: green; }78 #p1u, #p2u { color: red; }79 pre {80 font-family: monospace;81 font-size:120%;82 margin-top:50px;83 padding-left:2em;84 overflow-x:scroll;85 overflow-y:scroll;86 tab-size: 4;87 -moz-tab-size: 4;88 }89 .center {90 text-align: center;91 }92 .pagination {93 display: inline-block;94 padding-bottom: 20px;95 }96 .pagination a {97 color: black;98 float: left;99 padding: 8px 16px;100 text-decoration: none;101 transition: background-color .3s;102 border: 1px solid #ddd;103 margin: 0 4px;104 border-radius: 5px;105 }106 .pagination a.active {107 background-color: #4CAF50;108 color: white;109 border: 1px solid #4CAF50;110 border-radius: 5px;111 }112 .pagination a:hover:not(.active) {background-color: #ddd;}113 .nav a { text-decoration: none; padding:3px;}114 .nav { display: inline-block; vertical-align: baseline;}115 #navWrap{position:absolute;top:20;right:10;}116 </style>117 <body>118 <div id="navWrap">119 {{ if .Authenticated }}120 <div class="nav"><a href="view_bulletin_board?i=0&pc={{.PC}}">First<a></div>121 <div class="nav"><a href="view_bulletin_board?i={{.PrevI}}&pc={{.PC}}">Prev<a></div>122 <div class="nav"><a href="view_bulletin_board?i={{.NextI}}&pc={{.PC}}">Next<a></div>123 <div class="nav"><a href="remove_bulletin_page?i={{.I}}&pc={{.PC}}">&#x2718;</a></div>124 {{ end }}125 </div>126 <pre class="prettyprint linenums">{{.Code}}</pre>127 <div class="bottom_left">128 <div id="p2">{{.P2}}</div> <div class="label">Help Requests:</div>129 <div id="p2u">{{.P2Unanswered}}</div> <div class="label">Pending,</div>130 <div id="p2a">{{.P2Answered}}</div> <div class="label">Answered</div>131 </div>132 <div class="bottom_right">133 <div id="p1">{{.P1}}</div> <div class="label">Submissions:</div>134 <div id="p1u">{{.P1Ungraded}}</div> <div class="label">Pending,</div>135 <div id="p1g">{{.P1Graded}}</div> <div class="label">Graded</div>136 </div>137 </body>138</html>139`140var CODESPACE_TEMPLATE = `141 <!DOCTYPE html>142 <html>143 <head>144 <title>CodeSpace</title>145 <meta http-equiv="refresh" content="120" >146 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>147 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />148 </head>149 <body>150 <div class="container">151 <h3 class="title is-3">CodeSpace: List of Code Snapshots</h3>152 <table class="table is-striped is-fullwidth is-hoverable is-narrow">153 <thead>154 <tr>155 <th>Student</th>156 <th>Last Snapshot</th>157 <th>Time Spent</th>158 <th>Lines of Code</th>159 <th>Number of Feedback Messages</th>160 <th>Status</th>161 <th></th>162 </tr>163 </thead>164 <tbody>165 {{ range .Snapshots }}166 <tr>167 <td>{{ .StudentName }}</td>168 <td>{{ formatTimeSince .LastUpdated }} ago</td>169 <td>{{ formatTimeSince .FirstUpdate }}</td>170 <td>{{ .LinesOfCode }}</td>171 <td>{{ .NumFeedback }}</td>172 <td>{{ if eq .Status 0 }} Not Submitted {{else if eq .Status 1}} Submitted {{else if eq .Status 2}} <span style="font-size: 1.5em; color: red;"> <i class="far fa-times-circle"></i> </span> {{else if eq .Status 3}} <span style="font-size: 1.5em; color: green;"> <i class="far fa-check-circle"></i> </span> {{end}}</td>173 <td><a href="/get_snapshot?student_id={{ .StudentID }}&problem_id={{ .ProblemID }}&uid={{$.UserID}}&role={{$.UserRole}}&password={{$.Password}}">View</a></td>174 </tr>175 {{ end }}176 </tbody>177 </table>178 </div>179 </body>180 </html>181`182var CODE_SNAPSHOT_TEMPLATE = `183<!DOCTYPE html>184 <html>185 <head>186 <title>Latest Code Snapshot from {{.Snapshot.StudentName}}</title>187 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>188 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>189 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>190 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />191 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />192 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />193 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>194 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>195 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>196 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />197 </head>198 <body>199 <div class="container">200 <section class="section">201 <h3 class="title is-3">Latest Code Snapshot from {{.Snapshot.StudentName}}</h3>202 <h4 class="title is-4">{{.Snapshot.StudentName}} ({{.Snapshot.ProblemName}} @ {{.Snapshot.LastUpdated.Format "Jan 02, 2006 3:04:05 PM"}})</h4>203 <h5 class="title is-5">If you think that this student needs help, feel free to offer a brief comment.</h5>204 {{$l := (len .HelpRequestIDs)}}205 {{if ne $l 0}}206 <b>Help requests: </b>207 {{end}}208 {{range $i, $v := .HelpRequestIDs}}209 <a href="/view_help_request?request_id={{.}}&uid={{$.UserID}}&role={{$.UserRole}}&password={{$.Password}}">Request {{add $i 1}}</a>{{if lt (add $i 1) $l}} | {{end}}210 {{end}}211 <textarea id="editor">{{ .Snapshot.Code }}</textarea>212 </section>213 {{if lt .Snapshot.Status 3}}214 <section class="section" style="margin-top: 0px !important;">215 <form action="/save_snapshot_feedback" method="POST">216 <textarea class="textarea" placeholder="Write your feedback!" name="feedback"></textarea>217 <input class="button" type="submit" value="Send Feedback">218 219 <input type="hidden" name="snapshot_id" value="{{.Snapshot.ID}}">220 <input type="hidden" name="uid" value="{{.UserID}}">221 <input type="hidden" name="role" value="{{.UserRole}}">222 <input type="hidden" name="password" value="{{.Password}}">223 </form>224 </section>225 {{end}}226 <section class="section">227 {{range .Feedbacks}}228 <article class="message">229 <div class="message-header">230 <p>{{.GivenBy}} ({{.FeedbackTime.Format "Jan 02, 2006 3:4:5 PM"}})</p>231 </div>232 <div class="message-body">233 <div class="columns">234 <div class="column is-three-quarters">{{.Feedback}}</div>235 <div class="column">236 <a onclick="autoFeedbackSubmit('yes', {{.FeedbackID}})">237 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "yes"}} color: green; {{end}}">238 <i class="fas fa-thumbs-up"></i>239 </span>240 </a>241 <span>242 {{.Upvote}}243 </span>244 </div>245 <div class="column">246 <a onclick="autoFeedbackSubmit('no', {{.FeedbackID}})">247 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "no"}} color: red; {{end}}">248 <i class="fas fa-thumbs-down"></i>249 </span>250 </a>251 <span>252 {{.Downvote}}253 </span>254 </div>255 </div>256 <div class="codesnapshots">257 <h3>Code Snapshot</h3>258 <div>259 <textarea class="editors">{{ .Code }}</textarea>260 </div>261 </div>262 </div>263 </article>264 {{end}}265 </section>266 </div>267 <script>268 var editor = document.getElementById("editor");269 var myCodeMirror = CodeMirror.fromTextArea(editor, {lineNumbers: true, mode: "{{getEditorMode .Snapshot.ProblemName}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});270 myCodeMirror.setSize("100%", 400)271 var snapshotEditors = document.getElementsByClassName("editors");272 for (i = 0;i<snapshotEditors.length; i++) {273 CodeMirror.fromTextArea(snapshotEditors[i], {lineNumbers: true, mode: "{{getEditorMode .Snapshot.ProblemName}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});274 }275 $( function() {276 $( ".codesnapshots" ).accordion({277 collapsible: true,278 active: false279 });280 } );281 function autoFeedbackSubmit(backFeedback, fID) {282 $.ajax({283 url: "/save_snapshot_back_feedback",284 type: "POST",285 data: {286 feedback: backFeedback,287 feedback_id: fID,288 uid: {{.UserID}},289 role: "{{.UserRole}}",290 password: "{{.Password}}",291 },292 success: function(data){293 console.log("Success!")294 }295 });296 297 location.reload();298 }299 </script>300 </body>301 </html>302`303var STUDENT_VIEWS_FEEDBACK_TEMPLATE = `304<!DOCTYPE html>305 <html>306 <head>307 <title>Review Feedback</title>308 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>309 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>310 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>311 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />312 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />313 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />314 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>315 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>316 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>317 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />318 </head>319 <body>320 <div class="container">321 <h1 class="title">Review Feedback for Problem: {{.Filename}}</h1>322 <div class="tabs is-centered is-boxed is-medium">323 <ul>324 <li {{if eq .ViewType "forme"}}class="is-active"{{end}}>325 <a href="student_views_feedback?pid={{.CurrentPid}}&viewtype=forme&role={{.UserRole}}&uid={{.UserID}}&password={{.Password}}">326 <span class="icon is-small"><i class="fas fa-address-book" aria-hidden="true"></i></span>327 <span>For me</span>328 </a>329 </li>330 <li {{if eq .ViewType "all"}}class="is-active"{{end}}>331 <a href="student_views_feedback?pid={{.CurrentPid}}&viewtype=all&role={{.UserRole}}&uid={{.UserID}}&password={{.Password}}">332 <span class="icon is-small"><i class="fas fa-list-ul" aria-hidden="true"></i></span>333 <span>All</span>334 </a>335 </li>336 </ul>337 </div>338 <section class="section">339 {{range .Feedbacks}}340 <article class="message">341 <div class="message-header">342 <p>{{.GivenBy}} gave feedback on {{$.Filename}} at ({{.FeedbackTime.Format "Jan 02, 2006 3:04:05 PM"}})</p>343 </div>344 <div class="message-body">345 <div class="columns">346 <div class="column is-three-quarters">{{.Feedback}}</div>347 <div class="column">348 <a onclick="autoFeedbackSubmit('yes', {{.FeedbackID}})">349 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "yes"}} color: green; {{end}}">350 <i class="fas fa-thumbs-up"></i>351 </span>352 </a>353 <span>354 {{.Upvote}}355 </span>356 </div>357 <div class="column">358 <a onclick="autoFeedbackSubmit('no', {{.FeedbackID}})">359 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "no"}} color: red; {{end}}">360 <i class="fas fa-thumbs-down"></i>361 </span>362 </a>363 <span>364 {{.Downvote}}365 </span>366 </div>367 </div>368 <div class="codesnapshots">369 <h3>Code Snapshot</h3>370 <div>371 <textarea class="editors">{{ .Code }}</textarea>372 </div>373 </div>374 </div>375 </article>376 {{end}}377 </section>378 <nav class="pagination is-rounded" role="navigation" aria-label="pagination">379 {{if not (eq .NextPid -1)}}380 <a class="pagination-next" href="student_views_feedback?pid={{.NextPid}}&viewtype={{.ViewType}}&role={{.UserRole}}&uid={{.UserID}}&password={{.Password}}">Next</a>381 {{end}}382 <ul class="pagination-list">383 </ul>384 </nav>385 </div>386 <script>387 var snapshotEditors = document.getElementsByClassName("editors");388 389 for (let i = 0; i<snapshotEditors.length; i++){390 CodeMirror.fromTextArea(snapshotEditors[i], {lineNumbers: true, mode: "{{getEditorMode $.Filename}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});391 }392 $( function() {393 $( ".codesnapshots" ).accordion({394 collapsible: true,395 active: false396 });397 } );398 function autoFeedbackSubmit(backFeedback, fID) {399 $.ajax({400 url: "/save_snapshot_back_feedback",401 type: "POST",402 data: {403 feedback: backFeedback,404 feedback_id: fID,405 uid: {{.UserID}},406 role: "{{.UserRole}}",407 password: "{{.Password}}",408 },409 success: function(data){410 console.log("Success!")411 }412 });413 414 location.reload();415 }416 </script>417 </body>418 </html>419`420var TEACHER_VIEWS_FEEDBACK_TEMPLATE = `421<!DOCTYPE html>422 <html>423 <head>424 <title>Review Feedback</title>425 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>426 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>427 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>428 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />429 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />430 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />431 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>432 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>433 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>434 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />435 </head>436 <body>437 <div class="container">438 <<h1 class="title">Review Feedback for Problem: {{.Filename}}</h1>439 <section class="section">440 {{range .Feedbacks}}441 <article class="message">442 <div class="message-header">443 <p>{{.GivenBy}} gave feedback on {{$.Filename}} at ({{.FeedbackTime.Format "Jan 02, 2006 3:04:05 PM"}})</p>444 </div>445 <div class="message-body">446 <div class="columns">447 <div class="column is-three-quarters">{{.Feedback}}</div>448 <div class="column">449 <a onclick="autoFeedbackSubmit('yes', {{.FeedbackID}})">450 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "yes"}} color: green; {{end}}">451 <i class="fas fa-thumbs-up"></i>452 </span>453 </a>454 <span>455 {{.Upvote}}456 </span>457 </div>458 <div class="column">459 <a onclick="autoFeedbackSubmit('no', {{.FeedbackID}})">460 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "no"}} color: red; {{end}}">461 <i class="fas fa-thumbs-down"></i>462 </span>463 </a>464 <span>465 {{.Downvote}}466 </span>467 </div>468 </div>469 <div class="codesnapshots">470 <h3>Code Snapshot</h3>471 <div>472 <textarea class="editors">{{ .Code }}</textarea>473 </div>474 </div>475 </div>476 </article>477 {{end}}478 </section>479 <nav class="pagination is-rounded" role="navigation" aria-label="pagination">480 {{if not (eq .NextPid -1)}}481 <a class="pagination-next" href="teacher_views_feedback?pid={{.NextPid}}&role={{.UserRole}}&uid={{.UserID}}&password={{.Password}}">Next</a>482 {{end}}483 <ul class="pagination-list">484 </ul>485 </nav>486 </div>487 <script>488 var snapshotEditors = document.getElementsByClassName("editors");489 490 for (let i = 0; i<snapshotEditors.length; i++){491 CodeMirror.fromTextArea(snapshotEditors[i], {lineNumbers: true, mode: "{{getEditorMode .Filename}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});492 }493 $( function() {494 $( ".codesnapshots" ).accordion({495 collapsible: true,496 active: false497 });498 } );499 function autoFeedbackSubmit(backFeedback, fID) {500 $.ajax({501 url: "/save_snapshot_back_feedback",502 type: "POST",503 data: {504 feedback: backFeedback,505 feedback_id: fID,506 uid: {{.UserID}},507 role: "{{.UserRole}}",508 password: "{{.Password}}",509 },510 success: function(data){511 console.log("Success!")512 }513 });514 515 location.reload();516 }517 </script>518 </body>519 </html>520`521var HELP_REQUEST_LIST_TEMPLATE = `522 <!DOCTYPE html>523 <html>524 <head>525 <title>Help Hotline</title>526 <meta http-equiv="refresh" content="120" >527 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>528 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />529 </head>530 <body>531 <div class="container">532 <h3 class="title is-3">Help Hotline/<h3>533 <h5 class="title is-5">Currently, there are {{.NumHelpNeeded}} students who need help.</h5>534 <table class="table is-striped is-fullwidth is-hoverable is-narrow">535 <thead>536 <tr>537 <th>Student</th>538 <th>Given At</th>539 <th># of Reply</th>540 <th></th>541 </tr>542 </thead>543 <tbody>544 {{ range .HelpRequests }}545 <tr>546 <td>{{ .StudentName }}</td>547 <td>{{ formatTimeSince .GivenAt }} ago</td>548 <td>{{ .NumReply}}</td>549 <td><a href="/view_help_request?request_id={{.ID}}&uid={{$.UserID}}&role={{$.UserRole}}&password={{$.Password}}">View</a></td>550 </tr>551 {{ end }}552 </tbody>553 </table>554 </div>555 </body>556 </html>557`558var HELP_REQUEST_VIEW_TEMPLATE = `559<!DOCTYPE html>560 <html>561 <head>562 <title>Help Request</title>563 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>564 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>565 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>566 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />567 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />568 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />569 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>570 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>571 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>572 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />573 </head>574 <body>575 <div class="container">576 <h3 class="title is-3">Help Request</h3>577 <section class="section">578 <article class="message">579 <div class="message-header">580 <p>Help Request from {{.StudentName}} At ({{.GivenAt.Format "Jan 02, 2006 3:04:05 PM"}})</p>581 </div>582 <div class="message-body">583 {{.Explanation}}584 </div>585 </article>586 <textarea id="editor">{{ .Snapshot }}</textarea>587 <form action="/save_snapshot_feedback" method="POST">588 <label class="label">Feedback</label>589 <div class="field">590 <textarea class="textarea" placeholder="Write your feedback!" name="feedback"></textarea>591 </div>592 <div class="control">593 <input class="button" type="submit" value="Send Feedback">594 </div>595 596 597 <input type="hidden" name="snapshot_id" value="{{.SnapshotID}}">598 <input type="hidden" name="uid" value="{{.UserID}}">599 <input type="hidden" name="role" value="{{.UserRole}}">600 <input type="hidden" name="password" value="{{.Password}}">601 602 </form>603 <footer class="footer">604 <div class="content has-text-centered">605 <a href="/get_snapshot?snapshot_id={{.SnapshotID}}&uid={{$.UserID}}&role={{$.UserRole}}&password={{$.Password}}">View Snapshot</a>606 </div>607 </footer>608 </section>609 </div>610 </body>611 <script>612 var editor = document.getElementById("editor");613 var myCodeMirror = CodeMirror.fromTextArea(editor, {lineNumbers: true, mode: "{{getEditorMode .ProblemName}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});614 myCodeMirror.setSize("100%", 400)615 616 </script>617 </html>618`619var FEEDBACK_PROVISION_TEMPLATE = `620 <!DOCTYPE html>621 <html>622 <head>623 <title>Student Dashboard</title>624 <meta http-equiv="refresh" content="120" >625 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>626 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />627 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>628 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>629 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>630 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />631 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />632 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>633 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>634 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />635 <script src="https://cdn.jsdelivr.net/npm/@creativebulma/bulma-collapsible"></script>636 </head>637 <body>638 <div class="container">639 <nav class="breadcrumb" aria-label="breadcrumbs">640 <ul>641 <li>642 <a id="view-exercise-link" href="#">643 <span class="icon is-small">644 <i class="fas fa-home" aria-hidden="true"></i>645 </span>646 <span>Exercises</span>647 </a>648 </li>649 <li>650 <a id="problem-dashboard-link" href="#">651 <span class="icon is-small">652 <i class="fas fa-book" aria-hidden="true"></i>653 </span>654 <span>Problem Dashboard ({{.ProblemName}})</span>655 </a>656 </li>657 <li class="is-active">658 <a href="#">659 <span class="icon is-small">660 <i class="fas fa-puzzle-piece" aria-hidden="true"></i>661 </span>662 <span>Student Dashboard</span>663 </a>664 </li>665 </ul>666 </nav>667 <h2 class="title is-2">{{.StudentName}}'s Dashboard for {{.ProblemName}}</h2>668 <div class="tabs">669 <ul>670 <li><a href="/student_dashboard_code_snapshot?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}">Code Snapshot</a></li>671 <li class="is-active"><a>Feedback</a></li>672 <li><a href="/student_dashboard_submissions?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}">Submissions</a></li>673 </ul>674 </div>675 <div>676 <section class="section">677 {{range .Messages}}678 <article class="message">679 <div class="message-header">680 <p>{{if eq .Type 0}}{{.Name}} asked for help{{else}} Snapshot taken {{end}} at ({{.GivenAt.Format "Jan 02, 2006 3:04:05 PM"}})</p>681 </div>682 <div class="message-body">683 {{.Message}}684 </div>685 <div style="margin-left:20px;">686 687 <div class="accordions">688 <h3>Code Snapshot</h3>689 <div>690 <textarea class="editor">{{ .Code }}</textarea>691 </div>692 </div>693 694 {{range .Feedbacks}}695 <article class="message" style="margin-left: 25px;">696 <div class="message-header">697 <p>Reply from {{.Name}} given at {{.GivenAt.Format "Jan 02, 2006 3:04:05 PM"}} </p>698 </div>699 <div class="message-body">700 <div class="columns">701 <div class="column is-three-quarters">{{.Feedback}}</div>702 <div class="column">703 <a onclick="autoFeedbackSubmit('yes', {{.FeedbackID}})">704 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "yes"}} color: green; {{end}}">705 <i class="fas fa-thumbs-up"></i>706 </span>707 </a>708 <span>709 {{.Upvote}}710 </span>711 </div>712 <div class="column">713 <a onclick="autoFeedbackSubmit('no', {{.FeedbackID}})">714 <span style="font-size: 1.5em; {{if eq .CurrentUserVote "no"}} color: red; {{end}}">715 <i class="fas fa-thumbs-down"></i>716 </span>717 </a>718 <span>719 {{.Downvote}}720 </span>721 </div>722 </div>723 </div>724 </article>725 {{end}}726 <div class="columns">727 <div class="column is-three-quarters"><input class="input is-info" id="{{.ID}}" type="text" placeholder="Provide your feedback!"></div>728 <div class="column"><button class="button is-primary" onclick="sendMessageFeedback({{.ID}})">Post</button></div>729 730 </div>731 </div>732 </article>733 734 {{end}}735 </section>736 </div>737 <script>738 $(document).ready(function(){739 $('#view-exercise-link').attr("href", "/view_exercises"+window.location.search);740 $('#problem-dashboard-link').attr("href", "/problem_dashboard"+window.location.search+"&problem_id={{.ProblemID}}");741 });742 var snapshotEditors = document.getElementsByClassName("editor");743 744 for (let i = 0; i<snapshotEditors.length; i++){745 var code = CodeMirror.fromTextArea(snapshotEditors[i], {lineNumbers: true, mode: "{{getEditorMode .ProblemName}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});746 code.setSize("100%", 500);747 }748 function sendMessageFeedback(message_id) {749 var feedback = $('#'+message_id).val();750 if(feedback == "") {751 alert("Please write a feedback!");752 } else {753 $.post("/save_message_feedback", {feedback: feedback, message_id: message_id, uid: {{.UserID}}, role: {{.UserRole}}{{if ne .Password ""}}, password: {{.Password}}{{end}} }, function(data, status){754 if (status == "success"){755 alert("Feedback posted successfully!");756 window.location.reload();757 } else {758 alert("Could not post the feedback. Please try again!");759 }760 });761 }762 }763 $(".accordions").accordion({ header: "h3", active: false, collapsible: true });764 function autoFeedbackSubmit(backFeedback, fID) {765 $.ajax({766 url: "/save_snapshot_back_feedback",767 type: "POST",768 data: {769 feedback: backFeedback,770 feedback_id: fID,771 uid: {{.UserID}},772 role: "{{.UserRole}}",773 {{if ne .Password ""}}password: "{{.Password}}",{{end}}774 },775 success: function(data){776 console.log("Success!")777 }778 });779 780 location.reload();781 }782 </script>783 </body>784 </html>785`786var PROBLEM_DASHBOARD_TEMPLATE = `787<!DOCTYPE html>788<html>789<head>790<title>Problem Dashboard</title>791<meta http-equiv="refresh" content="120" >792<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>793<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>794<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>795<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />796<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />797<script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>798<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />799<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>800<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>801<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />802</head>803<body>804<div class="container">805<nav class="breadcrumb" aria-label="breadcrumbs">806<ul>807 <li>808 <a id="view-exercise-link" href="#">809 <span class="icon is-small">810 <i class="fas fa-home" aria-hidden="true"></i>811 </span>812 <span>Exercises</span>813 </a>814 </li>815 <li class="is-active">816 <a href="#">817 <span class="icon is-small">818 <i class="fas fa-book" aria-hidden="true"></i>819 </span>820 <span>Problem Dashboard</span>821 </a>822 </li>823</ul>824</nav>825 <h2 class="title is-2">Dashboard for {{.ProblemName}}</h2>826 <div class="accordions">827 <h3>{{.ProblemName}}</h3>828 <div>829 <textarea id="editor">{{ .Code }}</textarea>830 </div>831 </div>832 <table class="table">833 <thead>834 <tr>835 <th>Active Students</th>836 <th>Help Requests</th>837 <th>Not Graded</th>838 <th>Correct</th>839 <th>Incorrect</th>840 </tr>841 </thead>842 <tbody>843 <tr>844 <td>{{.NumActive}}</td>845 <td>{{.NumHelpRequest}}</td>846 <td>{{.NumNotGraded}}</td>847 <td>{{.NumGradedCorrect}}</td>848 <td>{{.NumGradedIncorrect}}</td>849 </tr>850 </tbody>851 </table>852 <table class="table">853 <thead>854 <tr>855 <th>Student</th>856 <th>Active</th>857 <th>Coding Status</th>858 <th>Help Status</th>859 <th>Submission Status</th>860 <th>Tutoring Status</th>861 </tr>862 </thead>863 <tbody>864 {{range .StudentInfo}}865 <tr>866 <td><a href="/student_dashboard_code_snapshot?student_id={{.StudentID}}&problem_id={{$.ProblemID}}&uid={{$.UserID}}&role={{$.UserRole}}{{if ne $.Password ""}}&password={{$.Password}}{{end}}">{{.StudentName}}</a></td>867 <td>{{if ne .CodingStat "Idle"}}<a href="/student_dashboard_code_snapshot?student_id={{.StudentID}}&problem_id={{$.ProblemID}}&uid={{$.UserID}}&role={{$.UserRole}}{{if ne $.Password ""}}&password={{$.Password}}{{end}}">{{ formatTimeSince .LastUpdatedAt }} ago</a>{{end}}</td>868 <td>{{.CodingStat}}</td>869 <td>{{if ne .HelpStat ""}}<a href="/student_dashboard_feedback_provision?student_id={{.StudentID}}&problem_id={{$.ProblemID}}&uid={{$.UserID}}&role={{$.UserRole}}{{if ne $.Password ""}}&password={{$.Password}}{{end}}">{{.HelpStat}}</a>{{end}}</td>870 <td>{{if ne .SubmissionStat ""}}<a href="/student_dashboard_submissions?student_id={{.StudentID}}&problem_id={{$.ProblemID}}&uid={{$.UserID}}&role={{$.UserRole}}{{if ne $.Password ""}}&password={{$.Password}}{{end}}">{{.SubmissionStat}}</a>{{end}}</td>871 <td>{{.TutoringStat}}</td>872 </tr>873 {{end}}874 </tbody>875 </table>876 <script>877 var editor = document.getElementById("editor");878 var myCodeMirror = CodeMirror.fromTextArea(editor, {lineNumbers: true, mode: get_editor_mode({{.ProblemName}}), theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});879 myCodeMirror.setSize("100%", 400)880 function get_editor_mode(filename) {881 filename = filename.toLowerCase();882 if (filename.endsWith('.py')) {883 return "python";884 }885 if (filename.endsWith('.java')) {886 return "text/x-java";887 }888 if (filename.endsWith('.cpp') || filename.endsWith('.c++') || filename.endsWith('.c')) {889 return "text/x-c++src";890 }891 return "text";892 }893 $(document).ready(function(){894 $('#view-exercise-link').attr("href", "/view_exercises"+window.location.search);895 });896 $(".accordions").accordion({ header: "h3", active: false, collapsible: true });897 $(".accordions").show();898 </script>899</body>900</html>901`902var PROBLEM_LIST_TEMPLATE = `903<!DOCTYPE html>904<html>905<head>906<title>Exercises</title>907<meta http-equiv="refresh" content="120" >908<script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>909<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />910<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>911</head>912<body>913<div class="container">914 <nav class="breadcrumb" aria-label="breadcrumbs">915 <ul>916 <li class="is-active">917 <a href="#">918 <span class="icon is-small">919 <i class="fas fa-home" aria-hidden="true"></i>920 </span>921 <span>Exercises</span>922 </a>923 </li>924 </ul>925 </nav>926 <h2 class="title is-2">Exercises</h2>927 <a id="new-problem" class="button is-success" href="">928 <span class="icon is-small">929 <i class="fa-solid fa-plus"></i>930 </span>931 <span>Broadcast New Exercise</span>932 </a>933 <table class="table">934 <thead>935 <tr>936 <th>Filename</th>937 <th>Posted At</th>938 <th>Attendance</th>939 <th>Active Students</th>940 <th>Help Requests</th>941 <th>Correct</th>942 <th>Incorrect</th>943 <th>Not Graded</th>944 </tr>945 </thead>946 <tbody>947 {{range .Problems}}948 <tr {{if eq .IsActive true}}class="is-selected"{{end}}>949 <td><a href="/problem_dashboard?problem_id={{.ID}}&uid={{$.UserID}}&role={{$.UserRole}}{{if ne $.Password ""}}&password={{$.Password}}{{end}}">{{.Filename}}</a></td>950 <td>{{ .UploadedAt.Format "Jan 02, 2006 3:04:05 PM" }}</td>951 <td>{{.Attendance}}</td>952 <td>{{.NumActive}}</td>953 <td>{{.NumHelpRequest}}</td>954 <td>{{.NumGradedCorrect}}</td>955 <td>{{.NumGradedIncorrect}}</td>956 <td>{{.NumNotGraded}}</td>957 </tr>958 {{end}}959 </tbody>960 </table>961<script>962$(document).ready(function(){963 $('#new-problem').attr("href", "/teacher_web_broadcast"+window.location.search);964 965});966</script>967</body>968</html>969`970var SUBMISSION_VIEW_TEMPLATE = `971 <!DOCTYPE html>972 <html>973 <head>974 <title>Student Dashboard</title>975 <meta http-equiv="refresh" content="120" >976 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>977 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />978 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>979 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>980 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>981 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />982 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />983 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>984 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>985 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />986 </head>987 <body>988 <div class="container">989 <nav class="breadcrumb" aria-label="breadcrumbs">990 <ul>991 <li>992 <a id="view-exercise-link" href="#">993 <span class="icon is-small">994 <i class="fas fa-home" aria-hidden="true"></i>995 </span>996 <span>Exercises</span>997 </a>998 </li>999 <li>1000 <a id="problem-dashboard-link" href="#">1001 <span class="icon is-small">1002 <i class="fas fa-book" aria-hidden="true"></i>1003 </span>1004 <span>Problem Dashboard ({{.ProblemName}})</span>1005 </a>1006 </li>1007 <li class="is-active">1008 <a href="#">1009 <span class="icon is-small">1010 <i class="fas fa-puzzle-piece" aria-hidden="true"></i>1011 </span>1012 <span>Student Dashboard</span>1013 </a>1014 </li>1015 </ul>1016 </nav>1017 <h2 class="title is-2">{{.StudentName}}'s Submissions for {{.ProblemName}}</h2>1018 <div class="tabs">1019 <ul>1020 <li><a href="/student_dashboard_code_snapshot?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}">Code Snapshot</a></li>1021 <li><a href="/student_dashboard_feedback_provision?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}" >Feedback</a></li>1022 <li class="is-active"><a>Submissions</a></li>1023 </ul>1024 </div>1025 <div>1026 {{range .Submissions}}1027 <h3 class="title is-3">Submitted at {{.SubmittedAt.Format "Jan 02, 2006 3:04:05 PM"}}</h3>1028 {{if eq .Grade ""}} Not Graded {{else}} Graded {{.Grade}} {{end}}1029 <div class="accordions">1030 <h3>Code</h3>1031 <div>1032 <textarea class="editor" id="editor-{{.ID}}">{{ .Code }}</textarea>1033 </div>1034 </div>1035 1036 {{if eq .Grade ""}}1037 <div class="columns">1038 <div class="column is-three-quarters"><input class="input is-info" id="{{.ID}}" type="text" placeholder="Provide your feedback!"></div>1039 <div class="column"><button class="button is-success" onclick="sendGrade({{.ID}}, {{.SnapshotID}}, 'correct')">Correct</button></div>1040 <div class="column"><button class="button is-danger" onclick="sendGrade({{.ID}}, {{.SnapshotID}}, 'incorrect')">Incorrect</button></div>1041 </div>1042 {{end}}1043 {{end}}1044 </div>1045 <script>1046 $(document).ready(function(){1047 $('#view-exercise-link').attr("href", "/view_exercises"+window.location.search);1048 $('#problem-dashboard-link').attr("href", "/problem_dashboard"+window.location.search+"&problem_id={{.ProblemID}}");1049 });1050 var snapshotEditors = document.getElementsByClassName("editor");1051 1052 for (let i = 0; i<snapshotEditors.length; i++){1053 var code = CodeMirror.fromTextArea(snapshotEditors[i], {lineNumbers: true, mode: "{{getEditorMode .ProblemName}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});1054 code.setSize("100%", "auto");1055 }1056 1057 function sendGrade(submission_id, snapshot_id, grade) {1058 var feedback = $('#'+submission_id).val().trim();1059 var code = $('#editor-'+submission_id).val();1060 $.post("/teacher_grades", {content: code, changed: "", decision: grade, sid: submission_id, uid: {{.UserID}}, role: {{.UserRole}}{{if ne .Password ""}}, password: {{.Password}}{{end}} }, function(data, status){1061 if (status == "success"){1062 if (feedback != "") {1063 $.post("/save_snapshot_feedback", {snapshot_id: snapshot_id, feedback: feedback, uid: {{.UserID}}, role: {{.UserRole}}{{if ne .Password ""}}, password: {{.Password}}{{end}} }, function(data1, status1){1064 });1065 }1066 alert("Graded successfully!");1067 window.location.reload();1068 } else {1069 alert("Could not grade the submission. Please try again!");1070 }1071 });1072 }1073 $(".accordions").accordion({ header: "h3", active: false, collapsible: true });1074 </script>1075 </body>1076 </html>1077`1078var TEACHER_LOGIN = `1079<!DOCTYPE html>1080<html>1081 <head>1082 <meta charset="utf-8">1083 <meta name="viewport" content="width=device-width, initial-scale=1">1084 <title>Teacher Login</title>1085 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">1086 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.0/css/bulma.min.css">1087 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>1088 </head>1089 <body>1090 <div class="container">1091 <section class="section"> 1092 <div class="columns">1093 <div class="column is-4 is-offset-4">1094 <div class="field">1095 <p class="control has-icons-left has-icons-right">1096 <input id="name" class="input" type="email" placeholder="Name">1097 <span class="icon is-small is-left">1098 <i class="fa fa-user"></i>1099 </span>1100 <span class="icon is-small is-right">1101 <i class="fa fa-check"></i>1102 </span>1103 </p>1104 </div>1105 <div class="field">1106 <p class="control has-icons-left">1107 <input id="password" class="input" type="password" placeholder="Password">1108 <span class="icon is-small is-left">1109 <i class="fa fa-lock"></i>1110 </span>1111 </p>1112 </div>1113 <div class="field">1114 <p class="control">1115 <button id="login" class="button is-success">1116 Login1117 </button>1118 </p>1119 </div>1120 </div> 1121 </div>1122 </section>1123 </div>1124 <script>1125 $(document).ready(function(){1126 $('#login').click(function(){1127 var name = $('#name').val().trim();1128 var pass = $('#password').val().trim();1129 if(name == "" || pass == "") {1130 alert("Please enter both name and password!");1131 } else {1132 $.post("/teacher_signin_complete", {username: name, password: pass}, function(data, status){1133 if (status == "success"){1134 window.location.replace("/view_exercises?role=teacher&uid="+data);1135 } else {1136 alert("Unauthorized access");1137 }1138 });1139 }1140 });1141 });1142 </script>1143 </body>1144</html>1145`1146var PROBLEM_FILE_UPLOAD_VIEW = `1147<!DOCTYPE html>1148<html>1149 <head>1150 <meta charset="utf-8">1151 <meta name="viewport" content="width=device-width, initial-scale=1">1152 <title>Broadcast Problem</title>1153 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>1154 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />1155 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>1156 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>1157 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>1158 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />1159 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />1160 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>1161 </head>1162 <body>1163 <div class="container">1164 <nav class="breadcrumb" aria-label="breadcrumbs">1165 <ul>1166 <li>1167 <a id="view-exercise-link" href="#">1168 <span class="icon is-small">1169 <i class="fas fa-home" aria-hidden="true"></i>1170 </span>1171 <span>Exercises</span>1172 </a>1173 </li>1174 <li class="is-active">1175 <a href="#">1176 <span class="icon is-small">1177 <i class="fas fa-book" aria-hidden="true"></i>1178 </span>1179 <span>Problem Broadcast</span>1180 </a>1181 </li>1182 </ul>1183 </nav>1184 <div id="problem" class="file is-centered is-boxed is-success has-name">1185 <label class="file-label">1186 <input class="file-input" type="file" name="resume">1187 <span class="file-cta">1188 <span class="file-icon">1189 <i class="fas fa-upload"></i>1190 </span>1191 <span class="file-label">1192 Select Exercise File1193 </span>1194 </span>1195 </label>1196 </div>1197 <div style="visibility:hidden;" id="editor-area">1198 <article class="message">1199 <div class="message-header">1200 <p><span id="filename"></span></p>1201 </div>1202 <div class="message-body">1203 <div>1204 <textarea id="editor"></textarea>1205 </div>1206 </div>1207 </article>1208 </div>1209 <button style="visibility:hidden" id="submit" class="button is-success is-rounded">1210 <span class="icon is-small">1211 <i class="fas fa-check"></i>1212 </span>1213 <span>Broadcast</span>1214 </button>1215 <input type="hidden" id="points" value="">1216 <input type="hidden" id="effort" value="">1217 <input type="hidden" id="attempt" value="">1218 <input type="hidden" id="tag" value="">1219 </div>1220 <script>1221 $(document).ready(function(){1222 $('#view-exercise-link').attr("href", "/view_exercises"+window.location.search);1223 });1224 document.querySelector('#problem input[type=file]').onchange = function(){1225 document.querySelector('#problem').style.visibility = "hidden";1226 var file = this.files[0];1227 document.querySelector('#filename').textContent = file.name;1228 var reader = new FileReader();1229 reader.onload = function(progressEvent){1230 1231 // By lines1232 var lines = this.result.split('\n');1233 var firstLine = lines[0];1234 lines.splice(0, 1);1235 var content = lines.join('\n');1236 if (firstLine.length == 0 || (firstLine[0]!='#' && !firstLine.startsWith('//') )){1237 alert("Invalid problem header!");1238 return;1239 }1240 var prefix = '';1241 if (firstLine[0] == '#') {1242 prefix = '#';1243 firstLine.replace("#", '');1244 } else {1245 prefix = '//';1246 firstLine.replace("//", '');1247 }1248 params = get_problem_info(firstLine);1249 // alert(params[1]+" Points, "+params[2]+" for effort. Maximum attempts: " + params[3]);1250 $('#editor-area').css('visibility', 'visible');1251 document.querySelector('#editor').textContent = prefix + ' ' + params[1]+" Points, "+params[2]+" for effort. Maximum attempts: " + params[3] + "\n" + content;1252 var editor = document.getElementById("editor");1253 var myCodeMirror = CodeMirror.fromTextArea(editor, {lineNumbers: true, mode: get_editor_mode(file.name), theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});1254 myCodeMirror.setSize("100%", 400)1255 $('#submit').css('visibility', 'visible');1256 $('#points').val(params[1]);1257 $('#effort').val(params[2]);1258 $('#attempt').val(params[3]);1259 $('#tag').val(params[4]);1260 };1261 reader.readAsText(file);1262 };1263 1264 function get_problem_info(content) {1265 let regexpNames = /\s*(\d+)\s+(\d+)\s+(\d+)(?:\s+(\w.*))?/mg;1266 let match = regexpNames.exec(content);1267 return match;1268 }1269 function get_editor_mode(filename) {1270 filename = filename.toLowerCase();1271 if (filename.endsWith('.py')) {1272 return "python";1273 }1274 if (filename.endsWith('.java')) {1275 return "text/x-java";1276 }1277 if (filename.endsWith('.cpp') || filename.endsWith('.c++') || filename.endsWith('.c')) {1278 return "text/x-c++src";1279 }1280 return "text";1281 }1282 $(document).ready(function() {1283 $.ajaxSetup({1284 xhrFields: {1285 withCredentials: true1286 }1287 });1288 $('#submit').click(function() {1289 var editor = document.querySelector('.CodeMirror').CodeMirror;1290 var uid = new URLSearchParams(window.location.search).get('uid');1291 var points = $('#points').val();1292 var effort = $('#effort').val();1293 var attempt = $('#attempt').val();1294 var tag = $('#tag').val();1295 var filename = $('#filename').text();1296 $.post("/teacher_broadcasts", {role: "teacher", uid: uid, content: editor.getValue(), answer: "", merit: points, effort: effort, attempts: attempt, tag: tag, filename: filename, exact_answer: true}, function(data, status){1297 if (status == "success"){1298 alert("Exercise broadcasted successfully!");1299 window.location.replace("/view_exercises?role=teacher&uid="+uid);1300 } else {1301 alert("Failed to broadcast. Try agian!");1302 }1303 });1304 });1305 });1306 1307 </script>1308 </body>1309</html>1310`1311var CODE_SNAPSHOT_TAB_TEMPLATE = `1312 <!DOCTYPE html>1313 <html>1314 <head>1315 <title>Student Dashboard</title>1316 <meta http-equiv="refresh" content="120" >1317 <script src="https://kit.fontawesome.com/923539b4ee.js" crossorigin="anonymous"></script>1318 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />1319 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.js" integrity="sha512-hGVnilhYD74EGnPbzyvje74/Urjrg5LSNGx0ARG1Ucqyiaz+lFvtsXk/1jCwT9/giXP0qoXSlVDjxNxjLvmqAw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>1320 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/python/python.min.js" integrity="sha512-/mavDpedrvPG/0Grj2Ughxte/fsm42ZmZWWpHz1jCbzd5ECv8CB7PomGtw0NAnhHmE/lkDFkRMupjoohbKNA1Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>1321 <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/mode/clike/clike.min.js" integrity="sha512-GAled7oA9WlRkBaUQlUEgxm37hf43V2KEMaEiWlvBO/ueP2BLvBLKN5tIJu4VZOTwo6Z4XvrojYngoN9dJw2ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>1322 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/codemirror.min.css" integrity="sha512-6sALqOPMrNSc+1p5xOhPwGIzs6kIlST+9oGWlI4Wwcbj1saaX9J3uzO3Vub016dmHV7hM+bMi/rfXLiF5DNIZg==" crossorigin="anonymous" referrerpolicy="no-referrer" />1323 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.3/theme/monokai.min.css" integrity="sha512-R6PH4vSzF2Yxjdvb2p2FA06yWul+U0PDDav4b/od/oXf9Iw37zl10plvwOXelrjV2Ai7Eo3vyHeyFUjhXdBCVQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />1324 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>1325 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>1326 <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />1327 <script src="https://cdn.jsdelivr.net/npm/@creativebulma/bulma-collapsible"></script>1328 </head>1329 <body>1330 <div class="container">1331 <nav class="breadcrumb" aria-label="breadcrumbs">1332 <ul>1333 <li>1334 <a id="view-exercise-link" href="#">1335 <span class="icon is-small">1336 <i class="fas fa-home" aria-hidden="true"></i>1337 </span>1338 <span>Exercises</span>1339 </a>1340 </li>1341 <li>1342 <a id="problem-dashboard-link" href="#">1343 <span class="icon is-small">1344 <i class="fas fa-book" aria-hidden="true"></i>1345 </span>1346 <span>Problem Dashboard ({{.ProblemName}})</span>1347 </a>1348 </li>1349 <li class="is-active">1350 <a href="#">1351 <span class="icon is-small">1352 <i class="fas fa-puzzle-piece" aria-hidden="true"></i>1353 </span>1354 <span>Student Dashboard</span>1355 </a>1356 </li>1357 </ul>1358 </nav>1359 <h2 class="title is-2">{{.StudentName}}'s Dashboard for {{.ProblemName}}</h2>1360 <div class="tabs">1361 <ul>1362 <li class="is-active"><a>Code Snapshot</a></li>1363 <li><a href="/student_dashboard_feedback_provision?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}">Feedback</a></li>1364 <li><a href="/student_dashboard_submissions?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}">Submissions</a></li>1365 </ul>1366 </div>1367 <div>1368 <h3 class="title is-3">Latest Code Snapshot at {{.LastSnapshot.LastUpdated.Format "Jan 02, 2006 3:04:05 PM"}}</h3>1369 <textarea class="editor">{{ .LastSnapshot.Code }}</textarea>1370 <div class="columns">1371 <div class="column is-three-quarters"><input id="snapshot-feedback-input" class="input is-info" type="text" placeholder="Provide your feedback!"></div>1372 <div class="column"><button id="snapshot-feedback-submit" class="button is-primary">Post</button></div>1373 1374 </div>1375 </div>1376 <script>1377 $(document).ready(function(){1378 $('#view-exercise-link').attr("href", "/view_exercises"+window.location.search);1379 $('#problem-dashboard-link').attr("href", "/problem_dashboard"+window.location.search+"&problem_id={{.ProblemID}}");1380 });1381 var snapshotEditors = document.getElementsByClassName("editor");1382 1383 for (let i = 0; i<snapshotEditors.length; i++){1384 var code = CodeMirror.fromTextArea(snapshotEditors[i], {lineNumbers: true, mode: "{{getEditorMode .ProblemName}}", theme: "monokai", matchBrackets: true, indentUnit: 4, indentWithTabs: true, readOnly: "nocursor"});1385 code.setSize("100%", 500);1386 }1387 1388 $(document).ready(function(){1389 $('#snapshot-feedback-submit').click(function(){1390 var feedback = $('#snapshot-feedback-input').val().trim();1391 if(feedback == "") {1392 alert("Please write a feedback!");1393 } else {1394 $.post("/save_snapshot_feedback", {feedback: feedback, snapshot_id: {{.LastSnapshot.ID}}, uid: {{.UserID}}, role: {{.UserRole}}{{if ne .Password ""}}, password: {{.Password}}{{end}} }, function(data, status){1395 if (status == "success"){1396 alert("Feedback posted successfully!");1397 window.location.replace("/student_dashboard_feedback_provision?student_id={{.StudentID}}&problem_id={{.ProblemID}}&uid={{.UserID}}&role={{.UserRole}}{{if ne .Password ""}}&password={{.Password}}{{end}}");1398 } else {1399 alert("Could not post the feedback. Please try again!");1400 }1401 });1402 }1403 });1404 });1405 </script>1406 </body>1407 </html>1408`...

Full Screen

Full Screen

preloadimage_test.go

Source:preloadimage_test.go Github

copy

Full Screen

1// Copyright 2019 Google LLC2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// https://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14package transformers_test15import (16 "net/url"17 "strings"18 "testing"19 "github.com/ampproject/amppackager/transformer/internal/amphtml"20 "github.com/ampproject/amppackager/transformer/transformers"21 "golang.org/x/net/html"22 "github.com/kylelemons/godebug/diff"23)24type TestCase = struct {25 testcaseName string26 input string27 expected string28}29func transformAndOutput(input string, version int64) (string, error) {30 inputDoc, err := html.Parse(strings.NewReader(input))31 if err != nil {32 return "", err33 }34 inputDOM, err := amphtml.NewDOM(inputDoc)35 if err != nil {36 return "", err37 }38 baseURL, _ := url.Parse("https://www.example.com")39 documentURL, _ := url.Parse("https://www.example.com/foo")40 context := &transformers.Context{41 DOM: inputDOM,42 BaseURL: baseURL,43 DocumentURL: documentURL,44 Version: version,45 }46 transformers.PreloadImage(context)47 var output strings.Builder48 if err := html.Render(&output, inputDoc); err != nil {49 return "", err50 }51 return output.String(), nil52}53func testCases(t *testing.T, cases []TestCase, version int64) {54 for _, tc := range cases {55 t.Run(tc.testcaseName, func(t *testing.T) {56 output, err := transformAndOutput(strings.TrimSpace(tc.input), version)57 if err != nil {58 t.Fatalf("Unexpected error %q", err)59 }60 if diff := diff.Diff(strings.TrimSpace(tc.expected), output); diff != "" {61 t.Errorf("PreloadImage transformer produced unexpected output:\n%s", diff)62 }63 })64 }65}66var testcaseInferSize = []TestCase{67 {68 "inferred-size: Has hero image.",69 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png"></body></html>`,70 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,71 },72 {73 "inferred-size: Dimensions too small",74 `<html><head></head><body><amp-img height="100" src="https://example.com/foo.png" width="100"></amp-img></body></html>`,75 `<html><head></head><body><amp-img height="100" src="https://example.com/foo.png" width="100"></amp-img></body></html>`,76 },77 {78 "inferred-size: Crossorigin attribute.",79 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" crossorigin="anonymous"></body></html>`,80 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" crossorigin="anonymous"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/foo.png"/></amp-img></body></html>`,81 },82 {83 "inferred-size: Referrerpolicy attribute.",84 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" referrerpolicy="origin"></body></html>`,85 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" referrerpolicy="origin"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/foo.png"/></amp-img></body></html>`,86 },87 {88 "inferred-size: Srcset attribute.",89 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></body></html>`,90 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></body></html>`,91 },92 {93 "inferred-size: Srcset without src.",94 `<html><head></head><body><amp-img width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></body></html>`,95 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-img width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></body></html>`,96 },97 {98 "inferred-size: Sizes",99 `<html><head></head><body><amp-img width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" sizes="100vw"></body></html>`,100 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w" imagesizes="100vw"/></head><body><amp-img width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" sizes="100vw" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" sizes="100vw"/></amp-img></body></html>`,101 },102 {103 "inferred-size: Several images",104 `<html><head></head><body><amp-img height="100" src="https://example.com/bar.png" width="100"></amp-img><amp-img width="500" height="400" src="https://example.com/foo.png"></amp-img></body></html>`,105 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img height="100" src="https://example.com/bar.png" width="100"></amp-img><amp-img width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,106 },107 {108 "inferred-size: Several images none qualifies. (all tiny)",109 `<html><head></head><body><amp-img height="100" src="https://example-com.cdn.ampproject.org/bar.png" width="100"></amp-img><amp-img width="100" height="100" src="https://example.com/foo.png"></body></html>`,110 `<html><head></head><body><amp-img height="100" src="https://example-com.cdn.ampproject.org/bar.png" width="100"></amp-img><amp-img width="100" height="100" src="https://example.com/foo.png"></amp-img></body></html>`,111 },112 {113 "inferred-size: Iframe placeholder",114 `<html><head></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/bar.png"></amp-img></amp-iframe></body></html>`,115 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png"/></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png"/></amp-img></amp-iframe></body></html>`,116 },117 {118 "inferred-size: Iframe placeholder crossorigin",119 `<html><head></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/bar.png" crossorigin="anonymous"></amp-img></amp-iframe></body></html>`,120 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png" crossorigin="anonymous"/></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/bar.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/bar.png"/></amp-img></amp-iframe></body></html>`,121 },122 {123 "inferred-size: Iframe placeholder referrerpolicy",124 `<html><head></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/bar.png" referrerpolicy="origin"></amp-img></amp-iframe></body></html>`,125 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png" referrerpolicy="origin"/></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/bar.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/bar.png"/></amp-img></amp-iframe></body></html>`,126 },127 {128 "inferred-size: Iframe placeholder srcset",129 `<html><head></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></amp-img></amp-iframe></body></html>`,130 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></amp-iframe></body></html>`,131 },132 {133 "inferred-size: No placeholder image",134 `<html><head></head><body><amp-iframe src="/foo.html"></amp-iframe></body></html>`,135 `<html><head></head><body><amp-iframe src="/foo.html"></amp-iframe></body></html>`,136 },137 {138 "inferred-size: iframe video placeholder",139 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/foo.png"></amp-video-iframe></body></html>`,140 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></amp-video-iframe></body></html>`,141 },142 {143 "inferred-size: iframe video placeholder crossorigin",144 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/foo.png" crossorigin="anonymous"></amp-video-iframe></body></html>`,145 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" crossorigin="anonymous"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/foo.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/foo.png"/></amp-img></amp-video-iframe></body></html>`,146 },147 {148 "inferred-size: iframe video placeholder referrerpolicy",149 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/foo.png" referrerpolicy="origin"></amp-video-iframe></body></html>`,150 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" referrerpolicy="origin"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/foo.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/foo.png"/></amp-img></amp-video-iframe></body></html>`,151 },152 {153 "inferred-size: iframe video placeholder srcset",154 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></amp-img></amp-video-iframe></body></html>`,155 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></amp-video-iframe></body></html>`,156 },157 {158 "inferred-size: iframe video poster",159 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html" poster="https://example.com/foo.png"></amp-video-iframe></body></html>`,160 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html" poster="https://example.com/foo.png"></amp-video-iframe></body></html>`,161 },162 {163 "inferred-size: iframe video poster crossorigin",164 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" crossorigin="anonymous"></amp-video-iframe></body></html>`,165 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" crossorigin="anonymous"></amp-video-iframe></body></html>`,166 },167 {168 "inferred-size: iframe video poster referrerpolicy",169 `<html><head></head><body><amp-video-iframe height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" referrerpolicy="origin"></amp-video-iframe></body></html>`,170 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" referrerpolicy="origin"></amp-video-iframe></body></html>`,171 },172 {173 "inferred-size: No placeholder image",174 `<html><head></head><body><amp-video-iframe src="/foo.html"></amp-video-iframe></body></html>`,175 `<html><head></head><body><amp-video-iframe src="/foo.html"></amp-video-iframe></body></html>`,176 },177 {178 "inferred-size: Video poster",179 `<html><head></head><body><amp-video poster="https://example.com/foo.png" width="400" height="400"><source src="foo.mp4" /></amp-video></body></html>`,180 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video poster="https://example.com/foo.png" width="400" height="400"><source src="foo.mp4"/></amp-video></body></html>`,181 },182 {183 "inferred-size: Video poster crossorigin",184 `<html><head></head><body><amp-video poster="https://example.com/foo.png" width="400" height="400" crossorigin="anonymous"><source src="foo.mp4" /></amp-video></body></html>`,185 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video poster="https://example.com/foo.png" width="400" height="400" crossorigin="anonymous"><source src="foo.mp4"/></amp-video></body></html>`,186 },187 {188 "inferred-size: Video poster referrerpolicy",189 `<html><head></head><body><amp-video poster="https://example.com/foo.png" width="400" height="400" referrerpolicy="origin"><source src="foo.mp4" /></amp-video></body></html>`,190 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video poster="https://example.com/foo.png" width="400" height="400" referrerpolicy="origin"><source src="foo.mp4"/></amp-video></body></html>`,191 },192 {193 "inferred-size: amp-video with missing poster.",194 `<html><head></head><body><amp-video width="400" height="400"><source src="foo.mp4" /></amp-video></body></html>`,195 `<html><head></head><body><amp-video width="400" height="400"><source src="foo.mp4"/></amp-video></body></html>`,196 },197 {198 "inferred-size: No display layout",199 `<html><head></head><body><amp-img height="500" src="https://example.com/foo.png" width="500" layout="nodisplay"></amp-img></body></html>`,200 `<html><head></head><body><amp-img height="500" src="https://example.com/foo.png" width="500" layout="nodisplay"></amp-img></body></html>`,201 },202 {203 "inferred-size: Same as above with nodisplay layout removed.",204 `<html><head></head><body><amp-img height="500" src="https://example.com/foo.png" width="500"></amp-img></body></html>`,205 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img height="500" src="https://example.com/foo.png" width="500" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,206 },207 {208 "inferred-size: Invalid protocol",209 `<html><head></head><body><amp-img width="500" height="400" src="ftp://example.com/ftp.png"></body></html>`,210 `<html><head></head><body><amp-img width="500" height="400" src="ftp://example.com/ftp.png"></amp-img></body></html>`,211 },212 {213 "inferred-size: Srcset validity. Empty srcset.",214 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset=""></body></html>`,215 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset=""/></amp-img></body></html>`,216 },217 {218 "inferred-size: Invalid srcset",219 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="foo bar baz"></body></html>`,220 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="foo bar baz" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset="foo bar baz"/></amp-img></body></html>`,221 },222 {223 "inferred-size: Invalid srcset duplicates.",224 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="foo 10w, bar 10w, baz 100w"></body></html>`,225 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" srcset="foo 10w, bar 10w, baz 100w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset="foo 10w, bar 10w, baz 100w"/></amp-img></body></html>`,226 },227 {228 "inferred-size: Hero image dimensions from parent container.",229 `<html><head></head><body><div width="500" height="500"><amp-img layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,230 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><div width="500" height="500"><amp-img layout="fill" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></div></body></html>`,231 },232 {233 "inferred-size: Hero image dimesions from parent container, too small.",234 `<html><head></head><body><div width="50" height="50"><amp-img layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,235 `<html><head></head><body><div width="50" height="50"><amp-img layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,236 },237 {238 "inferred-size: No dimensions in parent containers.",239 `<html><head></head><body><div><amp-img layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,240 `<html><head></head><body><div><amp-img layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,241 },242 {243 "inferred-size: No dimension from parent because layout is not responsive or fill",244 `<html><head></head><body><div><amp-img src="https://example.com/foo.png"></amp-img></div></body></html>`,245 `<html><head></head><body><div><amp-img src="https://example.com/foo.png"></amp-img></div></body></html>`,246 },247}248var testcaseDataHero = []TestCase{249 {250 "data-hero",251 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png"></body></html>`,252 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,253 },254 {255 "data-hero: Allows multiple heros",256 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png"></amp-img><amp-img data-hero width="500" height="400" src="https://example.com/bar.png"></amp-img><amp-img data-hero width="500" height="400" src="https://example.com/baz.png"></amp-img></body></html>`,257 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/><link rel="preload" as="image" href="https://example.com/bar.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img><amp-img data-hero="" width="500" height="400" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png"/></amp-img><amp-img data-hero="" width="500" height="400" src="https://example.com/baz.png"></amp-img></body></html>`,258 },259 {260 "data-hero: Prioritizes data-hero",261 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png"></amp-img><amp-img data-hero width="500" height="400" src="https://example.com/bar.png"></amp-img></body></html>`,262 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png"/></head><body><amp-img width="100" height="100" src="https://example.com/foo.png"></amp-img><amp-img data-hero="" width="500" height="400" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png"/></amp-img></body></html>`,263 },264 {265 "data-hero: Prevents size-inferred hero",266 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png"></amp-img><amp-img width="500" height="400" src="https://example.com/bar.png"></amp-img></body></html>`,267 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img><amp-img width="500" height="400" src="https://example.com/bar.png"></amp-img></body></html>`,268 },269 {270 "data-hero: Dimensions too small",271 `<html><head></head><body><amp-img data-hero height="100" src="https://example.com/foo.png" width="100"></amp-img></body></html>`,272 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" height="100" src="https://example.com/foo.png" width="100" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,273 },274 {275 "data-hero: Crossorigin attribute.",276 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png" crossorigin="anonymous"></body></html>`,277 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" crossorigin="anonymous"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/foo.png"/></amp-img></body></html>`,278 },279 {280 "data-hero: Referrerpolicy referrerpolicy.",281 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png" referrerpolicy="origin"></body></html>`,282 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" referrerpolicy="origin"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/foo.png"/></amp-img></body></html>`,283 },284 {285 "data-hero: Srcset attribute.",286 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></body></html>`,287 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></body></html>`,288 },289 {290 "inferred-size: Srcset without src.",291 `<html><head></head><body><amp-img data-hero width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></body></html>`,292 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-img data-hero="" width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></body></html>`,293 },294 {295 "inferred-size: Sizes.",296 `<html><head></head><body><amp-img data-hero width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" sizes="100vw"></body></html>`,297 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w" imagesizes="100vw"/></head><body><amp-img data-hero="" width="500" height="400" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" sizes="100vw" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" sizes="100vw"/></amp-img></body></html>`,298 },299 {300 "data-hero: Iframe placeholder",301 `<html><head></head><body><amp-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/bar.png"></amp-img></amp-iframe></body></html>`,302 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png"/></head><body><amp-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png"/></amp-img></amp-iframe></body></html>`,303 },304 {305 "data-hero: Iframe placeholder crossorigin",306 `<html><head></head><body><amp-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/bar.png" crossorigin="anonymous"></amp-img></amp-iframe></body></html>`,307 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png" crossorigin="anonymous"/></head><body><amp-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/bar.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/bar.png"/></amp-img></amp-iframe></body></html>`,308 },309 {310 "data-hero: Iframe placeholder referrerpolicy",311 `<html><head></head><body><amp-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/bar.png" referrerpolicy="origin"></amp-img></amp-iframe></body></html>`,312 `<html><head><link rel="preload" as="image" href="https://example.com/bar.png" referrerpolicy="origin"/></head><body><amp-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/bar.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/bar.png"/></amp-img></amp-iframe></body></html>`,313 },314 {315 "inferred-size: Iframe placeholder srcset",316 `<html><head></head><body><amp-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></amp-img></amp-iframe></body></html>`,317 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></amp-iframe></body></html>`,318 },319 {320 "data-hero: No placeholder image",321 `<html><head></head><body><amp-iframe data-hero src="/foo.html"></amp-iframe></body></html>`,322 `<html><head></head><body><amp-iframe data-hero="" src="/foo.html"></amp-iframe></body></html>`,323 },324 {325 "data-hero: iframe video placeholder",326 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/foo.png"></amp-video-iframe></body></html>`,327 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></amp-video-iframe></body></html>`,328 },329 {330 "data-hero: iframe video placeholder crossorigin",331 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/foo.png" crossorigin="anonymous"></amp-video-iframe></body></html>`,332 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" crossorigin="anonymous"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/foo.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/foo.png"/></amp-img></amp-video-iframe></body></html>`,333 },334 {335 "data-hero: iframe video placeholder referrerpolicy",336 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" src="https://example.com/foo.png" referrerpolicy="origin"></amp-video-iframe></body></html>`,337 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png" referrerpolicy="origin"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" src="https://example.com/foo.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/foo.png"/></amp-img></amp-video-iframe></body></html>`,338 },339 {340 "inferred-size: iframe video placeholder srcset",341 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html"><amp-img placeholder layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"></amp-img></amp-video-iframe></body></html>`,342 `<html><head><link rel="preload" as="image" imagesrcset="https://example.com/foolarge.png 1200w, https://example.com/foomedium.png 800w"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html"><amp-img placeholder="" layout="fill" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" srcset="https://example.com/foomedium.png 800w, https://example.com/foolarge.png 1200w"/></amp-img></amp-video-iframe></body></html>`,343 },344 {345 "data-hero: iframe video poster",346 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html" poster="https://example.com/foo.png"></amp-video-iframe></body></html>`,347 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html" poster="https://example.com/foo.png"></amp-video-iframe></body></html>`,348 },349 {350 "data-hero: iframe video poster crossorigin",351 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" crossorigin="anonymous"></amp-video-iframe></body></html>`,352 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" crossorigin="anonymous"></amp-video-iframe></body></html>`,353 },354 {355 "data-hero: iframe video poster referrerpolicy",356 `<html><head></head><body><amp-video-iframe data-hero height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" referrerpolicy="origin"></amp-video-iframe></body></html>`,357 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video-iframe data-hero="" height="500" width="500" src="/foo.html" poster="https://example.com/foo.png" referrerpolicy="origin"></amp-video-iframe></body></html>`,358 },359 {360 "data-hero: No placeholder image",361 `<html><head></head><body><amp-video-iframe data-hero src="/foo.html"></amp-video-iframe></body></html>`,362 `<html><head></head><body><amp-video-iframe data-hero="" src="/foo.html"></amp-video-iframe></body></html>`,363 },364 {365 "data-hero: Video poster",366 `<html><head></head><body><amp-video data-hero poster="https://example.com/foo.png" width="400" height="400"><source src="foo.mp4" /></amp-video></body></html>`,367 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video data-hero="" poster="https://example.com/foo.png" width="400" height="400"><source src="foo.mp4"/></amp-video></body></html>`,368 },369 {370 "data-hero: Video poster crossorigin",371 `<html><head></head><body><amp-video data-hero poster="https://example.com/foo.png" width="400" height="400" crossorigin="anonymous"><source src="foo.mp4" /></amp-video></body></html>`,372 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video data-hero="" poster="https://example.com/foo.png" width="400" height="400" crossorigin="anonymous"><source src="foo.mp4"/></amp-video></body></html>`,373 },374 {375 "data-hero: Video poster referrerpolicy",376 `<html><head></head><body><amp-video data-hero poster="https://example.com/foo.png" width="400" height="400" referrerpolicy="origin"><source src="foo.mp4" /></amp-video></body></html>`,377 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-video data-hero="" poster="https://example.com/foo.png" width="400" height="400" referrerpolicy="origin"><source src="foo.mp4"/></amp-video></body></html>`,378 },379 {380 "data-hero: amp-video with missing poster.",381 `<html><head></head><body><amp-video data-hero width="400" height="400"><source src="foo.mp4" /></amp-video></body></html>`,382 `<html><head></head><body><amp-video data-hero="" width="400" height="400"><source src="foo.mp4"/></amp-video></body></html>`,383 },384 {385 "data-hero: No display layout",386 `<html><head></head><body><amp-img data-hero height="500" src="https://example.com/foo.png" width="500" layout="nodisplay"></amp-img></body></html>`,387 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" height="500" src="https://example.com/foo.png" width="500" layout="nodisplay" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,388 },389 {390 "data-hero: Same as above with nodisplay layout removed.",391 `<html><head></head><body><amp-img data-hero height="500" src="https://example.com/foo.png" width="500"></amp-img></body></html>`,392 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" height="500" src="https://example.com/foo.png" width="500" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></body></html>`,393 },394 {395 "data-hero: Invalid protocol",396 `<html><head></head><body><amp-img data-hero width="500" height="400" src="ftp://example.com/ftp.png"></body></html>`,397 `<html><head></head><body><amp-img data-hero="" width="500" height="400" src="ftp://example.com/ftp.png"></amp-img></body></html>`,398 },399 {400 "data-hero: Srcset validity. Empty srcset.",401 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png" srcset=""></body></html>`,402 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" srcset="" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset=""/></amp-img></body></html>`,403 },404 {405 "data-hero: Invalid srcset",406 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png" srcset="foo bar baz"></body></html>`,407 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" srcset="foo bar baz" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset="foo bar baz"/></amp-img></body></html>`,408 },409 {410 "data-hero: Invalid srcset duplicates.",411 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png" srcset="foo 10w, bar 10w, baz 100w"></body></html>`,412 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" srcset="foo 10w, bar 10w, baz 100w" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" srcset="foo 10w, bar 10w, baz 100w"/></amp-img></body></html>`,413 },414 {415 "data-hero: Hero image dimensions from parent container.",416 `<html><head></head><body><div width="500" height="500"><amp-img data-hero layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,417 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><div width="500" height="500"><amp-img data-hero="" layout="fill" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></div></body></html>`,418 },419 {420 "data-hero: Hero image dimesions from parent container, too small.",421 `<html><head></head><body><div width="50" height="50"><amp-img data-hero layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,422 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><div width="50" height="50"><amp-img data-hero="" layout="fill" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></div></body></html>`,423 },424 {425 "data-hero: No dimensions in parent containers.",426 `<html><head></head><body><div><amp-img data-hero layout="fill" src="https://example.com/foo.png"></amp-img></div></body></html>`,427 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><div><amp-img data-hero="" layout="fill" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></div></body></html>`,428 },429 {430 "data-hero: No dimension from parent because layout is not responsive or fill",431 `<html><head></head><body><div><amp-img data-hero src="https://example.com/foo.png"></amp-img></div></body></html>`,432 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><div><amp-img data-hero="" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img></div></body></html>`,433 },434}435var testLazyLoadImg = []TestCase{436 {437 "data-hero leftover",438 `<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png"></amp-img><amp-img width="500" height="400" src="https://example.com/bar.png"></amp-img></body></html>`,439 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img><amp-img width="500" height="400" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png" loading="lazy"/></amp-img></body></html>`,440 },441 {442 "inferred-size leftover",443 `<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png"></amp-img><amp-img width="100" height="100" src="https://example.com/bar.png"></amp-img></body></html>`,444 `<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img><amp-img width="100" height="100" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png" loading="lazy"/></amp-img></body></html>`,445 },446 {447 "no transformed images",448 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png"></amp-img></body></html>`,449 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" loading="lazy"/></amp-img></body></html>`,450 },451 {452 "crossorigin propagates",453 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png" crossorigin="anonymous"></amp-img></body></html>`,454 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png" crossorigin="anonymous" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" crossorigin="anonymous" src="https://example.com/foo.png" loading="lazy"/></amp-img></body></html>`,455 },456 {457 "referrerpolicy propagates",458 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png" referrerpolicy="origin"></amp-img></body></html>`,459 `<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png" referrerpolicy="origin" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" referrerpolicy="origin" src="https://example.com/foo.png" loading="lazy"/></amp-img></body></html>`,460 },461}462func TestInferSizeCases(t *testing.T) {463 testCases(t, testcaseInferSize, 0)464}465func TestDataHeroCases(t *testing.T) {466 testCases(t, testcaseDataHero, 0)467}468func TestLazyLoadCases(t *testing.T) {469 testCases(t, testLazyLoadImg, 5)470}...

Full Screen

Full Screen

html.go

Source:html.go Github

copy

Full Screen

1package printers2import (3 "context"4 "fmt"5 "html/template"6 "strings"7 "github.com/hitzhangjie/go-readability/pkg/logutils"8 "github.com/hitzhangjie/go-readability/pkg/result"9)10const templateContent = `<!doctype html>11<html lang="en">12<head>13 <meta charset="utf-8">14 <title>go-readability</title>15 <link rel="shortcut icon" type="image/png" href="https://go-readability.run/favicon-32x32.png">16 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.2/css/bulma.min.css"17 integrity="sha512-byErQdWdTqREz6DLAA9pCnLbdoGGhXfU6gm1c8bkf7F51JVmUBlayGe2A31VpXWQP+eiJ3ilTAZHCR3vmMyybA=="18 crossorigin="anonymous" referrerpolicy="no-referrer"/>19 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css"20 integrity="sha512-kZqGbhf9JTB4bVJ0G8HCkqmaPcRgo88F0dneK30yku5Y/dep7CZfCnNml2Je/sY4lBoqoksXz4PtVXS4GHSUzQ=="21 crossorigin="anonymous" referrerpolicy="no-referrer"/>22 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js"23 integrity="sha512-s+tOYYcC3Jybgr9mVsdAxsRYlGNq4mlAurOrfNuGMQ/SCofNPu92tjE7YRZCsdEtWL1yGkqk15fU/ark206YTg=="24 crossorigin="anonymous" referrerpolicy="no-referrer"></script>25 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/languages/go.min.js"26 integrity="sha512-+UYV2NyyynWEQcZ4sMTKmeppyV331gqvMOGZ61/dqc89Tn1H40lF05ACd03RSD9EWwGutNwKj256mIR8waEJBQ=="27 crossorigin="anonymous" referrerpolicy="no-referrer"></script>28 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"29 integrity="sha512-qlzIeUtTg7eBpmEaS12NZgxz52YYZVF5myj89mjJEesBd/oE9UPsYOX2QAXzvOAZYEvQohKdcY8zKE02ifXDmA=="30 crossorigin="anonymous" referrerpolicy="no-referrer"></script>31 <script type="text/javascript"32 src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"33 integrity="sha512-9jGNr5Piwe8nzLLYTk8QrEMPfjGU0px80GYzKZUxi7lmCfrBjtyCc1V5kkS5vxVwwIB7Qpzc7UxLiQxfAN30dw=="34 crossorigin="anonymous" referrerpolicy="no-referrer"></script>35 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"36 integrity="sha512-kp7YHLxuJDJcOzStgd6vtpxr4ZU9kjn77e6dBsivSz+pUuAuMlE2UTdKB7jjsWT84qbS8kdCWHPETnP/ctrFsA=="37 crossorigin="anonymous" referrerpolicy="no-referrer"></script>38</head>39<body>40<section class="section">41 <div class="container">42 <div id="content"></div>43 </div>44</section>45<script>46 const data = {{ . }};47</script>48<script type="text/babel">49 class Highlight extends React.Component {50 componentDidMount() {51 hljs.highlightElement(ReactDOM.findDOMNode(this));52 }53 render() {54 return <pre className="go"><code>{this.props.code}</code></pre>;55 }56 }57 class Issue extends React.Component {58 render() {59 return (60 <div className="issue box">61 <div>62 <div className="columns">63 <div className="column is-four-fifths">64 <h5 className="title is-5 has-text-danger-dark">{this.props.data.Title}</h5>65 </div>66 <div className="column is-one-fifth">67 <h6 className="title is-6">{this.props.data.Linter}</h6>68 </div>69 </div>70 <strong>{this.props.data.Pos}</strong>71 </div>72 <div className="highlight">73 <Highlight code={this.props.data.Code}/>74 </div>75 </div>76 );77 }78 }79 class Issues extends React.Component {80 render() {81 if (!this.props.data.Issues || this.props.data.Issues.length === 0) {82 return (83 <div>84 <div className="notification">85 No issues found!86 </div>87 </div>88 );89 }90 return (91 <div className="issues">92 {this.props.data.Issues.map(issue => (<Issue data={issue}/>))}93 </div>94 );95 }96 }97 ReactDOM.render(98 <div className="content">99 <div className="columns is-centered">100 <div className="column is-three-quarters">101 <Issues data={data}/>102 </div>103 </div>104 </div>,105 document.getElementById("content")106 );107</script>108</body>109</html>`110type htmlIssue struct {111 Title string112 Pos string113 Linter string114 Code string115}116type HTML struct{}117func NewHTML() *HTML {118 return &HTML{}119}120func (h HTML) Print(_ context.Context, issues []result.Issue) error {121 var htmlIssues []htmlIssue122 for i := range issues {123 pos := fmt.Sprintf("%s:%d", issues[i].FilePath(), issues[i].Line())124 if issues[i].Pos.Column != 0 {125 pos += fmt.Sprintf(":%d", issues[i].Pos.Column)126 }127 htmlIssues = append(htmlIssues, htmlIssue{128 Title: strings.TrimSpace(issues[i].Text),129 Pos: pos,130 Linter: issues[i].FromLinter,131 Code: strings.Join(issues[i].SourceLines, "\n"),132 })133 }134 t, err := template.New("go-readability").Parse(templateContent)135 if err != nil {136 return err137 }138 return t.Execute(logutils.StdOut, struct{ Issues []htmlIssue }{Issues: htmlIssues})139}...

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.ReferrerPolicyDefault)4 fmt.Println(html.ReferrerPolicyNoReferrer)5 fmt.Println(html.ReferrerPolicyNoReferrerWhenDowngrade)6 fmt.Println(html.ReferrerPolicySameOrigin)7 fmt.Println(html.ReferrerPolicyOrigin)8 fmt.Println(html.ReferrerPolicyStrictOrigin)9 fmt.Println(html.ReferrerPolicyOriginWhenCrossOrigin)10 fmt.Println(html.ReferrerPolicyStrictOriginWhenCrossOrigin)11 fmt.Println(html.ReferrerPolicyUnsafeUrl)12}

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3fmt.Println(html.ReferrerPolicy(0))4fmt.Println(html.ReferrerPolicy(1))5fmt.Println(html.ReferrerPolicy(2))6fmt.Println(html.ReferrerPolicy(3))7fmt.Println(html.ReferrerPolicy(4))8}

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.ReferrerPolicy("strict-origin-when-cross-origin"))4}5Recommended Posts: Golang | html.EscapeString() method6Golang | html.UnescapeString() method7Golang | html.Parse() method8Golang | html.ParseFragment() method9Golang | html.ParseFragmentToken() method10Golang | html.Render() method11Golang | html.Renderer() method12Golang | html.Tokenizer() method13Golang | html.NewTokenizer() method14Golang | html.NewTokenizerFragment() method15Golang | html.Token() method16Golang | html.TokenType() method17Golang | html.NextToken() method18Golang | html.ParseError() method19Golang | html.ParseFragmentError() method20Golang | html.ParseFragmentTokenError() method21Golang | html.RenderError() method22Golang | html.RendererError() method23Golang | html.TokenizerError() method24Golang | html.TokenizerEOF() method25Golang | html.TokenizerHTML() method26Golang | html.TokenizerScript() method27Golang | html.TokenizerStyle() method28Golang | html.TokenizerTag() method29Golang | html.TokenizerText() method30Golang | html.TokenizerComment() method31Golang | html.TokenizerDoctype() method

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3}4import (5func main() {6}7import (8func main() {9}10import (11func main() {12}13import (14func main() {15 }))

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {4 w.Header().Set("Referrer-Policy", "no-referrer")5 fmt.Fprintln(w, "You should not see the referrer in the network tab.")6 })7 log.Fatal(http.ListenAndServe(":8080", nil))8}

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 req, _ := http.NewRequest("GET", u.String(), nil)4 req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0")5 fmt.Println("Referrer policy: ", req.ReferrerPolicy())6}7Recommended Posts: Go | http.Header.Get() method8Go | http.Header.Add() method9Go | http.Header.Del() method10Go | http.Header.Set() method11Go | http.Header.Clone() method12Go | http.Header.Write() method13Go | http.Header.WriteSubset() method14Go | http.Header.Values() method15Go | http.Header.Add() method16Go | http.Header.Set() method17Go | http.Header.Values() method18Go | http.Header.Del() method19Go | http.Header.Get() method20Go | http.Header.Clone() method21Go | http.Header.Write() method22Go | http.Header.WriteSubset() method23Go | http.Header.Clone() method24Go | http.Header.WriteSubset() method25Go | http.Header.Write() method26Go | http.Header.Values() method27Go | http.Header.Del() method28Go | http.Header.Set() method29Go | http.Header.Add() method30Go | http.Header.Get() method31Go | http.Header.Values() method32Go | http.Header.Write() method33Go | http.Header.WriteSubset() method34Go | http.Header.Clone() method35Go | http.Header.Del() method36Go | http.Header.Get() method37Go | http.Header.Set() method38Go | http.Header.Add() method39Go | http.Header.Values() method40Go | http.Header.Get() method41Go | http.Header.Set() method

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1func main() {2 doc, err := html.Parse(strings.NewReader("<html><head><meta http-equiv=\"Referrer-Policy\" content=\"no-referrer\"></head></html>"))3 if err != nil {4 log.Fatal(err)5 }6 referrerPolicy := html.ReferrerPolicy(doc)7 fmt.Println(referrerPolicy)8}

Full Screen

Full Screen

ReferrerPolicy

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.EscapeString(str))4}5import (6func main() {7 fmt.Println(html.EscapeString(str))8}9import (10func main() {11 fmt.Println(html.EscapeString(str))12}13import (14func main() {15 fmt.Println(html.EscapeString(str))16}17import (18func main() {19 fmt.Println(html.EscapeString(str))20}21import (22func main() {23 fmt.Println(html.EscapeString(str))24}25import (26func main() {27 fmt.Println(html.EscapeString(str))28}29import (30func main() {31 fmt.Println(html.EscapeString(str))32}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run K6 automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful