twitter.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. import { getChromeStorage, setChromeStorage, LANDING_PAGE } from '@/uilts/chromeExtension.js'
  2. import { throttle } from '@/uilts/help'
  3. import { getTtwitterRequestToken, twitterLogin, httpTwitterShortUrl } from '../server/twitter.js'
  4. import { srcPublishSuccess } from '@/http/publishApi'
  5. import Report from "@/log-center/log"
  6. let dom = {};
  7. export function contentTwitterPinLogin(port) {
  8. if (window.location.href == 'https://api.twitter.com/oauth/authorize') {
  9. let code = document.querySelector('code')
  10. if (code) {
  11. port.postMessage({ state: 'CONTENT_SEND_CODE', code: code.innerText })
  12. }
  13. }
  14. }
  15. let authToken = ''
  16. export function backTwitterPinLoginToken() {
  17. // 1.判断是否登陆了
  18. getChromeStorage('userInfo', (res) => {
  19. // 没有登陆
  20. if (!res) {
  21. getTtwitterRequestToken().then((res) => {
  22. authToken = res.data.authToken
  23. chrome.tabs.create({
  24. url: `https://api.twitter.com/oauth/authorize?oauth_token=${res.data.authToken}`
  25. })
  26. })
  27. }
  28. })
  29. }
  30. export function backTwitterPinLoginCode(code) {
  31. // 关闭code页面
  32. chrome.tabs.query({}, (tab) => {
  33. for (let i in tab) {
  34. console.log(tab[i])
  35. if (tab[i].url == 'https://api.twitter.com/oauth/authorize') {
  36. chrome.tabs.remove(tab[i].id)
  37. }
  38. }
  39. })
  40. chrome.cookies.getAll(LANDING_PAGE, (e = []) => {
  41. let _str = '[]'
  42. if (e.length > 0) {
  43. _str = e[0].value
  44. }
  45. let _arr = JSON.parse(decodeURIComponent(_str))
  46. let receivedIds = []
  47. if (_arr.length > 0) {
  48. for (let i in _arr) {
  49. receivedIds.push(_arr[i].receivedId)
  50. }
  51. }
  52. // 发送请求
  53. // token,code
  54. twitterLogin(authToken, code, receivedIds).then(res => {
  55. if (res.code == 0) {
  56. setChromeStorage({ userInfo: JSON.stringify(res.data) })
  57. chrome.cookies.remove(LANDING_PAGE)
  58. }
  59. })
  60. }
  61. )
  62. }
  63. export function backHttpTwitterShortUrl(url) {
  64. return new Promise(function (resolve, reject) {
  65. httpTwitterShortUrl(url).then(res => {
  66. let _str_arr = res.match(/denetme.net\/([\s\S]*?)"/) || []
  67. let _post_id = _str_arr[1] || ''
  68. console.log('_str_arr_post_id', _post_id)
  69. if (!_post_id) {
  70. return
  71. }
  72. // 解析
  73. let _obj = {
  74. url,
  75. post_id: _post_id
  76. // tweet_id
  77. }
  78. getChromeStorage('sortLink', item => {
  79. if (item) {
  80. for (let i in item) {
  81. if (item[i].url == _obj.url) {
  82. item[i] = _obj
  83. }
  84. // else{
  85. // delete item[i].tweet_id
  86. // }
  87. }
  88. setChromeStorage({ sortLink: JSON.stringify(item) })
  89. } else {
  90. setChromeStorage({ sortLink: JSON.stringify([_obj]) })
  91. }
  92. resolve({
  93. post_id: _post_id
  94. })
  95. })
  96. })
  97. })
  98. }
  99. /**
  100. * 渲染要插入的dom,初始化逻辑
  101. * @param port
  102. */
  103. export function renderDom(port) {
  104. if (window.location.href.indexOf('https://twitter.com') > -1) {
  105. _createBtnDom(port);
  106. onWindowResize();
  107. checkHasDeBtn();
  108. setTimeout(() => {
  109. _addIframe();
  110. _addDeNetBtn();
  111. _getSliderTwitterBtn();
  112. }, 800)
  113. }
  114. }
  115. /**
  116. * 展示give弹窗
  117. */
  118. export function showGiveDialogHandler(userInfo) {
  119. let iframe = document.getElementById('iframe-content');
  120. if (iframe) {
  121. iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', userInfo }, '*');
  122. } else {
  123. _addIframe();
  124. let iframe = document.getElementById('iframe-content');
  125. iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', userInfo }, '*');
  126. }
  127. }
  128. export function showIframeHandler() {
  129. document.getElementById('iframe-content').style.display = 'block';
  130. }
  131. export function hideIframeHandler() {
  132. document.getElementById('iframe-content').style.display = 'none';
  133. }
  134. /**
  135. * 展示twitter原生发布框
  136. */
  137. export function showTwitterPublishDialogHandler(publishRes) {
  138. dom.tweetBtn.click();
  139. _setPublishContent(publishRes.srcContent);
  140. _publishTweetEvent(publishRes.postId);
  141. }
  142. export function showPinTips() {
  143. getChromeStorage('pinData', (res) => {
  144. if (!res || res.show) {
  145. let domPop = document.getElementById('de-pin-pop');
  146. domPop.style.display = 'block';
  147. }
  148. })
  149. }
  150. export function addPinedPop() {
  151. let domPop = document.getElementById('de-pin-pop');
  152. if (domPop) {
  153. return;
  154. }
  155. let popWrapper = document.createElement('div');
  156. popWrapper.style.cssText = 'position: fixed; height: 400px;width: 300px;top: 12px;right: 20px;border-radius: 12px;border: 0.5px solid #919191;box-sizing: border-box;padding: 20px;background: #fff;display:none';
  157. popWrapper.id = 'de-pin-pop'
  158. let img = document.createElement('img');
  159. img.src = require("@/assets/img/img-pined-guide.png");
  160. let contentDom = document.createElement('div');
  161. contentDom.innerHTML = "<div style='font-weight: 500;font-size: 18px;margin-top: 20px;margin-bottom: 20px'>📌 Pin an Extension is more convenient to open😄</div><div style='display: flex; align-items: center; justify-content: space-between;'><div style='display: flex; align-items: center; font-size: 14px; color: #899099; cursor: pointer;' id='de-remind'><input id='de-check' type='checkbox'/> Don't remind</div><div class='de-pin-skip' style='font-weight: 500; font-size: 16px; color: #1D9BF0;cursor: pointer;'>Skip</div></div>"
  162. popWrapper.appendChild(img);
  163. popWrapper.appendChild(contentDom);
  164. document.querySelector('body').appendChild(popWrapper);
  165. let deCheck = document.querySelector('#de-check');
  166. let deRemind = document.querySelector('#de-remind');
  167. deCheck.onclick = function (e) {
  168. e && e.stopPropagation && e.stopPropagation();
  169. setChromeStorage({ pinData: JSON.stringify({ show: !this.checked }) })
  170. }
  171. deRemind.onclick = function () {
  172. deCheck.checked = !deCheck.checked;
  173. setChromeStorage({ pinData: JSON.stringify({ show: !deCheck.checked }) })
  174. }
  175. document.querySelector('.de-pin-skip').onclick = function () {
  176. document.querySelector('#de-pin-pop').style.display = 'none';
  177. }
  178. }
  179. function getUserInfo(cb) {
  180. getChromeStorage('userInfo', (res) => {
  181. cb && cb(res);
  182. })
  183. }
  184. // 绑定推文id所需参数
  185. let bindTwitterArt = {
  186. needBind: false,
  187. postId: '',
  188. isBindIng: false
  189. };
  190. /**
  191. * 监听dialog内点击原生发布按钮事件
  192. * @private
  193. */
  194. function _publishTweetEvent(contentStr, cb) {
  195. setTimeout(() => {
  196. let publishTweetBtn;
  197. let dialog = document.querySelector('div[role="dialog"]');
  198. if (dialog) {
  199. publishTweetBtn = dialog.querySelector('div[data-testid="tweetButton"]');
  200. } else {
  201. let domMain = document.querySelector('main[role="main"]');
  202. publishTweetBtn = domMain && domMain.querySelector('div[data-testid="tweetButton"]');
  203. }
  204. publishTweetBtn && publishTweetBtn.addEventListener('click', function () {
  205. bindTwitterArt.needBind = true;
  206. bindTwitterArt.postId = contentStr;
  207. cb && cb()
  208. });
  209. }, 800)
  210. }
  211. /**
  212. * 在输入推文区插入deNet按钮
  213. * @param parent
  214. * @param dom
  215. * @param isClick
  216. * @private
  217. */
  218. function _addDeNetEditBtn(parent, dom, isClick = false) {
  219. setTimeout(() => {
  220. if (parent && parent.parentNode) {
  221. Report.reportLog({
  222. pageSource: Report.pageSource.mainPage,
  223. businessType: Report.businessType.buttonView,
  224. objectType: Report.objectType.buttonSecond
  225. });
  226. parent.parentNode.insertBefore(dom, parent.nextElementSibling);
  227. } else {
  228. setTimeout(() => {
  229. parent = _getScheduleDom(isClick);
  230. if (parent && parent.parentNode) {
  231. Report.reportLog({
  232. pageSource: Report.pageSource.mainPage,
  233. businessType: Report.businessType.buttonView,
  234. objectType: Report.objectType.buttonSecond
  235. });
  236. parent.parentNode.insertBefore(dom, parent.nextElementSibling);
  237. }
  238. }, 1000)
  239. }
  240. })
  241. }
  242. /**
  243. * 在dialog插入deNet按钮
  244. * @private
  245. */
  246. // function _addDeNetBtnToDialog() {
  247. // setTimeout(() => {
  248. // let dialogScheduleBtn = _getScheduleDom(true);
  249. // _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn2);
  250. // }, 800)
  251. // }
  252. /**
  253. * 获取左侧twitter按钮
  254. * @private
  255. */
  256. function _getSliderTwitterBtn() {
  257. dom.tweetBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
  258. dom.tweetBtn.addEventListener('click', function () {
  259. // _addDeNetBtnToDialog();
  260. })
  261. }
  262. /**
  263. * 添加deNet按钮
  264. * @private
  265. */
  266. function _addDeNetBtn() {
  267. setTimeout(() => {
  268. let navWidth = document.querySelector('nav[role="navigation"]').offsetWidth;
  269. addSliderNavDeBtn(navWidth < 245);
  270. let innerDeIcon = document.getElementById('de-btn1');
  271. if (!innerDeIcon) {
  272. let dialogScheduleBtn = _getScheduleDom(false);
  273. _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn1);
  274. }
  275. }, 800)
  276. }
  277. /**
  278. * 获取推文输入框内dom,用于插入deNet
  279. * @param isDialogInner
  280. * @returns {Element}
  281. * @private
  282. */
  283. function _getScheduleDom(isDialogInner = false) {
  284. let scheduleBtn;
  285. if (isDialogInner) {
  286. scheduleBtn = document.querySelector('div[role="dialog"]').querySelector('[data-testid="createPollButton"]');
  287. } else {
  288. let toolBar = document.querySelector('div[data-testid="toolBar"]');
  289. if (toolBar) {
  290. scheduleBtn = toolBar.querySelector('div[data-testid="geoButton"]');
  291. }
  292. }
  293. return scheduleBtn;
  294. }
  295. /**
  296. * 插入iframe到页面
  297. * @private
  298. */
  299. function _addIframe() {
  300. // let span = document.createElement('span');
  301. // const shadowRoot = span.attachShadow({mode: 'closed'})
  302. let iframe = document.createElement('iframe');
  303. iframe.src = chrome.runtime.getURL('/iframe/publish.html')
  304. iframe.id = 'iframe-content'
  305. iframe.style.cssText = 'position:fixed;top:0px;right:0;display:block; width:100%;height:100%;z-index:0; border: medium none;display:none';
  306. // shadowRoot.appendChild(iframe);
  307. // document.body.appendChild(span)
  308. dom.iframe = iframe;
  309. let iframeContent = document.getElementById('iframe-content');
  310. if (!iframeContent) {
  311. document.getElementById('layers').appendChild(iframe);
  312. }
  313. }
  314. /**
  315. * 获取发布推文id
  316. * @returns {string}
  317. * @private
  318. */
  319. /** function _getTwitterArtId(contentStr, cb) {
  320. let id = '';
  321. let timer = setInterval(() => {
  322. let arr = document.querySelectorAll('a') || [];
  323. for (let i = 0; i < arr.length; i++) {
  324. let item = arr[i];
  325. if (item.innerText == '#DeNet') {
  326. if (item.parentNode && item.parentNode.parentNode && item.parentNode.parentNode.innerText.length > 5) {
  327. let _postId = item.parentNode.parentNode.innerText || ''
  328. let _dom = item.parentNode.parentNode.parentNode.parentNode.parentNode
  329. let regex = new RegExp(contentStr);
  330. if (regex.test(_postId)) {
  331. id = _dom.children[0].querySelector('a[dir="auto"]').getAttribute('href').split('/status/')[1];
  332. clearInterval(timer);
  333. if (id) {
  334. cb && cb(id);
  335. }
  336. break;
  337. }
  338. }
  339. }
  340. }
  341. }, 1000);
  342. }
  343. */
  344. /**
  345. * 点击deNet按钮处理
  346. * @private
  347. */
  348. function _deNetBtnClick(port) {
  349. getUserInfo((res) => {
  350. if (res) {
  351. if (window.location.pathname != '/home') {
  352. if (!dom.homeBtn) {
  353. dom.homeBtn = document.querySelector('a[data-testid="AppTabBar_Home_Link"]');
  354. }
  355. dom.homeBtn.click();
  356. }
  357. showGiveDialogHandler(res);
  358. } else {
  359. let loadIcon = document.getElementById('de-btn-loading');
  360. if (loadIcon) {
  361. return;
  362. }
  363. dom.deBtn.insertBefore(dom.loadingImg, dom.deBtn.querySelector('span'));
  364. setTimeout(() => {
  365. dom.loadingImg.style.transform = 'rotate(1080deg)'
  366. });
  367. setTimeout(() => {
  368. dom.loadingImg.style.transform = 'rotate(0deg)'
  369. dom.deBtn.innerHTML = '<span>DeNet<span>';
  370. }, 3000)
  371. port.postMessage({ state: 'CONTENT_TWITTER_LOGIN' })
  372. }
  373. })
  374. }
  375. /**
  376. * 设置发布内容
  377. * @param content
  378. * @private
  379. */
  380. let isSetContent = false;
  381. function _setPublishContent(content) {
  382. if (!isSetContent) {
  383. isSetContent = true;
  384. setTimeout(() => {
  385. document.execCommand("insertText", false, content);
  386. setTimeout(() => {
  387. isSetContent = false;
  388. }, 2000)
  389. }, 1000);
  390. }
  391. }
  392. /**
  393. * 创建deNet按钮 添加到页面
  394. * @returns {{deBtn2: HTMLDivElement, deBtn1: HTMLDivElement, deBtn: HTMLSpanElement}}
  395. * @private
  396. */
  397. function _createBtnDom(port) {
  398. let loadingImg = document.createElement('img');
  399. loadingImg.id = 'de-btn-loading'
  400. loadingImg.src = require("@/assets/img/icon-btn-loading.png");
  401. loadingImg.style.cssText = 'width:20px;height: 20px;margin-right:3px;transition-duration: 3s;';
  402. let style = document.createElement('style');
  403. style.innerHTML = "#de-btn:hover{opacity: .9;};@-webkit-keyframes load{from{ transform: rotate(0deg);} to{transform: rotate(360deg);}}";
  404. document.getElementsByTagName('head').item(0).appendChild(style);
  405. // 左侧大屏按钮
  406. let deBtn = document.createElement('span');
  407. // const shadowDiv = document.createElement('div');
  408. deBtn.innerHTML = '<span>DeNet</span>';
  409. deBtn.id = 'de-btn';
  410. deBtn.style.cssText = 'width:90%;height: 52px;text-align:center;line-height:52px;margin-bottom: 4px;margin-top: 4px;background: linear-gradient(274.8deg, #FF9900 -3.69%, #BD00FF 69.71%, #00F0FF 122.65%);color:#fff;font-size:17px;font-weight:700;border-radius:100px;cursor: pointer;display: flex;align-items: center;justify-content: center;';
  411. // 编辑框内按钮
  412. const deBtn1 = document.createElement('img');
  413. let src = require("@/assets/img/icon-gift-pack.png");
  414. const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;padding: 0px 8px';
  415. deBtn1.id = 'de-btn1';
  416. deBtn1.style.cssText = smallDeBtnStyle;
  417. deBtn1.src = src
  418. const deBtn2 = document.createElement('div');
  419. deBtn2.id = 'de-btn2';
  420. deBtn2.style.cssText = smallDeBtnStyle;
  421. deBtn2.src = "@/assets/img/icon-gift-pack.png"
  422. // 小屏按钮
  423. const deBtn3 = document.createElement('img');
  424. deBtn3.id = 'de-btn3'
  425. deBtn3.src = require("@/assets/logo/128.png");
  426. deBtn3.style.cssText = 'width:52px;height: 52px;margin-top:20px;cursor: pointer;';
  427. deBtn.addEventListener('click', () => {
  428. Report.reportLog({
  429. pageSource: Report.pageSource.mainPage,
  430. businessType: Report.businessType.buttonClick,
  431. objectType: Report.objectType.buttonMain
  432. });
  433. _deNetBtnClick(port);
  434. })
  435. deBtn1.addEventListener('click', () => {
  436. Report.reportLog({
  437. pageSource: Report.pageSource.mainPage,
  438. businessType: Report.businessType.buttonClick,
  439. objectType: Report.objectType.buttonSecond
  440. });
  441. _deNetBtnClick(port);
  442. })
  443. deBtn2.addEventListener('click', () => {
  444. _deNetBtnClick(port);
  445. })
  446. deBtn3.addEventListener('click', () => {
  447. Report.reportLog({
  448. pageSource: Report.pageSource.mainPage,
  449. businessType: Report.businessType.buttonClick,
  450. objectType: Report.objectType.buttonMain
  451. });
  452. _deNetBtnClick(port);
  453. })
  454. dom.deBtn = deBtn;
  455. dom.deBtn1 = deBtn1;
  456. dom.deBtn2 = deBtn2;
  457. dom.deBtn3 = deBtn3;
  458. dom.loadingImg = loadingImg;
  459. }
  460. function addSliderNavDeBtn(isSmall = false) {
  461. if (!isSmall) {
  462. let bigDom = document.querySelector('h1[role]').parentNode.parentNode;
  463. let deBtn = document.getElementById('de-btn');
  464. if (bigDom && !deBtn) {
  465. bigDom.appendChild(dom.deBtn);
  466. Report.reportLog({
  467. pageSource: Report.pageSource.mainPage,
  468. businessType: Report.businessType.buttonView,
  469. objectType: Report.objectType.buttonMain
  470. });
  471. }
  472. } else {
  473. let smallDom = document.querySelector('h1[role]').parentNode.parentNode;
  474. let deBtn3 = document.getElementById('de-btn3');
  475. if (smallDom && !deBtn3) {
  476. smallDom.appendChild(dom.deBtn3);
  477. Report.reportLog({
  478. pageSource: Report.pageSource.mainPage,
  479. businessType: Report.businessType.buttonView,
  480. objectType: Report.objectType.buttonMain
  481. });
  482. }
  483. }
  484. }
  485. function onWindowResize() {
  486. window.onresize = throttle(function () {
  487. try {
  488. if (window.innerWidth < 1273) {
  489. let bigBtn = document.querySelector('#de-btn');
  490. bigBtn && bigBtn.remove();
  491. setTimeout(() => {
  492. addSliderNavDeBtn(true);
  493. })
  494. } else {
  495. let smallBtn = document.querySelector('#de-btn3');
  496. smallBtn && smallBtn.remove();
  497. setTimeout(() => {
  498. addSliderNavDeBtn()
  499. })
  500. }
  501. } catch (e) {
  502. console.log(e)
  503. }
  504. }, 800)
  505. }
  506. function checkHasDeBtn() {
  507. setInterval(() => {
  508. try {
  509. let toolBar = document.querySelector('div[data-testid="toolBar"]');
  510. let innerDeIcon = document.getElementById('de-btn1');
  511. if (toolBar && !innerDeIcon) {
  512. let dialogScheduleBtn = _getScheduleDom(false);
  513. _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn1);
  514. }
  515. } catch (e) {
  516. console.log(e)
  517. }
  518. }, 1000)
  519. }
  520. /**
  521. * 根据postID绑定推文id
  522. */
  523. function bindTwitterArtMethod({ postId, twitterId }) {
  524. let regex = new RegExp(bindTwitterArt.postId);
  525. if (regex.test(postId)) {
  526. if (twitterId && bindTwitterArt.needBind && !bindTwitterArt.isBindIng) {
  527. bindTwitterArt.isBindIng = true;
  528. srcPublishSuccess({
  529. params: {
  530. postId: postId,
  531. srcContentId: twitterId
  532. }
  533. }).then((res) => {
  534. if (res.code == 0) {
  535. Report.reportLog({
  536. objectType: Report.objectType.tweetPostBinded
  537. });
  538. bindTwitterArt.needBind = false;
  539. bindTwitterArt.postId = '';
  540. bindTwitterArt.isBindIng = false;
  541. }
  542. })
  543. }
  544. }
  545. }
  546. function parseDOMRedPacket() {
  547. let _dom = null
  548. let arr = document.querySelectorAll('a') || []
  549. let _type = ''
  550. for (let i in arr) {
  551. if (arr[i].innerText == '#DeNet') {
  552. let _tweetId = ''
  553. let _article = arr[i].closest('article')
  554. let _txt_area = _article.querySelector('[lang][dir=auto]')
  555. let _postId = _txt_area.innerText
  556. _postId = _postId.match(/###([\s\S]*?)###/)[1]
  557. _dom = _article.querySelector('div[aria-labelledby]')
  558. if (_dom) {
  559. _type = 'card'
  560. } else {
  561. _type = 'parnet'
  562. _dom = _txt_area
  563. }
  564. let _a_area = _article.querySelector('a[aria-label]')
  565. if (_a_area && _a_area.getAttribute('href')) {
  566. _tweetId = _a_area.getAttribute('href').split('/status/')[1] || ''
  567. if (bindTwitterArt.needBind) {
  568. bindTwitterArtMethod({ postId: _postId, twitterId: _tweetId });
  569. }
  570. }
  571. replaceDOMRedPacket(_type, _dom, _postId, _tweetId)
  572. }
  573. }
  574. }
  575. let parse_dom = {}
  576. async function parseDOMRedPacketByShortUrl(port) {
  577. // let _new_time = new Date().getTime()
  578. // if ((_new_time - change_time) > 1000) {
  579. // change_time = _new_time
  580. // } else {
  581. // return
  582. // }
  583. // 为了减少声明变量次数
  584. parse_dom.dom = null
  585. parse_dom.txt_area = null
  586. parse_dom.short_url = ''
  587. parse_dom.postId = ''
  588. parse_dom.a_arr = null
  589. parse_dom.type = ''
  590. parse_dom.tweetId = ''
  591. parse_dom.article = null
  592. parse_dom.a_tweetId = null
  593. parse_dom.a_arr = document.querySelectorAll('a') || []
  594. for (let i in parse_dom.a_arr) {
  595. if (parse_dom.a_arr[i].innerText == '#DeNet') {
  596. parse_dom.article = parse_dom.a_arr[i].closest('article')
  597. parse_dom.dom = parse_dom.article.querySelector('div[aria-labelledby]')
  598. if (parse_dom.dom && !parse_dom.dom.querySelector('iframe') && parse_dom.dom.closest('article').querySelector('iframe')) {
  599. parse_dom.dom.style.display = 'none'
  600. continue
  601. }
  602. if (parse_dom.dom && parse_dom.dom.parentElement.querySelector('iframe')) {
  603. continue
  604. }
  605. parse_dom.short_url = getTwitterShortUrl(parse_dom.article)
  606. parse_dom.a_tweetId = parse_dom.article.querySelector('a[aria-label]')
  607. if (parse_dom.a_tweetId && parse_dom.a_tweetId.getAttribute('href')) {
  608. parse_dom.tweetId = parse_dom.a_tweetId.getAttribute('href').split('/status/')[1] || ''
  609. }
  610. parse_dom.postId = await handleShortUrl(port, parse_dom.short_url)
  611. console.log('_postId', parse_dom.postId)
  612. console.log('short_url', parse_dom.short_url)
  613. // 获取到postId了
  614. if (parse_dom.postId) {
  615. console.log('bindTwitterArt.postId', bindTwitterArt.postId)
  616. console.log('parse_dom.postId', parse_dom.postId)
  617. if (bindTwitterArt.needBind) {
  618. bindTwitterArtMethod({ postId: parse_dom.postId, twitterId: parse_dom.tweetId });
  619. }
  620. if (parse_dom.dom) {
  621. parse_dom.type = 'card'
  622. } else {
  623. parse_dom.type = 'parnet'
  624. parse_dom.txt_area = parse_dom.article.querySelector('[lang][dir=auto]')
  625. parse_dom.dom = parse_dom.txt_area
  626. }
  627. replaceDOMRedPacket(parse_dom.type, parse_dom.dom, parse_dom.postId, parse_dom.tweetId)
  628. }
  629. }
  630. }
  631. }
  632. // 校验推特短数组大小
  633. function checkShortUrlArraySize(_array) {
  634. if (new Blob(_array).size >= 1024 * 1024) {
  635. _array.splice(0, parseInt(_array.length / 2))
  636. }
  637. return _array
  638. }
  639. // 获取推特短链接
  640. function getTwitterShortUrl(_article) {
  641. let dom_arr = _article.querySelectorAll('a[href][role]')
  642. let url = ''
  643. for (let i in dom_arr) {
  644. if (dom_arr[i].href.includes('https://t.co')) {
  645. url = dom_arr[i].href
  646. break
  647. }
  648. }
  649. return url
  650. }
  651. // 处理短链接
  652. async function handleShortUrl(port, url) {
  653. let post_id = ''
  654. // 校验本地是否存在
  655. let sort_link_data = await getChromeStorage('sortLink') || ''
  656. if (sort_link_data) {
  657. let _item = sort_link_data.filter((_item) => { return _item.url == url })
  658. // 本地有值
  659. if (_item.length > 0) {
  660. if (_item[0].post_id) {
  661. post_id = _item[0].post_id
  662. } else {
  663. // 防止多次请求,校验timeout时间
  664. let _new_time = new Date().getTime()
  665. if (_new_time - _item[0].time > 5000) {
  666. for (let i in sort_link_data) {
  667. if (sort_link_data[i].url == url) {
  668. sort_link_data[i].time = _new_time
  669. }
  670. }
  671. setChromeStorage({ sortLink: JSON.stringify(sort_link_data) })
  672. port.postMessage({ state: 'CONTENT_TWITTER_SHORT_LINK', url })
  673. }
  674. }
  675. } else {
  676. // 本地没有值
  677. sort_link_data.push({ url, post_id: '', time: new Date().getTime() })
  678. setChromeStorage({ sortLink: JSON.stringify(sort_link_data) })
  679. port.postMessage({ state: 'CONTENT_TWITTER_SHORT_LINK', url })
  680. }
  681. // 校验存储大小
  682. let new_item = checkShortUrlArraySize(sort_link_data)
  683. if (sort_link_data.length != new_item.length) {
  684. setChromeStorage({ sortLink: JSON.stringify(new_item) })
  685. }
  686. } else {
  687. setChromeStorage({ sortLink: JSON.stringify([{ url, post_id: '', time: new Date().getTime() }]) })
  688. port.postMessage({ state: 'CONTENT_TWITTER_SHORT_LINK', url })
  689. }
  690. return post_id
  691. }
  692. function createIframe(postId, tweetId) {
  693. let _iframe = document.createElement('iframe')
  694. _iframe.id = postId
  695. _iframe.src = chrome.runtime.getURL('/iframe/red-packet.html') + `?postId=${postId}&tweetId=${tweetId}`;
  696. _iframe.style.cssText = 'border: medium none; width:375px;min-height:500px;'
  697. return _iframe
  698. }
  699. function replaceDOMRedPacket(_type, _dom, postId, tweetId) {
  700. if (!_dom || !_dom.parentElement) {
  701. return
  702. }
  703. if (_dom.parentElement.querySelector('iframe')) {
  704. return
  705. }
  706. if (_type == 'card') {
  707. let _len
  708. _len = _dom.childNodes.length
  709. for (let i = 0; i < _len; i++) {
  710. _dom.children[i].style.display = 'none'
  711. }
  712. _dom.style = 'min-height:500px'
  713. _dom.appendChild(createIframe(postId, tweetId))
  714. } else {
  715. let _parent = _dom.parentNode
  716. _parent.appendChild(createIframe(postId, tweetId))
  717. }
  718. }
  719. // let change_time = new Date().getTime()
  720. // function onChangePageMain(port, targetNode) {
  721. // const config = { attributes: true, childList: true, subtree: true };
  722. // const callback = (mutationsList, observer) => {
  723. // setTimeout(() => {
  724. // parseDOMRedPacketByShortUrl(port)
  725. // }, 2000)
  726. // }
  727. // const observer = new MutationObserver(callback);
  728. // observer.observe(targetNode, config);
  729. // }
  730. export function setIframeRedPacket(port) {
  731. // let elment = document.documentElement
  732. if (window.location.href.includes('twitter.com)')) {
  733. return
  734. }
  735. setInterval(() => {
  736. parseDOMRedPacketByShortUrl(port)
  737. }, 1000)
  738. // let targetNode = null
  739. // let timer = setInterval(() => {
  740. // targetNode = document.querySelector('main')
  741. // if (targetNode) {
  742. // clearInterval(timer)
  743. // onChangePageMain(port, targetNode)
  744. // }
  745. // }, 1000);
  746. }