content.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. var port = chrome.runtime.connect({ name: "hello" });
  2. let file = null
  3. let local_file_url = ''
  4. let local_player_state = false
  5. let test_tweet_state = false
  6. let tweet_json = {}
  7. let current_target
  8. let test_list_progress_time = -1
  9. let test_list_progress_duration = 0
  10. // let mediaSource = new MediaSource()
  11. // var mime = 'video/mp4;'
  12. // var sourceBuffer = null
  13. function partFilePost(res, file) {
  14. let buffer_str = ''
  15. let end_index = res.length - 1
  16. for (let i in res) {
  17. buffer_str = arrayBufferToString(res[i])
  18. port.postMessage({ state: 'SEDN_FILE_START', index: i, end_index, buffer_str, name: file.name, type: file.type })
  19. }
  20. }
  21. port.onMessage.addListener(function (res) {
  22. switch (res.state) {
  23. case 'CHECK_MD5_END':
  24. checkMd5(res)
  25. break
  26. case 'SEDN_FILE_END':
  27. // 切换状态
  28. switchState()
  29. break
  30. case 'UPLOAD_FILE':
  31. // 进度
  32. changeProgress(res)
  33. break
  34. case 'UPLOAD_FILE_END':
  35. showPlayer(res)
  36. break
  37. case 'AUDIO_CANPLAY':
  38. current_target.parentNode.querySelector('.test_list_start_time').innerText = '00:00'
  39. current_target.parentNode.querySelector('.test_list_end_time').innerText = formateTime(res.duration)
  40. test_list_progress_duration = res.duration
  41. test_list_progress_time = 0
  42. break
  43. case 'AUDIO_END':
  44. current_target.parentNode.querySelector('.test_list_start_time').innerText = '00:00'
  45. current_target.parentNode.querySelector('.test_list_player_state').src = 'https://webeditter.piaoquantv.com/data/play.png'
  46. current_target.parentNode.querySelector('.test_list_player_state').dataset.state = 'pause'
  47. break
  48. // case 'TEST_VIDEO':
  49. // debugger
  50. // sourceBuffer.appendBuffer(new Uint8Array(stringToArrayBuffer(res.str)))
  51. // break
  52. }
  53. });
  54. // function sourceOpen(){
  55. // console.log('sourceOpen')
  56. // sourceBuffer = mediaSource.addSourceBuffer(mime);
  57. // port.postMessage({state:'TEST_VIDEO'})
  58. // }
  59. // mediaSource.addEventListener('sourceopen', sourceOpen);
  60. function switchState() {
  61. dom.test_player.style.display = 'none'
  62. dom.test_progress.style.display = 'flex'
  63. dom.test_upload.style.display = 'none'
  64. }
  65. function showPlayer(res) {
  66. if (res.code == 0) {
  67. dom.test_player.style.display = 'block'
  68. dom.test_progress.style.display = 'none'
  69. dom.test_upload.style.display = 'none'
  70. tweet_json.url = res.data.url
  71. dom.test_tweet.style.background = '#0091E9'
  72. } else {
  73. dom.test_player.style.display = 'none'
  74. dom.test_progress.style.display = 'none'
  75. dom.test_upload.style.display = 'block'
  76. alert('Upload error')
  77. }
  78. dom.test_progress_detail.style.width = '0px'
  79. }
  80. function changeProgress(res) {
  81. dom.test_player.style.display = 'none'
  82. dom.test_progress.style.display = 'flex'
  83. dom.test_upload.style.display = 'none'
  84. let bili = parseInt(res.bili * 100)
  85. dom.test_progress_detail.style.width = 290 * bili / 100 + 'px'
  86. dom.test_progress_bili.innerText = bili + '%'
  87. }
  88. function checkMd5(res) {
  89. dom.test_upload_error.innerText = ''
  90. dom.test_player_audio.src = local_file_url
  91. if (res.code == 0) {
  92. // 云端有
  93. dom.test_player.style.display = 'block'
  94. dom.test_progress.style.display = 'none'
  95. dom.test_upload.style.display = 'none'
  96. dom.test_start_time.innerText = '00:00'
  97. tweet_json.url = res.data.url
  98. dom.test_tweet.style.background = '#0091E9'
  99. } else {
  100. dom.test_player.style.display = 'none'
  101. dom.test_progress.style.display = 'flex'
  102. dom.test_upload.style.display = 'none'
  103. // 云端没有,执行上传
  104. localFileSlice(file, (res) => {
  105. partFilePost(res, file)
  106. })
  107. }
  108. }
  109. // 获取dom
  110. let dom = {}
  111. function getDOM() {
  112. // dom.text =
  113. }
  114. // 弹框
  115. //
  116. dom.div_layer = document.createElement('div')
  117. dom.div_layer.style = 'width:100%;height:100%; background-color: rgba(0, 0, 0, 0.4); position: fixed; z-index:999; top:0;left:0;'
  118. dom.div_layer_form_html = document.createElement('div')
  119. dom.div_layer_form_html.innerHTML = `
  120. <div class="test_form">
  121. <div class="test_head">
  122. <img src="https://webeditter.piaoquantv.com/data/menu_close.png" class="test_menu_close" />
  123. </div>
  124. <div class="test_content">
  125. <div class="test_type">
  126. <textarea class="test_type_textarea" placeholder="What’s happening?" ></textarea>
  127. </div>
  128. <!-- Upload -->
  129. <div class="test_upload" style="display:none;">
  130. <div class="test_upload_txt">Drag File Upload</div>
  131. <div class="test_upload_note">Mp3 or Wav</div>
  132. <div class="test_upload_btn">Upload</div>
  133. <div class="test_upload_error" hidden>*Only Supports Mp3、Wav</div>
  134. <input type="file" accept="audio/mpeg" hidden class="test_form_file"/>
  135. </div>
  136. <!-- player -->
  137. <div class="test_card test_player" style="display:none;">
  138. <img class="test_player_close" src="https://webeditter.piaoquantv.com/data/close.png" />
  139. <img src="https://webeditter.piaoquantv.com/data/play.png" class="test_player_state" data-state='play'/>
  140. <audio src="" hidden></audio>
  141. <div class="test_progress_point"></div>
  142. <div class="test_progress_time"></div>
  143. <div class="test_start_time">00:00</div>
  144. <div class="test_end_time">01:05</div>
  145. </div>
  146. <div class="test_card test_progress" style="display:none;">
  147. <div class="test_progress_area">
  148. <div class="test_progress_back">
  149. <div class="test_progress_detail"></div>
  150. </div>
  151. <span class="test_progress_bili">0%</span>
  152. </div>
  153. </div>
  154. <div class="test_link">
  155. <input type="text" class="test_link_input" placeholder="Original Aduio Link (Optional)">
  156. </div>
  157. <div class="test_tweet">Tweet</div>
  158. </div>
  159. </div>`
  160. // css
  161. function showError(str) {
  162. dom.test_upload_error.hidden = false
  163. dom.test_upload_error.innerText = str
  164. }
  165. // 事件
  166. // DOM
  167. dom.btn_music = document.createElement('div')
  168. dom.btn_music.className ='test_btn_music'
  169. dom.btn_link = document.createElement('div')
  170. dom.btn_music.className ='test_btn_link'
  171. dom.image = document.createElement('img')
  172. dom.image.src = 'https://webeditter.piaoquantv.com/data/audio_icon.png'
  173. dom.image.width = "20"
  174. dom.image2 = document.createElement('img')
  175. dom.image2.src = 'https://webeditter.piaoquantv.com/data/1.png'
  176. dom.image2.width = "20"
  177. dom.div_layer.hidden = true
  178. document.addEventListener('DOMContentLoaded', function () {
  179. console.log(new Date().getTime())
  180. var iframe = document.createElement('iframe');
  181. iframe.src = chrome.runtime.getURL('iframe.html');
  182. iframe.style.cssText = 'position:fixed;top:0px;right:0;display:block; width:50px;height:50px;z-index:1000; border: medium none;';
  183. iframe.id = 'id12'
  184. iframe.dataset.link = 'https://www.baidu.com'
  185. chrome.storage.onChanged.addListener(changes => {
  186. if (changes.iframe) {
  187. let item = JSON.parse(changes.iframe.newValue)
  188. iframe.style.width = item.width || '0px'
  189. iframe.style.height = item.height || '0px'
  190. iframe.dataset.link = item.url || ''
  191. iframe.contentWindow.postMessage(iframe.dataset.link, '*')
  192. }
  193. })
  194. chrome.storage.sync.get({ iframe: '' }, (item) => {
  195. if (item.iframe) {
  196. item = JSON.parse(item.iframe)
  197. iframe.style.width = item.width || '0px'
  198. iframe.style.height = item.height || '0px'
  199. iframe.dataset.link = item.url || ''
  200. }
  201. })
  202. document.body.appendChild(iframe);
  203. if (window.location.href.indexOf('twitter.com') < 0) {
  204. return
  205. }
  206. dom.btn_music.appendChild(dom.image)
  207. dom.btn_link.appendChild(dom.image2)
  208. dom.div_layer.appendChild(dom.div_layer_form_html)
  209. document.body.appendChild(dom.div_layer)
  210. dom.menu_close = document.querySelector('.test_menu_close')
  211. dom.test_upload_btn = document.querySelector('.test_upload_btn')
  212. dom.test_form_file = document.querySelector('.test_form_file')
  213. dom.test_upload_error = document.querySelector('.test_upload_error')
  214. dom.test_type_textarea = document.querySelector('.test_type_textarea')
  215. dom.test_link_input = document.querySelector('.test_link_input')
  216. dom.test_upload = document.querySelector('.test_upload')
  217. dom.test_progress = document.querySelector('.test_progress')
  218. dom.test_player = document.querySelector('.test_player')
  219. dom.test_player_audio = dom.test_player.querySelector('audio')
  220. dom.test_tweet = document.querySelector('.test_tweet')
  221. dom.test_progress_detail = document.querySelector('.test_progress_detail')
  222. dom.test_progress_bili = document.querySelector('.test_progress_bili')
  223. dom.test_player_close = document.querySelector('.test_player_close')
  224. dom.test_player_state = document.querySelector('.test_player_state')
  225. dom.test_start_time = document.querySelector('.test_start_time')
  226. dom.test_end_time = document.querySelector('.test_end_time')
  227. dom.test_progress_point = document.querySelector('.test_progress_point')
  228. dom.twitter_input = document.querySelector('[contenteditable]')
  229. dom.test_player_audio.addEventListener('canplay', () => {
  230. dom.test_end_time.innerText = formateTime(dom.test_player_audio.duration)
  231. })
  232. dom.test_player_audio.addEventListener('ended', () => {
  233. dom.test_player_state.src = 'https://webeditter.piaoquantv.com/data/play.png'
  234. e.target.dataset.state = 'pause'
  235. dom.test_player_audio.pause()
  236. local_player_state = false
  237. })
  238. dom.test_player_state.addEventListener('click', (e) => {
  239. let state = e.target.dataset.state
  240. if (state == 'play') {
  241. e.target.dataset.state = 'pause'
  242. e.target.src = 'https://webeditter.piaoquantv.com/data/play.png'
  243. dom.test_player_audio.pause()
  244. local_player_state = false
  245. } else {
  246. e.target.dataset.state = 'play'
  247. e.target.src = 'https://webeditter.piaoquantv.com/data/pause.png'
  248. dom.test_player_audio.play()
  249. local_player_state = true
  250. }
  251. })
  252. dom.test_upload.addEventListener('dragover', (e) => {
  253. dom.test_upload.style.background = 'rgba(136, 136, 136, 0.1)'
  254. e.preventDefault();
  255. e.stopPropagation();
  256. })
  257. dom.test_upload.addEventListener('dragenter', (e) => {
  258. e.preventDefault();
  259. e.stopPropagation();
  260. })
  261. dom.test_upload.addEventListener('drop', (e) => {
  262. e.preventDefault();
  263. e.stopPropagation();
  264. var df = e.dataTransfer;
  265. var dropFiles = []; // 存放拖拽的文件对象
  266. let _file
  267. if (df.items !== undefined) {
  268. // Chrome有items属性,对Chrome的单独处理
  269. for (var i = 0; i < df.items.length; i++) {
  270. var item = df.items[i];
  271. // 用webkitGetAsEntry禁止上传目录
  272. if (item.kind === "file" && item.webkitGetAsEntry().isFile) {
  273. _file = item.getAsFile();
  274. dropFiles.push(_file);
  275. }
  276. }
  277. }
  278. if (dropFiles.length == 0) {
  279. showError('Can only is a file')
  280. return
  281. }
  282. if (dropFiles.length > 1) {
  283. showError('Can only one')
  284. return
  285. }
  286. file = dropFiles[0]
  287. let _index = file.name.lastIndexOf(".");
  288. //获取后缀
  289. var ext = file.name.substr(_index + 1);
  290. let typelist = ['mp3', 'wav']
  291. let result = typelist.find(item => item === ext.toLocaleLowerCase());
  292. if (!result) {
  293. showError('File type can only is MP3 or Wav')
  294. return
  295. }
  296. if (file.size > (1024 * 1024 * 100)) {
  297. showError('Cannot exceed 100MB')
  298. return
  299. }
  300. test_tweet_state = true
  301. local_file_url = URL.createObjectURL(file)
  302. //
  303. localFileToMD5(file, (md5) => {
  304. port.postMessage({ state: 'CHECK_MD5_START', md5 })
  305. })
  306. })
  307. dom.test_upload.addEventListener('dragleave', (e) => {
  308. e.preventDefault();
  309. e.stopPropagation();
  310. dom.test_upload.style.background = 'rgba(136, 136, 136, 0.01)'
  311. })
  312. dom.test_player_close.addEventListener('click', (e) => {
  313. dom.test_player.style.display = 'none'
  314. dom.test_progress.style.display = 'none'
  315. dom.test_upload.style.display = 'block'
  316. dom.test_tweet.style.background = '#C4C4C4'
  317. dom.test_progress_point.style.left = `${116}px`
  318. dom.test_player_audio.pause()
  319. dom.test_form_file.value = ''
  320. test_tweet_state = false
  321. if (local_file_url != '') {
  322. URL.revokeObjectURL(local_file_url)
  323. }
  324. })
  325. // dom.div_layer.addEventListener('click',(e)=>{
  326. // dom.div_layer.hidden = true
  327. // e.stopPropagation();
  328. // },false)
  329. dom.test_upload_btn.addEventListener('click', () => {
  330. dom.test_form_file.click()
  331. })
  332. dom.test_form_file.addEventListener('change', (e) => {
  333. file = e.target.files[0]
  334. // 1.check md5
  335. showError('Checking...')
  336. if (file.size > (1024 * 1024 * 100)) {
  337. showError('Cannot exceed 100MB')
  338. return
  339. }
  340. test_tweet_state = true
  341. local_file_url = URL.createObjectURL(file)
  342. //
  343. localFileToMD5(file, (md5) => {
  344. port.postMessage({ state: 'CHECK_MD5_START', md5 })
  345. })
  346. // 2.upload
  347. // 3.进度
  348. })
  349. dom.test_tweet.addEventListener('click', (e) => {
  350. if (!test_tweet_state && tweet_json.type == '') {
  351. return
  352. }
  353. document.querySelector('.r-e7q0ms').children[0].click()
  354. tweet_json.txt = dom.test_type_textarea.value
  355. tweet_json.link = dom.test_link_input.value
  356. if (tweet_json.type == 'iframe') {
  357. let content = '安装 #test 解密此贴文 ! https://test.io/?' + encodeURI(JSON.stringify(tweet_json))
  358. setTimeout(() => {
  359. document.execCommand("insertText", false, content);
  360. }, 500);
  361. dom.div_layer.hidden = true
  362. return
  363. }
  364. document.querySelector('.r-e7q0ms').children[0].click()
  365. document.querySelector('[contenteditable]').focus()
  366. let content = '安装 #test 解密此贴文 ! https://test.io/?' + encodeURI(JSON.stringify(tweet_json)) + ' ' + tweet_json.link
  367. setTimeout(() => {
  368. document.execCommand("insertText", false, content);
  369. }, 500);
  370. dom.div_layer.hidden = true
  371. })
  372. dom.menu_close.addEventListener('click', (e) => {
  373. dom.div_layer.hidden = true
  374. dom.test_tweet.style.background = 'rgb(196, 196, 196)'
  375. dom.test_upload_error.innerText = ''
  376. dom.test_type_textarea.value = ''
  377. dom.test_link_input.value = ''
  378. dom.test_upload_error.hidden = true
  379. })
  380. // let video = document.createElement('video')
  381. // video.style = ` top: 0px;
  382. // left: 0px;
  383. // width: 168px;
  384. // height: 100px;
  385. // position: fixed;
  386. // z-index: 9999;
  387. // border: 1px solid;`
  388. // video.src = URL.createObjectURL(mediaSource)
  389. // video.controls = 'controls'
  390. // document.body.appendChild(video)
  391. }, false)
  392. let timer = setInterval(() => {
  393. if (window.location.href.indexOf('twitter.com') < 0) {
  394. return
  395. }
  396. dom.twitter_nav = document.querySelector('div[data-testid="toolBar"]')
  397. if(!dom.twitter_nav){
  398. return
  399. }
  400. dom.twitter_nav = dom.twitter_nav.children[0]
  401. dom.test_btn_music = document.querySelector('.test_btn_music')
  402. dom.test_btn_link = document.querySelector('.test_btn_link')
  403. if (dom.twitter_nav && !dom.test_btn_music && !dom.test_btn_link) {
  404. dom.twitter_nav.appendChild(dom.btn_music);
  405. dom.twitter_nav.appendChild(dom.btn_link);
  406. dom.btn_music.addEventListener('click', () => {
  407. dom.div_layer.hidden = false
  408. dom.test_upload.style.display = 'block'
  409. tweet_json.type = ''
  410. })
  411. dom.btn_link.addEventListener('click', (e) => {
  412. dom.div_layer.hidden = false
  413. dom.test_upload.style.display = 'none'
  414. document.querySelector('.test_type').style.display = 'none'
  415. dom.test_tweet.style.background = '#0091E9'
  416. tweet_json.type = 'iframe'
  417. })
  418. }
  419. if (local_player_state) {
  420. let bili = dom.test_player_audio.currentTime / dom.test_player_audio.duration
  421. dom.test_progress_point.style.left = `${230 * bili + 116}px`
  422. dom.test_start_time.innerText = formateTime(dom.test_player_audio.currentTime)
  423. }
  424. //
  425. render()
  426. //
  427. if (test_list_progress_time >= 0) {
  428. test_list_progress_time++
  429. let bili = test_list_progress_time / test_list_progress_duration
  430. if (bili <= 1) {
  431. current_target.parentNode.querySelector('.test_list_start_time').innerText = formateTime(test_list_progress_time)
  432. current_target.parentNode.querySelector('.test_list_progress_point').style.left = `${230 * bili + 116}px`
  433. }
  434. }
  435. }, 1000);
  436. window.onbeforeunload = function (ev) {
  437. // port.postMessage({ state: 'AUDIO_PAUSE' })
  438. };
  439. // document.querySelectorAll('.test_post_play').addEventListener('click',function(e){
  440. // e.stopPropagation();
  441. // },true)
  442. document.addEventListener('click', (e) => {
  443. if (e.target.className == 'test_list_player_state') {
  444. current_target = e.target
  445. let url = e.target.dataset.url
  446. if (e.target.dataset.state == 'play') {
  447. test_list_progress_time = -1
  448. e.target.dataset.state = 'pause'
  449. e.target.src = 'https://webeditter.piaoquantv.com/data/play.png'
  450. // 暂停
  451. port.postMessage({ state: 'AUDIO_PAUSE', url })
  452. } else {
  453. e.target.dataset.state = 'play'
  454. e.target.src = 'https://webeditter.piaoquantv.com/data/pause.png'
  455. port.postMessage({ state: 'AUDIO_PLAY', url })
  456. }
  457. e.stopPropagation()
  458. }
  459. }, true)
  460. function render() {
  461. let all = document.querySelectorAll('.r-kzbkwu')
  462. // console.log(all)
  463. let net = 'https://test.io/?'
  464. try {
  465. let all_iframe = document.querySelectorAll('iframe')
  466. for (let j = 0; j < all_iframe.length; j++) {
  467. all_iframe[j].contentWindow.postMessage(all_iframe[j].dataset.link, '*')
  468. }
  469. for (let i in all) {
  470. let _dom = all[i].children[1].children[0].children[0]
  471. let text = _dom.innerText
  472. text = text.replace('…', '')
  473. let num = text.indexOf('安装 #test')
  474. let num2 = text.indexOf(net)
  475. if (num >= 0 && num2 >= 0) {
  476. text = decodeURI(text.substring((num2 + net.length)))
  477. text = text.substring(0, text.indexOf('}') + 1)
  478. let _json = JSON.parse(text)
  479. if (all[i].children[1].children[0].children[0]) {
  480. all[i].children[1].children[0].children[0].remove()
  481. }
  482. let div = document.createElement('div')
  483. if (_json.type == 'iframe') {
  484. var iframe = document.createElement('iframe');
  485. // iframe.src = chrome.runtime.getURL('iframe.html');
  486. iframe.src = _json.link
  487. iframe.id = 'id' + new Date().getTime()
  488. iframe.width = '100%'
  489. iframe.height = '100%'
  490. // iframe.dataset.link = _json.link
  491. iframe.style.cssText = 'width:100%;height:500px';
  492. div.appendChild(iframe)
  493. all[i].children[1].children[0].appendChild(div)
  494. return
  495. }
  496. // } else {
  497. // var iframe = document.createElement('iframe');
  498. // iframe.src = chrome.runtime.getURL('iframe.html');
  499. // // iframe.src = _json.link
  500. // iframe.id = 'id' + new Date().getTime()
  501. // iframe.width = '100%'
  502. // iframe.height = '100%'
  503. // iframe.dataset.url = _json.url
  504. // iframe.style.cssText = 'width:100%;height:500px';
  505. // div.appendChild(iframe)
  506. // all[i].children[1].children[0].appendChild(div)
  507. // }
  508. _json.txt = _json.txt.replace('<', '[')
  509. _json.txt = _json.txt.replace('>', ']')
  510. div.innerHTML = `
  511. <div class="test_list_txt">${_json.txt}</div>
  512. <div class="test_list_link">
  513. <a class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineHover mui-wxdxbxanymd-10p1q4g" href="${_json.link}" target="_blank">
  514. ${_json.link}
  515. </a>
  516. </div>
  517. <div class="test_list_tag"><a class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineHover mui-xvbctlsiwvx-10p1q4g" href="/hashtag/test?src=hashtag_click">#test</a></div>
  518. <div class="test_card test_player" >
  519. <img src="https://webeditter.piaoquantv.com/data/play.png" class="test_list_player_state" data-state='pause' data-url="${_json.url}"/>
  520. <div class="test_list_progress_point"></div>
  521. <div class="test_list_progress_time"></div>
  522. <div class="test_list_start_time"></div>
  523. <div class="test_list_end_time"></div>
  524. </div>`
  525. all[i].children[1].children[0].appendChild(div)
  526. all[i].children[1].children[0].children[0].remove()
  527. }
  528. }
  529. } catch (error) {
  530. }
  531. }