content.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  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. var iframe = document.createElement('iframe');
  180. // iframe.src = chrome.runtime.getURL('iframe.html');
  181. iframe.style.cssText = 'position:fixed;top:0px;right:0;display:block; width:50px;height:50px;z-index:1000; border: medium none;';
  182. iframe.id = 'id12'
  183. iframe.dataset.link = 'https://www.baidu.com'
  184. chrome.storage.onChanged.addListener(changes => {
  185. if (changes.iframe) {
  186. let item = JSON.parse(changes.iframe.newValue)
  187. iframe.style.width = item.width || '0px'
  188. iframe.style.height = item.height || '0px'
  189. iframe.dataset.link = item.url || ''
  190. // iframe.contentWindow.postMessage(iframe.dataset.link, '*')
  191. iframe.src= item.url || ''
  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. // iframe.contentWindow.postMessage(iframe.dataset.link, '*')
  201. iframe.src= item.url || ''
  202. }
  203. })
  204. document.body.appendChild(iframe);
  205. if (window.location.href.indexOf('twitter.com') < 0) {
  206. return
  207. }
  208. dom.btn_music.appendChild(dom.image)
  209. dom.btn_link.appendChild(dom.image2)
  210. dom.div_layer.appendChild(dom.div_layer_form_html)
  211. document.body.appendChild(dom.div_layer)
  212. dom.menu_close = document.querySelector('.test_menu_close')
  213. dom.test_upload_btn = document.querySelector('.test_upload_btn')
  214. dom.test_form_file = document.querySelector('.test_form_file')
  215. dom.test_upload_error = document.querySelector('.test_upload_error')
  216. dom.test_type_textarea = document.querySelector('.test_type_textarea')
  217. dom.test_link_input = document.querySelector('.test_link_input')
  218. dom.test_upload = document.querySelector('.test_upload')
  219. dom.test_progress = document.querySelector('.test_progress')
  220. dom.test_player = document.querySelector('.test_player')
  221. dom.test_player_audio = dom.test_player.querySelector('audio')
  222. dom.test_tweet = document.querySelector('.test_tweet')
  223. dom.test_progress_detail = document.querySelector('.test_progress_detail')
  224. dom.test_progress_bili = document.querySelector('.test_progress_bili')
  225. dom.test_player_close = document.querySelector('.test_player_close')
  226. dom.test_player_state = document.querySelector('.test_player_state')
  227. dom.test_start_time = document.querySelector('.test_start_time')
  228. dom.test_end_time = document.querySelector('.test_end_time')
  229. dom.test_progress_point = document.querySelector('.test_progress_point')
  230. dom.twitter_input = document.querySelector('[contenteditable]')
  231. dom.test_player_audio.addEventListener('canplay', () => {
  232. dom.test_end_time.innerText = formateTime(dom.test_player_audio.duration)
  233. })
  234. dom.test_player_audio.addEventListener('ended', () => {
  235. dom.test_player_state.src = 'https://webeditter.piaoquantv.com/data/play.png'
  236. e.target.dataset.state = 'pause'
  237. dom.test_player_audio.pause()
  238. local_player_state = false
  239. })
  240. dom.test_player_state.addEventListener('click', (e) => {
  241. let state = e.target.dataset.state
  242. if (state == 'play') {
  243. e.target.dataset.state = 'pause'
  244. e.target.src = 'https://webeditter.piaoquantv.com/data/play.png'
  245. dom.test_player_audio.pause()
  246. local_player_state = false
  247. } else {
  248. e.target.dataset.state = 'play'
  249. e.target.src = 'https://webeditter.piaoquantv.com/data/pause.png'
  250. dom.test_player_audio.play()
  251. local_player_state = true
  252. }
  253. })
  254. dom.test_upload.addEventListener('dragover', (e) => {
  255. dom.test_upload.style.background = 'rgba(136, 136, 136, 0.1)'
  256. e.preventDefault();
  257. e.stopPropagation();
  258. })
  259. dom.test_upload.addEventListener('dragenter', (e) => {
  260. e.preventDefault();
  261. e.stopPropagation();
  262. })
  263. dom.test_upload.addEventListener('drop', (e) => {
  264. e.preventDefault();
  265. e.stopPropagation();
  266. var df = e.dataTransfer;
  267. var dropFiles = []; // 存放拖拽的文件对象
  268. let _file
  269. if (df.items !== undefined) {
  270. // Chrome有items属性,对Chrome的单独处理
  271. for (var i = 0; i < df.items.length; i++) {
  272. var item = df.items[i];
  273. // 用webkitGetAsEntry禁止上传目录
  274. if (item.kind === "file" && item.webkitGetAsEntry().isFile) {
  275. _file = item.getAsFile();
  276. dropFiles.push(_file);
  277. }
  278. }
  279. }
  280. if (dropFiles.length == 0) {
  281. showError('Can only is a file')
  282. return
  283. }
  284. if (dropFiles.length > 1) {
  285. showError('Can only one')
  286. return
  287. }
  288. file = dropFiles[0]
  289. let _index = file.name.lastIndexOf(".");
  290. //获取后缀
  291. var ext = file.name.substr(_index + 1);
  292. let typelist = ['mp3', 'wav']
  293. let result = typelist.find(item => item === ext.toLocaleLowerCase());
  294. if (!result) {
  295. showError('File type can only is MP3 or Wav')
  296. return
  297. }
  298. if (file.size > (1024 * 1024 * 100)) {
  299. showError('Cannot exceed 100MB')
  300. return
  301. }
  302. test_tweet_state = true
  303. local_file_url = URL.createObjectURL(file)
  304. //
  305. localFileToMD5(file, (md5) => {
  306. port.postMessage({ state: 'CHECK_MD5_START', md5 })
  307. })
  308. })
  309. dom.test_upload.addEventListener('dragleave', (e) => {
  310. e.preventDefault();
  311. e.stopPropagation();
  312. dom.test_upload.style.background = 'rgba(136, 136, 136, 0.01)'
  313. })
  314. dom.test_player_close.addEventListener('click', (e) => {
  315. dom.test_player.style.display = 'none'
  316. dom.test_progress.style.display = 'none'
  317. dom.test_upload.style.display = 'block'
  318. dom.test_tweet.style.background = '#C4C4C4'
  319. dom.test_progress_point.style.left = `${116}px`
  320. dom.test_player_audio.pause()
  321. dom.test_form_file.value = ''
  322. test_tweet_state = false
  323. if (local_file_url != '') {
  324. URL.revokeObjectURL(local_file_url)
  325. }
  326. })
  327. // dom.div_layer.addEventListener('click',(e)=>{
  328. // dom.div_layer.hidden = true
  329. // e.stopPropagation();
  330. // },false)
  331. dom.test_upload_btn.addEventListener('click', () => {
  332. dom.test_form_file.click()
  333. })
  334. dom.test_form_file.addEventListener('change', (e) => {
  335. file = e.target.files[0]
  336. // 1.check md5
  337. showError('Checking...')
  338. if (file.size > (1024 * 1024 * 100)) {
  339. showError('Cannot exceed 100MB')
  340. return
  341. }
  342. test_tweet_state = true
  343. local_file_url = URL.createObjectURL(file)
  344. //
  345. localFileToMD5(file, (md5) => {
  346. port.postMessage({ state: 'CHECK_MD5_START', md5 })
  347. })
  348. // 2.upload
  349. // 3.进度
  350. })
  351. dom.test_tweet.addEventListener('click', (e) => {
  352. if (!test_tweet_state && tweet_json.type == '') {
  353. return
  354. }
  355. document.querySelector('.r-e7q0ms').children[0].click()
  356. tweet_json.txt = dom.test_type_textarea.value
  357. tweet_json.link = dom.test_link_input.value
  358. if (tweet_json.type == 'iframe') {
  359. let content = '安装 #test 解密此贴文 ! https://test.io/?' + encodeURI(JSON.stringify(tweet_json))
  360. setTimeout(() => {
  361. document.execCommand("insertText", false, content);
  362. }, 500);
  363. dom.div_layer.hidden = true
  364. return
  365. }
  366. document.querySelector('.r-e7q0ms').children[0].click()
  367. document.querySelector('[contenteditable]').focus()
  368. let content = '安装 #test 解密此贴文 ! https://test.io/?' + encodeURI(JSON.stringify(tweet_json)) + ' ' + tweet_json.link
  369. setTimeout(() => {
  370. document.execCommand("insertText", false, content);
  371. }, 500);
  372. dom.div_layer.hidden = true
  373. })
  374. dom.menu_close.addEventListener('click', (e) => {
  375. dom.div_layer.hidden = true
  376. dom.test_tweet.style.background = 'rgb(196, 196, 196)'
  377. dom.test_upload_error.innerText = ''
  378. dom.test_type_textarea.value = ''
  379. dom.test_link_input.value = ''
  380. dom.test_upload_error.hidden = true
  381. })
  382. // let video = document.createElement('video')
  383. // video.style = ` top: 0px;
  384. // left: 0px;
  385. // width: 168px;
  386. // height: 100px;
  387. // position: fixed;
  388. // z-index: 9999;
  389. // border: 1px solid;`
  390. // video.src = URL.createObjectURL(mediaSource)
  391. // video.controls = 'controls'
  392. // document.body.appendChild(video)
  393. }, false)
  394. let timer = setInterval(() => {
  395. if (window.location.href.indexOf('twitter.com') < 0) {
  396. return
  397. }
  398. dom.twitter_nav = document.querySelector('div[data-testid="toolBar"]')
  399. if(!dom.twitter_nav){
  400. return
  401. }
  402. dom.twitter_nav = dom.twitter_nav.children[0]
  403. dom.test_btn_music = document.querySelector('.test_btn_music')
  404. dom.test_btn_link = document.querySelector('.test_btn_link')
  405. if (dom.twitter_nav && !dom.test_btn_music && !dom.test_btn_link) {
  406. dom.twitter_nav.appendChild(dom.btn_music);
  407. dom.twitter_nav.appendChild(dom.btn_link);
  408. dom.btn_music.addEventListener('click', () => {
  409. dom.div_layer.hidden = false
  410. dom.test_upload.style.display = 'block'
  411. tweet_json.type = ''
  412. })
  413. dom.btn_link.addEventListener('click', (e) => {
  414. dom.div_layer.hidden = false
  415. dom.test_upload.style.display = 'none'
  416. document.querySelector('.test_type').style.display = 'none'
  417. dom.test_tweet.style.background = '#0091E9'
  418. tweet_json.type = 'iframe'
  419. })
  420. }
  421. if (local_player_state) {
  422. let bili = dom.test_player_audio.currentTime / dom.test_player_audio.duration
  423. dom.test_progress_point.style.left = `${230 * bili + 116}px`
  424. dom.test_start_time.innerText = formateTime(dom.test_player_audio.currentTime)
  425. }
  426. //
  427. render()
  428. //
  429. if (test_list_progress_time >= 0) {
  430. test_list_progress_time++
  431. let bili = test_list_progress_time / test_list_progress_duration
  432. if (bili <= 1) {
  433. current_target.parentNode.querySelector('.test_list_start_time').innerText = formateTime(test_list_progress_time)
  434. current_target.parentNode.querySelector('.test_list_progress_point').style.left = `${230 * bili + 116}px`
  435. }
  436. }
  437. }, 1000);
  438. window.onbeforeunload = function (ev) {
  439. // port.postMessage({ state: 'AUDIO_PAUSE' })
  440. };
  441. // document.querySelectorAll('.test_post_play').addEventListener('click',function(e){
  442. // e.stopPropagation();
  443. // },true)
  444. document.addEventListener('click', (e) => {
  445. if (e.target.className == 'test_list_player_state') {
  446. current_target = e.target
  447. let url = e.target.dataset.url
  448. if (e.target.dataset.state == 'play') {
  449. test_list_progress_time = -1
  450. e.target.dataset.state = 'pause'
  451. e.target.src = 'https://webeditter.piaoquantv.com/data/play.png'
  452. // 暂停
  453. port.postMessage({ state: 'AUDIO_PAUSE', url })
  454. } else {
  455. e.target.dataset.state = 'play'
  456. e.target.src = 'https://webeditter.piaoquantv.com/data/pause.png'
  457. port.postMessage({ state: 'AUDIO_PLAY', url })
  458. }
  459. e.stopPropagation()
  460. }
  461. }, true)
  462. function render() {
  463. let all = document.querySelectorAll('.r-kzbkwu')
  464. // console.log(all)
  465. let net = 'https://test.io/?'
  466. try {
  467. let all_iframe = document.querySelectorAll('iframe')
  468. for (let j = 0; j < all_iframe.length; j++) {
  469. all_iframe[j].contentWindow.postMessage(all_iframe[j].dataset.link, '*')
  470. }
  471. for (let i in all) {
  472. let _dom = all[i].children[1].children[0].children[0]
  473. let text = _dom.innerText
  474. text = text.replace('…', '')
  475. let num = text.indexOf('安装 #test')
  476. let num2 = text.indexOf(net)
  477. if (num >= 0 && num2 >= 0) {
  478. text = decodeURI(text.substring((num2 + net.length)))
  479. text = text.substring(0, text.indexOf('}') + 1)
  480. let _json = JSON.parse(text)
  481. if (all[i].children[1].children[0].children[0]) {
  482. all[i].children[1].children[0].children[0].remove()
  483. }
  484. let div = document.createElement('div')
  485. if (_json.type == 'iframe') {
  486. var iframe = document.createElement('iframe');
  487. // iframe.src = chrome.runtime.getURL('iframe.html');
  488. iframe.src = _json.link
  489. iframe.id = 'id' + new Date().getTime()
  490. iframe.width = '100%'
  491. iframe.height = '100%'
  492. // iframe.dataset.link = _json.link
  493. iframe.style.cssText = 'width:100%;height:500px';
  494. div.appendChild(iframe)
  495. all[i].children[1].children[0].appendChild(div)
  496. return
  497. }
  498. // } else {
  499. // var iframe = document.createElement('iframe');
  500. // iframe.src = chrome.runtime.getURL('iframe.html');
  501. // // iframe.src = _json.link
  502. // iframe.id = 'id' + new Date().getTime()
  503. // iframe.width = '100%'
  504. // iframe.height = '100%'
  505. // iframe.dataset.url = _json.url
  506. // iframe.style.cssText = 'width:100%;height:500px';
  507. // div.appendChild(iframe)
  508. // all[i].children[1].children[0].appendChild(div)
  509. // }
  510. _json.txt = _json.txt.replace('<', '[')
  511. _json.txt = _json.txt.replace('>', ']')
  512. div.innerHTML = `
  513. <div class="test_list_txt">${_json.txt}</div>
  514. <div class="test_list_link">
  515. <a class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineHover mui-wxdxbxanymd-10p1q4g" href="${_json.link}" target="_blank">
  516. ${_json.link}
  517. </a>
  518. </div>
  519. <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>
  520. <div class="test_card test_player" >
  521. <img src="https://webeditter.piaoquantv.com/data/play.png" class="test_list_player_state" data-state='pause' data-url="${_json.url}"/>
  522. <div class="test_list_progress_point"></div>
  523. <div class="test_list_progress_time"></div>
  524. <div class="test_list_start_time"></div>
  525. <div class="test_list_end_time"></div>
  526. </div>`
  527. all[i].children[1].children[0].appendChild(div)
  528. all[i].children[1].children[0].children[0].remove()
  529. }
  530. }
  531. } catch (error) {
  532. }
  533. }