| 97 | | // thumbnail URL |
| 98 | | const thumbnailURL = 'http://tn-skr$HOSTNUMBER.smilevideo.jp/smile?i=$VIDEO_ID'; |
| 99 | | |
| 100 | | // style |
| 101 | | const styles = [ |
| 102 | | '<style type="text/css">', |
| 103 | | 'table.nnp_coop .index { text-align:right; width:2em; }', |
| 104 | | 'table.nnp_coop .thumbnail { text-align:center; }', |
| 105 | | 'table.nnp_coop caption { color:green; }', |
| 106 | | 'table.nnp_coop thead { text-align:center; }', |
| 107 | | '</style>', |
| 108 | | ].join(''); |
| 109 | | |
| 110 | | // table |
| 111 | | const tableTemplate = [ |
| 112 | | '<table class="nnp_coop">', |
| 113 | | '$CAPTION', |
| 114 | | '$THEAD', |
| 115 | | '<tbody>$ITEMS</tbody>', |
| 116 | | '</table>', |
| 117 | | ].join(''); |
| 118 | | |
| 119 | | // table caption |
| 120 | | const captionTemplate = '<caption>now playing: $PLAYTITLE (display $NUMOFDISPLAY / $NUMOFTOTAL$STATUSES)</caption>'; |
| 121 | | |
| 122 | | // table head |
| 123 | | const thead = [ |
| 124 | | '<thead>', |
| 125 | | '<tr>', |
| 126 | | '<td> </td>', |
| 127 | | '<td>thumbnail</td>', |
| 128 | | '<td>title</td>', |
| 129 | | '<td>url</td>', |
| 130 | | '</tr>', |
| 131 | | '</thead>', |
| 132 | | ].join(''); |
| 133 | | |
| 134 | | // item |
| 135 | | const itemHTML = [ |
| 136 | | '<tr>', |
| 137 | | '<td class="index">$INDEX:</td>', |
| 138 | | '<td class="thumbnail"><img src="$THUMBNAILURL" width="33" height="25" /></td>', |
| 139 | | '<td>$TITLE</td>', |
| 140 | | '<td>$URL</td>', |
| 141 | | '</tr>', |
| 142 | | ].join(''); |
| 143 | | |
| 144 | | |
| 200 | | var caption = captionTemplate |
| 201 | | .replace(/\$NUMOFDISPLAY/g, (nodesLength < numofList) ? nodesLength : numofList) |
| 202 | | .replace(/\$NUMOFTOTAL/g, nodesLength) |
| 203 | | .replace(/\$PLAYTITLE/g, playTitle) |
| 204 | | .replace(/\$STATUSES/g, statuses); |
| 205 | | |
| 206 | | // final processing |
| 207 | | var str = styles + tableTemplate.replace(/\$CAPTION/g, caption) |
| 208 | | .replace(/\$THEAD/g, thead) |
| 209 | | .replace(/\$ITEMS/g, items.join('')); |
| 210 | | |
| 211 | | liberator.echo(str, liberator.modules.commandline.FORCE_MULTILINE); |
| 212 | | },{} |
| | 143 | let xml = <> |
| | 144 | {style()} |
| | 145 | {table({ |
| | 146 | numofDisplay: (nodesLength < numofList) ? nodesLength : numofList, |
| | 147 | numofTotal: nodesLength, |
| | 148 | playTitle: getPlayTitle(), |
| | 149 | statuses: getStatusText(playlistNode.id), |
| | 150 | items: items, |
| | 151 | })} |
| | 152 | </> |
| | 153 | |
| | 154 | liberator.echo(xml, liberator.modules.commandline.FORCE_MULTILINE); |
| | 155 | }, |
| | 156 | {} |
| 215 | | // stuff functions |
| | 159 | // define other commands |
| | 160 | // only send CommandEvent to NicoNicoPlaylist script |
| | 161 | [ |
| | 162 | [['nnppushallvideos'], 'push all videos to NicoNicoPlaylist', 'GMNNPPushAllVideos'], |
| | 163 | [['nnppushthisvideo'], 'push current video to NicoNicoPlaylist', 'GMNNPPushThisVideo'], |
| | 164 | [['nnpplaynext'], 'play next in NicoNicoPlaylist', 'GMNNPPlayNext'], |
| | 165 | [['nnpremove'], 'remove item in NicoNicoPlaylist', 'GMNNPRemove'], |
| | 166 | [['nnpclear'], 'clear all items in NicoNicoPlaylist', 'GMNNPClear'], |
| | 167 | [['nnprandom'], 'toggle random mode of NicoNicoPlaylist', 'GMNNPRandom'], |
| | 168 | [['nnploop'], 'toggle loop mode of NicoNicoPlaylist', 'GMNNPLoop'], |
| | 169 | [['nnpfullscreen'], 'toggle fullscreen mode of NicoNicoPlaylist', 'GMNNPFullScreen'], |
| | 170 | ].forEach( function ([command, description, eventname]){ |
| | 171 | liberator.modules.commands.addUserCommand( |
| | 172 | command, |
| | 173 | description, |
| | 174 | function (arg) { |
| | 175 | let r = document.createEvent('CommandEvent'); |
| | 176 | r.initCommandEvent(eventname, true, true, arg[0]); |
| | 177 | window.content.dispatchEvent(r); |
| | 178 | }, |
| | 179 | {} |
| | 180 | ); |
| | 181 | }); |
| | 182 | |
| | 183 | |
| | 184 | // stuff functions --- |
| 229 | | // return snapshot nodes list |
| 230 | | function $s(query, node) { |
| 231 | | node = node || window.content.document; |
| 232 | | var result = (node.ownerDocument || node).evaluate( |
| 233 | | query, |
| 234 | | node, |
| 235 | | null, |
| 236 | | XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, |
| 237 | | null |
| 238 | | ); |
| 239 | | var nodes = []; |
| 240 | | for(let i=0 ; i<result.snapshotLength ; ++i) nodes.push(result.snapshotItem(i)); |
| 241 | | return nodes; |
| 242 | | } |
| 243 | | |
| 244 | | // define other commands |
| 245 | | // only send CommandEvent to NicoNicoPlaylist script |
| 246 | | [ |
| 247 | | [['nnppushallvideos'], "push all videos to NicoNicoPlaylist", 'GMNNPPushAllVideos'], |
| 248 | | [['nnppushthisvideo'], "push current video to NicoNicoPlaylist", 'GMNNPPushThisVideo'], |
| 249 | | [['nnpplaynext'], "play next in NicoNicoPlaylist", 'GMNNPPlayNext'], |
| 250 | | [['nnpremove'], "remove item in NicoNicoPlaylist", 'GMNNPRemove'], |
| 251 | | [['nnpclear'], "clear all items in NicoNicoPlaylist", 'GMNNPClear'], |
| 252 | | [['nnprandom'], "toggle random mode of NicoNicoPlaylist", 'GMNNPRandom'], |
| 253 | | [['nnploop'], "toggle loop mode of NicoNicoPlaylist", 'GMNNPLoop'], |
| 254 | | [['nnpfullscreen'], "toggle fullscreen mode of NicoNicoPlaylist", 'GMNNPFullScreen'], |
| 255 | | ].forEach( |
| 256 | | function ([command, description, eventname]){ |
| 257 | | liberator.modules.commands.addUserCommand(command, description, |
| 258 | | function (arg) { |
| 259 | | var r = document.createEvent("CommandEvent"); |
| 260 | | r.initCommandEvent(eventname, true, true, arg.string); |
| 261 | | window.content.dispatchEvent(r); |
| 262 | | },{} |
| 263 | | ); |
| 264 | | } |
| 265 | | ); |
| | 198 | function getPlayTitle() { |
| | 199 | let titleNode = $f('//h1') || $f('//title'); |
| | 200 | return titleNode.textContent; |
| | 201 | } |
| | 202 | |
| | 203 | function getStatusText(idPrefix) { |
| | 204 | let statuses = []; |
| | 205 | [ |
| | 206 | ['//input[starts-with(@id, "playlist") and contains(@id, "-checkbox-random")]', 'R'], |
| | 207 | ['//input[starts-with(@id, "playlist") and contains(@id, "-checkbox-loop")]', 'L'], |
| | 208 | ['//input[starts-with(@id, "playlist") and contains(@id, "-checkbox-full")]', 'F'], |
| | 209 | ].forEach(function ([query, text]) { |
| | 210 | if ($f(query).checked) statuses.push(text); |
| | 211 | }); |
| | 212 | return (statuses.length) ? ' ' + statuses.join('') : ''; |
| | 213 | } |
| | 214 | |
| | 215 | // thumbnail URL |
| | 216 | // refer: http://d.hatena.ne.jp/ZIGOROu/20081014/1223991205 |
| | 217 | function thumbnailURL(videoId) { |
| | 218 | return [ |
| | 219 | 'http://tn-skr', |
| | 220 | (videoId % 2 + 1), |
| | 221 | '.smilevideo.jp/smile?i=', |
| | 222 | videoId |
| | 223 | ].join(''); |
| | 224 | } |
| | 225 | |
| | 226 | // E4X hell --- |
| | 227 | // style |
| | 228 | function style(css) { |
| | 229 | return <style type="text/css">{[ |
| | 230 | 'table.nnp_coop .index { text-align:right; width:2em; }', |
| | 231 | 'table.nnp_coop .thumbnail { text-align:center; }', |
| | 232 | 'table.nnp_coop caption { color:green; }', |
| | 233 | 'table.nnp_coop thead { text-align:center; }', |
| | 234 | ].join('')}</style> |
| | 235 | } |
| | 236 | |
| | 237 | // table |
| | 238 | function table(data) { |
| | 239 | return <table class="nnp_coop"> |
| | 240 | {caption(data)} |
| | 241 | {thead()} |
| | 242 | <tbody>{liberator.modules.template.map(data.items, item)}</tbody> |
| | 243 | </table> |
| | 244 | } |
| | 245 | |
| | 246 | // table caption |
| | 247 | function caption(data) { |
| | 248 | return <caption>now playing: {data.playTitle} (display {data.numofDisplay} / {data.numofTotal}{data.statuses})</caption> |
| | 249 | } |
| | 250 | |
| | 251 | // table head |
| | 252 | function thead() { |
| | 253 | return <thead> |
| | 254 | <tr> |
| | 255 | <td> </td> |
| | 256 | <td>thumbnail</td> |
| | 257 | <td>title</td> |
| | 258 | <td>url</td> |
| | 259 | </tr> |
| | 260 | </thead> |
| | 261 | } |
| | 262 | |
| | 263 | // item |
| | 264 | function item(datum) { |
| | 265 | return <tr> |
| | 266 | <td class="index">{datum.index}:</td> |
| | 267 | <td class="thumbnail"><img src={datum.thumbnailURL} width="33" height="25" /></td> |
| | 268 | <td>{datum.title}</td> |
| | 269 | <td>{datum.url}</td> |
| | 270 | </tr> |
| | 271 | } |