เดธเดพเดงเดพเดฐเดฃ "เดเตเดฒเดฏเดจเตเดฑเต-เดธเตเตผเดตเตผ" เดเตผเดเตเดเดฟเดเตเดเตเดเดฑเดฟเตฝ เดจเดฟเดจเตเดจเต เดตเตเดฏเดคเตเดฏเดธเตเดคเดฎเดพเดฏเดฟ, เดตเดฟเดเตเดจเตเดฆเตเดฐเตเดเตเดค เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ เดเดตเดฏเดพเดฃเต:
- เดเดชเดฏเตเดเตเดคเต เดฒเตเดเดฟเดจเตเดเดณเตเด เดชเดพเดธเตโเดตเตเดกเตเดเดณเตเด เดเดณเตเดณ เดเดฐเต เดกเดพเดฑเตเดฑเดพเดฌเตเดธเต เดธเดเดญเดฐเดฟเดเตเดเตเดฃเตเด เดเดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ. เดเดเตโเดธเดธเตเดธเต เดตเดฟเดตเดฐเดเตเดเตพ เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพ เดคเดจเตเดจเต เดชเตเดฐเดคเตเดฏเตเดเดฎเดพเดฏเดฟ เดธเดเดญเดฐเดฟเดเตเดเตเดจเตเดจเต, เดเตเดเดพเดคเต เด เดตเดฐเตเดเต เดเดงเดฟเดเดพเดฐเดฟเดเดคเดฏเตเดเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฃเด เดชเตเดฐเตเดเตเดเตเดเตเดเตเตพ เดคเดฒเดคเตเดคเดฟเตฝ เดธเดเดญเดตเดฟเดเตเดเตเดจเตเดจเต.
- เดเดฐเต เดธเตเตผเดตเตผ เดเดชเดฏเตเดเดฟเดเตเดเตเดฃเตเดเดคเดฟเดฒเตเดฒ. เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดฒเตเดเดฟเดเต เดเดฐเต เดฌเตเดฒเตเดเตเดเตเดเตเดฏเดฟเตป เดจเตเดฑเตเดฑเตโเดตเตผเดเตเดเดฟเตฝ เดเดเตเดธเดฟเดเตเดฏเตเดเตเดเต เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเตเด, เด เดตเดฟเดเต เดเดตเดถเตเดฏเดฎเดพเดฏ เดกเดพเดฑเตเดฑ เดธเดเดญเดฐเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเตเด.
เดเดชเดฏเตเดเตเดคเต เดเตเดเตพเดเตเดเดพเดฏเดฟ เดคเดพเดฐเดคเดฎเตเดฏเตเดจ เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฏ 2 เดธเตเดฑเตเดฑเตเดฑเตเดเตเดเดณเตเดฃเตเดเต - เดนเดพเตผเดกเตโเดตเตเดฏเตผ เดตเดพเดฒเดฑเตเดฑเตเดเดณเตเด เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเดณเตเด. เดนเดพเตผเดกเตโเดตเตเดฏเตผ เดตเดพเดฒเดฑเตเดฑเตเดเตพ เดเดฑเตเดเตเดเตเดฑเต เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฃเต, เดเดจเตเดจเดพเตฝ เดเดชเดฏเตเดเดฟเดเตเดเดพเตป เดชเตเดฐเดฏเดพเดธเดฎเตเดณเตเดณเดคเตเด เดธเตเดเดจเตเดฏเดฎเดฒเตเดฒ, เดเดจเตเดจเดพเตฝ เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพ เดธเตเดฐเดเตเดทเดฟเดคเดคเตเดตเดคเตเดคเดฟเดจเตเดฑเตเดฏเตเด เดเดชเดฏเตเด เดเดณเตเดชเตเดชเดคเตเดคเดฟเดจเตเดฑเตเดฏเตเด เดธเดฎเตเดชเตเตผเดฃเตเดฃ เดธเดเดฏเตเดเดจเดฎเดพเดฃเต, เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ เด เดจเตเดคเดฟเดฎ เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเต เดชเตเตผเดฃเตเดฃเดฎเดพเดฏเตเด เดธเตเดเดจเตเดฏเดตเตเดฎเดพเดเดพเด.
เดเดคเตเดฒเตเดฒเดพเด เดเดฃเดเตเดเดฟเดฒเตเดเตเดคเตเดคเต, เดเดเดชเดพเดเตเดเดณเตเด เดเดชเตเดชเตเดเดณเตเด เดเดชเดฏเตเดเดฟเดเตเดเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดฒเดณเดฟเดคเดฎเดพเดฏ API เดจเตฝเดเดฟเดเตเดเตเดฃเตเดเต เดตเดฟเดเตเดจเตเดฆเตเดฐเตเดเตเดค เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเดณเตเดเต เดตเดฟเดเดธเดจเด เดฒเดณเดฟเดคเดฎเดพเดเตเดเตเดจเตเดจ เดเดฑเตเดฑเดตเตเด เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฏ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเด เดเดฃเตเดเดพเดเตเดเดพเตป เดเดเตเดเตพ เดเดเตเดฐเดนเดฟเดเตเดเตเดจเตเดจเต.
เด เด
เดจเตเดญเดตเดคเตเดคเตเดเตเดเตเดฑเดฟเดเตเดเต เดเดเตเดเตพ เดเตเดตเดเต เดจเดฟเดเตเดเดณเตเดเต เดชเดฑเดฏเตเด.
เดเตเดกเต เดเดฆเดพเดนเดฐเดฃเดเตเดเดณเตเด เดธเตโเดเตเดฐเตเตปเดทเตเดเตเดเตเดเดณเตเด เดเดชเดฏเตเดเดฟเดเตเดเต เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเด เดเดเตเดเดจเต เดเดดเตเดคเดพเด เดเดจเตเดจเดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เดเดเตเดเด เดเดเตเดเดฎเดพเดฏเตเดณเตเดณ เดจเดฟเตผเดฆเตเดฆเตเดถเดเตเดเตพ เดฒเตเดเดจเดคเตเดคเดฟเตฝ เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเด. เดจเดฟเดเตเดเตพเดเตเดเต เดเดฒเตเดฒเดพ เดเตเดกเตเด เดเดฃเตเดเตเดคเตเดคเดพเดจเดพเดเตเด
เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเดณเตเดเต เดเดฐเต เดนเตเดฐเดธเตเดต เดเดฐเดฟเดคเตเดฐเด
เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพ เดตเดณเดฐเตเดเตเดเดพเดฒเดฎเดพเดฏเดฟ เดจเดฟเดฒเดตเดฟเดฒเตเดฃเตเดเต. 1999-เตฝ เดเดจเตเดฑเตผเดจเตเดฑเตเดฑเต เดเดเตเดธเตเดชเตเดฒเตเดฑเดฑเดฟเตฝ, 2004-เตฝ เดซเดฏเตผเดซเตเดเตเดธเดฟเตฝ เด เดตเตผ เดชเตเดฐเดคเตเดฏเดเตเดทเดชเตเดชเตเดเตเดเต. เดเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด, เดตเดณเดฐเตเดเตเดเดพเดฒเดฎเดพเดฏเดฟ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเต เดเดฐเตเดฑเตเดฑ เดฎเดพเดจเดฆเดฃเตเดกเดฎเดฟเดฒเตเดฒ.
เดเตเดเดฟเตพ เดเตเดฐเตเดฎเดฟเดจเตเดฑเต เดจเดพเดฒเดพเดฎเดคเตเดคเต เดชเดคเดฟเดชเตเดชเดฟเดฒเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพเดเตเดเตเดชเตเดชเด เดเดคเต เดชเตเดฐเดคเตเดฏเดเตเดทเดชเตเดชเตเดเตเดเตเดตเตเดจเตเดจเต เดจเดฎเตเดเตเดเต เดชเดฑเดฏเดพเด. เดคเตเตผเดเตเดเดฏเดพเดฏเตเด, เด เดจเตเดจเต เดเดฐเต เดธเตเดชเตเดธเดฟเดซเดฟเดเตเดเตเดทเดจเตเด เดเดฃเตเดเดพเดฏเดฟเดฐเตเดจเตเดจเดฟเดฒเตเดฒ, เดชเดเตเดทเต Chrome API เดเดฏเดฟเดฐเตเดจเตเดจเต เด เดคเดฟเดจเตเดฑเต เด เดเดฟเดธเตเดฅเดพเดจเด: เดฌเตเดฐเตเดธเตผ เดฎเดพเตผเดเตเดเดฑเตเดฑเดฟเดจเตเดฑเต เดญเตเดฐเดฟเดญเดพเดเดตเตเด เดเตเดดเดเดเตเดเตเดเดฏเตเด เดเดฐเต เดฌเดฟเตฝเดฑเตเดฑเต-เดเตป เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดธเตเดฑเตเดฑเตเตผ เดเดณเตเดณเดคเดฟเดจเดพเตฝ, Chrome เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพเดเตเดเตเดณเตเดณ เดฎเดพเดจเดฆเดฃเตเดกเด เดธเดเตเดเดฎเดพเดเตเดเดฟ.
เดฎเตเดธเดฟเดฒเตเดฒเดฏเตเดเตเดเต เด เดคเดฟเดจเตเดฑเตเดคเดพเดฏ เดธเตเดฑเตเดฑเดพเตปเดกเตเตผเดกเต เดเดฃเตเดเดพเดฏเดฟเดฐเตเดจเตเดจเต, เดเดจเตเดจเดพเตฝ Chrome เดเดเตเดธเตเดฑเตเดฑเตปเดทเดจเตเดเดณเตเดเต เดเดจเดชเตเดฐเตเดคเดฟ เดเดฃเตเดเดชเตเดชเตเตพ, เด เดจเตเดฏเตเดเตเดฏเดฎเดพเดฏ API เดจเดฟเตผเดฎเตเดฎเดฟเดเตเดเดพเตป เดเดฎเตเดชเดจเดฟ เดคเตเดฐเตเดฎเดพเดจเดฟเดเตเดเต. 2015-เตฝ, เดฎเตเดธเดฟเดฒเตเดฒเดฏเตเดเต เดฎเตเตปเดเตเดฏเดฟเตฝ, เดเตเดฐเตเดธเต-เดฌเตเดฐเตเดธเตผ เดเดเตเดธเตเดฑเตเดฑเตปเดทเตป เดธเตเดชเตเดธเดฟเดซเดฟเดเตเดเตเดทเดจเตเดเดณเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเดพเตป เดตเตเตพเดกเต เดตเตเดกเต เดตเตเดฌเต เดเตบเดธเตเตผเดทเตเดฏเดคเตเดคเดฟเตฝ (W3C) เดเดฐเต เดชเตเดฐเดคเตเดฏเตเด เดเตเดฐเตเดชเตเดชเต เดธเตเดทเตเดเดฟเดเตเดเต.
Chrome-เดจเตเดณเตเดณ เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ API เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพ เด
เดเดฟเดธเตเดฅเดพเดจเดฎเดพเดฏเดฟ เดเดเตเดคเตเดคเต. เดฎเตเดเตเดฐเตเดธเตเดซเตเดฑเตเดฑเดฟเดจเตเดฑเต เดชเดฟเดจเตเดคเตเดฃเดฏเตเดเตเดฏเดพเดฃเต เดชเตเดฐเดตเตผเดคเตเดคเดจเด เดจเดเดคเตเดคเดฟเดฏเดคเต (เดธเตเดฑเตเดฑเดพเตปเดกเตเตผเดกเดฟเดจเตเดฑเต เดตเดฟเดเดธเดจเดคเตเดคเดฟเตฝ เดชเดเตเดเตเดเตเดเตเดเดพเตป เดเตเดเดฟเตพ เดตเดฟเดธเดฎเตเดฎเดคเดฟเดเตเดเต), เด
เดคเดฟเดจเตเดฑเต เดซเดฒเดฎเดพเดฏเดฟ เดเดฐเต เดกเตเดฐเดพเดซเตเดฑเตเดฑเต เดชเตเดฐเดคเตเดฏเดเตเดทเดชเตเดชเตเดเตเดเต.
เดเดชเดเดพเดฐเดฟเดเดฎเดพเดฏเดฟ, เดธเตเดชเตเดธเดฟเดซเดฟเดเตเดเตเดทเตป เดเดกเตเดเต, เดซเดฏเตผเดซเตเดเตเดธเต, เดเดชเตเดชเดฑ เดเดจเตเดจเดฟเดต เดชเดฟเดจเตเดคเตเดฃเดฏเตเดเตเดเตเดจเตเดจเต (Chrome เด เดฒเดฟเดธเตเดฑเตเดฑเดฟเตฝ เดเดฒเตเดฒ เดเดจเตเดจเดคเต เดถเตเดฐเดฆเตเดงเดฟเดเตเดเตเด). เดเดจเตเดจเดพเตฝ เดตเดพเดธเตเดคเดตเดคเตเดคเดฟเตฝ, เดธเตเดฑเตเดฑเดพเตปเดกเตเตผเดกเต Chrome-เดฎเดพเดฏเดฟ เดเดฑเตเดเตเดเตเดฑเต เด
เดจเตเดฏเตเดเตเดฏเดฎเดพเดฃเต, เดเดพเดฐเดฃเด เดเดคเต เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ เด
เดคเดฟเดจเตเดฑเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเดณเต เด
เดเดฟเดธเตเดฅเดพเดจเดฎเดพเดเตเดเดฟเดฏเดพเดฃเต เดเดดเตเดคเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเต. WebExtensions API-เดฏเต เดเตเดฑเดฟเดเตเดเต เดจเดฟเดเตเดเตพเดเตเดเต เดเตเดเตเดคเตฝ เดตเดพเดฏเดฟเดเตเดเดพเด
เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดเดเดจ
เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเต เดเดตเดถเตเดฏเดฎเดพเดฏ เดเดฐเตเดฏเตเดฐเต เดซเดฏเตฝ เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเต (manifest.json) เดเดฃเต. เดเดคเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดฒเตเดเตเดเตเดณเตเดณ "เดชเตเดฐเดตเตเดถเดจ เดชเตเดฏเดฟเดจเตเดฑเต" เดเตเดเดฟเดฏเดพเดฃเต.
เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเต
เดธเตเดชเตเดธเดฟเดซเดฟเดเตเดเตเดทเตป เด
เดจเตเดธเดฐเดฟเดเตเดเต, เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเต เดซเดฏเตฝ เดเดฐเต เดธเดพเดงเตเดตเดพเดฏ JSON เดซเดฏเดฒเดพเดฃเต. เดเดคเต เดฌเตเดฐเตเดธเดฑเดฟเตฝ เดเดคเต เดเตเดเตพ เดชเดฟเดจเตเดคเตเดฃเดฏเตเดเตเดเตเดจเตเดจเต เดเดจเตเดจเดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เดตเดฟเดตเดฐเดเตเดเดณเตเดณเตเดณ เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเต เดเตเดเดณเตเดเต เดชเตเตผเดฃเตเดฃเดฎเดพเดฏ เดตเดฟเดตเดฐเดฃเด เดเดพเดฃเดพเตป เดเดดเดฟเดฏเตเด
เดธเตโเดชเตเดธเดฟเดซเดฟเดเตเดเตเดทเดจเดฟเตฝ เดเดฒเตเดฒเดพเดคเตเดค เดเตเดเตพ เด เดตเดเดฃเดฟเดเตเดเดชเตเดชเตเดเดพเด (Chrome-เดเด Firefox-เดเด เดชเดฟเดถเดเตเดเตพ เดฑเดฟเดชเตเดชเตเตผเดเตเดเต เดเตเดฏเตเดฏเตเดจเตเดจเต, เดชเดเตเดทเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเดคเต เดคเตเดเดฐเตเดจเตเดจเต).
เดเตเดเดพเดคเต เดเดฟเดฒ เดชเตเดฏเดฟเดจเตเดฑเตเดเดณเดฟเดฒเตเดเตเดเต เดถเตเดฐเดฆเตเดง เดเดเตผเดทเดฟเดเตเดเดพเตป เดเดพเตป เดเดเตเดฐเดนเดฟเดเตเดเตเดจเตเดจเต.
- เดชเดถเตเดเดพเดคเตเดคเดฒเด - เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดซเตเตฝเดกเตเดเตพ เดเตพเดชเตเดชเตเดเตเดจเตเดจ เดเดฐเต เดตเดธเตเดคเต:
- เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเตพ - เดชเดถเตเดเดพเดคเตเดคเดฒ เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเตฝ เดเดเตเดธเดฟเดเตเดฏเตเดเตเดเต เดเตเดฏเตเดฏเตเดจเตเดจ เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐ (เดเดคเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเต เดเดเตเดเตพ เดเตเดฑเดเตเดเต เดเดดเดฟเดเตเดเต เดธเดเดธเดพเดฐเดฟเดเตเดเตเด);
- เดชเตเดเต - เดถเตเดจเตเดฏเดฎเดพเดฏ เดชเตเดเดฟเตฝ เดเดเตเดธเดฟเดเตเดฏเตเดเตเดเต เดเตเดฏเตเดฏเตเดจเตเดจ เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเตพเดเตเดเต เดชเดเดฐเด, เดจเดฟเดเตเดเตพเดเตเดเต เดเดณเตเดณเดเดเตเดเดฎเตเดณเตเดณ html เดตเตเดฏเดเตเดคเดฎเดพเดเตเดเดพเตป เดเดดเดฟเดฏเตเด. เด เดธเดพเดนเดเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดซเตเตฝเดกเต เด เดตเดเดฃเดฟเดเตเดเดชเตเดชเตเดเตเด, เดเตเดเดพเดคเต เดเดณเตเดณเดเดเตเด เดชเตเดเดฟเดฒเตเดเตเดเต เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเตพ เดเตเตผเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต;
- เดจเดฟเดฐเตเดฌเดจเตเดงเดเดชเดฟเดเดฟเดเตเดเตเด โ เดเดฐเต เดฌเตเดจเดฑเดฟ เดซเตเดฒเดพเดเต, เดตเตเดฏเดเตเดคเดฎเดพเดเตเดเดฟเดฏเดฟเดเตเดเดฟเดฒเตเดฒเตเดเตเดเดฟเตฝ, เดฌเตเดฐเตเดธเตผ เด เดคเต เดเดจเตเดจเตเด เดเตเดฏเตเดฏเตเดจเตเดจเดฟเดฒเตเดฒเตเดจเตเดจเต เดเดฃเดเตเดเดพเดเตเดเตเดฎเตเดชเตเตพ เดชเดถเตเดเดพเดคเตเดคเดฒ เดชเตเดฐเดเตเดฐเดฟเดฏเดฏเต "เดเตเดฒเตเดฒเตเด", เดเดตเดถเตเดฏเดฎเตเดเตเดเดฟเตฝ เด เดคเต เดชเตเดจเดฐเดพเดฐเดเดญเดฟเดเตเดเตเด. เด เดฒเตเดฒเตเดเตเดเดฟเตฝ, เดฌเตเดฐเตเดธเตผ เด เดเดฏเตเดเตเดเตเดฎเตเดชเตเตพ เดฎเดพเดคเตเดฐเดฎเต เดชเตเดเต เด เตบเดฒเตเดกเต เดเตเดฏเตเดฏเตเดเดฏเตเดณเตเดณเต. Firefox-เตฝ เดชเดฟเดจเตเดคเตเดฃเดฏเตเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ.
- เดเดณเตเดณเดเดเตเด_เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเตพ - เดตเตเดฏเดคเตเดฏเดธเตเดค เดตเตเดฌเต เดชเตเดเตเดเดณเดฟเดฒเตเดเตเดเต เดตเตเดฏเดคเตเดฏเดธเตเดค เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเตพ เดฒเตเดกเต เดเตเดฏเตเดฏเดพเตป เดจเดฟเดเตเดเดณเต เด
เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจ เดเดฌเตเดเดเตเดฑเตเดฑเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐ. เดเดฐเต เดเดฌเตเดเดเตเดฑเตเดฑเดฟเดฒเตเด เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดชเตเดฐเดงเดพเดจเดชเตเดชเตเดเตเด เดซเตเตฝเดกเตเดเตพ เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต:
- เดฎเดคเตเดธเดฐเดเตเดเตพ -
เดชเดพเดฑเตเดฑเตเตบ url , เดเดฐเต เดชเตเดฐเดคเตเดฏเตเด เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดเตพเดชเตเดชเตเดเตเดคเตเดคเดฃเต เดตเตเดฃเตเดเดฏเต เดเดจเตเดจเต เดเดคเต เดจเดฟเตผเดฃเตเดฃเดฏเดฟเดเตเดเตเดจเตเดจเต. - js - เด เดฎเดคเตเดธเดฐเดคเตเดคเดฟเตฝ เดฒเตเดกเต เดเตเดฏเตเดฏเตเดจเตเดจ เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเดณเตเดเต เดเดฐเต เดฒเดฟเดธเตเดฑเตเดฑเต;
- เดเดดเดฟเดตเดพเดเตเด_เดชเตเดฐเตเดคเตเดคเดเตเดเตพ - เดซเตเตฝเดกเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดดเดฟเดตเดพเดเตเดเตเดจเตเดจเต
match
เด เดซเตเตฝเดกเตเดฎเดพเดฏเดฟ เดชเตเดฐเตเดคเตเดคเดชเตเดชเตเดเตเดจเตเดจ URL-เดเตพ.
- เดฎเดคเตเดธเดฐเดเตเดเตพ -
- เดชเตเดเต_เดเดเตเดทเตป - เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ เดฌเตเดฐเตเดธเดฑเดฟเดฒเต เด
เดกเตเดฐเดธเต เดฌเดพเดฑเดฟเดจเต เด
เดเตเดคเตเดคเดพเดฏเดฟ เดชเตเดฐเดฆเตผเดถเดฟเดชเตเดชเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดเดเตเดเดฃเดฟเดจเตเด เด
เดคเตเดฎเดพเดฏเดฟ เดเดเดชเดดเดเตเดจเตเดจเดคเดฟเดจเตเด เดเดคเตเดคเดฐเดตเดพเดฆเดฟเดฏเดพเดฏ เดเดฐเต เดตเดธเตเดคเตเดตเดพเดฃเต. เดจเดฟเดเตเดเดณเตเดเต เดธเตเดตเดจเตเดคเด HTML, CSS, JS เดเดจเตเดจเดฟเดต เดเดชเดฏเตเดเดฟเดเตเดเต เดจเดฟเตผเดตเดเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดชเตเดชเตเดชเตเด
เดชเตเดชเต เดตเดฟเตปเดกเต เดชเตเดฐเดฆเตผเดถเดฟเดชเตเดชเดฟเดเตเดเดพเดจเตเด เดเดคเต เดจเดฟเดเตเดเดณเต เด
เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต.
- default_popup โ เดชเตเดชเตเดชเตเด เดชเตเดชเต เดเดจเตเดฑเตผเดซเตเดธเตเดณเตเดณ HTML เดซเดฏเดฒเดฟเดฒเตเดเตเดเตเดณเตเดณ เดชเดพเดคเดฏเดฟเตฝ CSS, JS เดเดจเตเดจเดฟเดต เด เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเดพเด.
- เด
เดจเตเดฎเดคเดฟเดเตพ - เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เด
เดตเดเดพเดถเดเตเดเตพ เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดเดฐเต เดถเตเดฐเตเดฃเดฟ. 3 เดคเดฐเดคเตเดคเดฟเดฒเตเดณเตเดณ เด
เดตเดเดพเดถเดเตเดเดณเตเดฃเตเดเต, เด
เดต เดตเดฟเดถเดฆเดฎเดพเดฏเดฟ เดตเดฟเดตเดฐเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต
เดเดตเดฟเดเต - web_accessible_resources โ เดเดฐเต เดตเตเดฌเต เดชเตเดเดฟเดจเต เด เดญเตเดฏเตผเดคเตเดฅเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเตเดจเตเดจ เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดเดฑเดตเดฟเดเดเตเดเตพ, เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดเดฎเตเดเตเดเตพ, JS, CSS, HTML เดซเดฏเดฒเตเดเตพ.
- เดฌเดพเดนเตเดฏเดฎเดพเดฏเดฟ_เดเดฃเดเตเดเดฌเดฟเตพ โ เดเดตเดฟเดเต เดจเดฟเดเตเดเตพเดเตเดเต เดฎเดฑเตเดฑเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเดณเตเดเต เดเดกเดฟเดเดณเตเด เดจเดฟเดเตเดเตพเดเตเดเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเตเดจเตเดจ เดตเตเดฌเต เดชเตเดเตเดเดณเตเดเต เดกเตเดฎเตเดฏเตโเดจเตเดเดณเตเด เดตเตเดฏเดเตเดคเดฎเดพเดฏเดฟ เดตเตเดฏเดเตเดคเดฎเดพเดเตเดเดพเตป เดเดดเดฟเดฏเตเด. เดเดฐเต เดกเตเดฎเตเดฏเตเตป เดฐเดฃเตเดเดพเด เดจเดฟเดฒเดฏเต เดเดฏเตผเดจเตเดจเดคเต เดเดเดพเด. เดซเดฏเตผเดซเตเดเตเดธเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ.
เดจเดฟเตผเดตเตเดตเดนเดฃ เดธเดจเตเดฆเตผเดญเด
เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเต เดฎเตเดจเตเดจเต เดเตเดกเต เดจเดฟเตผเดตเตเดตเดนเดฃ เดธเดจเตเดฆเตผเดญเดเตเดเดณเตเดฃเตเดเต, เด เดคเดพเดฏเดคเต, เดฌเตเดฐเตเดธเตผ API-เดฏเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดเตโเดธเดธเดฟเดจเตเดฑเต เดตเตเดฏเดคเตเดฏเดธเตเดค เดคเดฒเดเตเดเดณเตเดณเตเดณ เดฎเตเดจเตเดจเต เดญเดพเดเดเตเดเตพ เด เดชเตเดฒเดฟเดเตเดเตเดทเดจเดฟเตฝ เด เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดธเดจเตเดฆเตผเดญเด
เดฎเดฟเดเตเด API-เดเดณเตเด เดเดตเดฟเดเต เดฒเดญเตเดฏเดฎเดพเดฃเต. เด เดธเดพเดนเดเดฐเตเดฏเดคเตเดคเดฟเตฝ เด เดตเตผ "เดเตเดตเดฟเดเตเดเตเดจเตเดจเต":
- เดชเดถเตเดเดพเดคเตเดคเดฒ เดชเตเดเต - เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเตเดฑเต "เดฌเดพเดเตเดเตเตปเดกเต" เดญเดพเดเด. "เดชเดถเตเดเดพเดคเตเดคเดฒเด" เดเต เดเดชเดฏเตเดเดฟเดเตเดเต เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเดฟเตฝ เดซเดฏเตฝ เดตเตเดฏเดเตเดคเดฎเดพเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
- เดชเตเดชเตเดชเตเด
เดชเตเดชเต เดชเตเดเต โ เดจเดฟเดเตเดเตพ เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดเดเตเดเดฃเดฟเตฝ เดเตเดฒเดฟเดเตเดเต เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ เดฆเตเดถเตเดฏเดฎเดพเดเตเดจเตเดจ เดเดฐเต เดชเตเดชเตเดชเตเด
เดชเตเดชเต เดชเตเดเต. เดชเตเดฐเดเดเดจเดชเดคเตเดฐเดฟเดเดฏเดฟเตฝ
browser_action
->default_popup
. - เดเดทเตเดเดพเดจเตเดธเตเดค เดชเตเดเต - เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดชเตเดเต, เดเดพเดดเตโเดเดฏเตเดเต เดเดฐเต เดชเตเดฐเดคเตเดฏเตเด เดเดพเดฌเดฟเตฝ "เดเตเดตเดฟเดเตเดเตเดจเตเดจเดคเต"
chrome-extension://<id_ัะฐััะธัะตะฝะธั>/customPage.html
.
เด เดธเดจเตเดฆเตผเดญเด เดฌเตเดฐเตเดธเตผ เดตเดฟเตปเดกเตเดเดณเดฟเตฝ เดจเดฟเดจเตเดจเตเด เดเดพเดฌเตเดเดณเดฟเตฝ เดจเดฟเดจเตเดจเตเด เดธเตเดตเดคเดจเตเดคเตเดฐเดฎเดพเดฏเดฟ เดจเดฟเดฒเดจเดฟเตฝเดเตเดเตเดจเตเดจเต. เดชเดถเตเดเดพเดคเตเดคเดฒ เดชเตเดเต เดเดฐเตเดฑเตเดฑ เดชเดเตผเดชเตเดชเดฟเตฝ เดจเดฟเดฒเดตเดฟเดฒเตเดฃเตเดเต, เดเดฒเตเดฒเดพเดฏเตโเดชเตเดชเตเดดเตเด เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเต (เดเดฐเต เดเดตเดจเตเดฑเต เดชเดถเตเดเดพเดคเตเดคเดฒ เดธเตโเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดธเดฎเดพเดฐเดเดญเดฟเดเตเดเตเดเดฏเตเด เด เดคเดฟเดจเตเดฑเต เดจเดฟเตผเดตเตเดตเดนเดฃเดคเตเดคเดฟเดจเต เดถเตเดทเด โเดฎเดฐเดฟเดเตเดเตเดเดฏเตเดโ เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ เดเดตเดจเตเดฑเต เดชเตเดเดพเดฃเต เดเดดเดฟเดตเดพเดเตเดเตฝ. เดชเตเดชเตเดชเตเด เดชเตเดชเต เดชเตเดเต เดชเตเดชเตเดชเตเด เดชเตเดชเต เดตเดฟเตปเดกเต เดคเตเดฑเดเตเดเตเดฎเตเดชเตเตพ เดจเดฟเดฒเดตเดฟเดฒเตเดฃเตเดเต, เดเตเดเดพเดคเต เดเดทเตเดเดพเดจเตเดธเตเดค เดชเตเดเต โ เด เดคเดฟเดจเตเดณเตเดณ เดเดพเดฌเต เดคเตเดฑเดจเตเดจเดฟเดฐเดฟเดเตเดเตเดฎเตเดชเตเตพ. เด เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เดฎเดฑเตเดฑเต เดเดพเดฌเตเดเดณเดฟเดฒเตเดเตเดเตเด เด เดตเดฏเตเดเต เดเดณเตเดณเดเดเตเดเดเตเดเดณเดฟเดฒเตเดเตเดเตเด เดชเตเดฐเดตเตเดถเดจเดฎเดฟเดฒเตเดฒ.
เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดธเดจเตเดฆเตผเดญเด
เดเดฐเต เดฌเตเดฐเตเดธเตผ เดเดพเดฌเดฟเดจเตเดชเตเดชเด เดเดณเตเดณเดเดเตเด เดธเตโเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดซเดฏเตฝ เดธเดฎเดพเดฐเดเดญเดฟเดเตเดเต. เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเตเดฑเต API เดฏเตเดเต เดญเดพเดเดคเตเดคเดฟเดฒเตเดเตเดเตเด เดตเตเดฌเต เดชเตเดเดฟเดจเตเดฑเต DOM เดเตเดฐเตเดฏเดฟเดฒเตเดเตเดเตเด เดเดคเดฟเดจเต เดเดเตโเดธเดธเต เดเดฃเตเดเต. เดชเตเดเตเดฎเดพเดฏเตเดณเตเดณ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเดคเตเดคเดฟเดจเต เดเดคเตเดคเดฐเดตเดพเดฆเดฟเดเตพ เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเดณเดพเดฃเต. DOM เดเตเดฐเต เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเตเดจเตเดจ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดเตเดเตพ เดเดคเต เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเตเดเดณเดฟเตฝ เดเตเดฏเตเดฏเตเดจเตเดจเต - เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดชเดฐเดธเตเดฏ เดฌเตเดฒเตเดเตเดเดฑเตเดเตพ เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดตเดฟเดตเตผเดคเตเดคเดเตผ. เดเตเดเดพเดคเต, เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเดฟเดจเต เดธเตเดฑเตเดฑเดพเตปเดกเตเตผเดกเต เดตเดดเดฟ เดชเตเดเตเดฎเดพเดฏเดฟ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเด เดจเดเดคเตเดคเดพเดจเดพเดเตเด postMessage
.
เดตเตเดฌเต เดชเตเดเต เดธเดจเตเดฆเตผเดญเด
เดเดคเดพเดฃเต เดฏเดฅเดพเตผเดคเตเดฅ เดตเตเดฌเต เดชเตเดเต. เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเดฟเตฝ เด เดชเตเดเดฟเดจเตเดฑเต เดกเตเดฎเตเดฏเตโเตป เดตเตเดฏเดเตเดคเดฎเดพเดฏเดฟ เดธเตเดเดฟเดชเตเดชเดฟเดเตเดเดฟเดเตเดเดฟเดฒเตเดฒเดพเดคเตเดค เดธเดจเตเดฆเตผเดญเดเตเดเดณเดฟเดฒเตเดดเดฟเดเต เดเดคเดฟเดจเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดตเตเดฎเดพเดฏเดฟ เดฏเดพเดคเตเดฐเต เดฌเดจเตเดงเดตเตเดฎเดฟเดฒเตเดฒ (เดเตเดตเดเตเดฏเตเดณเตเดณเดคเดฟเตฝ เดเตเดเตเดคเตฝ).
เดธเดจเตเดฆเตเดถ เดเตเดฎเดพเดฑเตเดฑเด
เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดฑเต เดตเดฟเดตเดฟเดง เดญเดพเดเดเตเดเตพ เดชเดฐเดธเตเดชเดฐเด เดธเดจเตเดฆเตเดถเดเตเดเตพ เดเตเดฎเดพเดฑเดฃเด. เดเดคเดฟเดจเดพเดฏเดฟ เดเดฐเต API เดเดฃเตเดเต runtime.sendMessage
เดเดฐเต เดธเดจเตเดฆเตเดถเด เด
เดฏเดฏเตเดเตเดเดพเตป background
ะธ tabs.sendMessage
เดเดฐเต เดชเตเดเดฟเดฒเตเดเตเดเต เดเดฐเต เดธเดจเตเดฆเตเดถเด เด
เดฏเดเตเดเดพเตป (เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเต, เดชเตเดชเตเดชเตเด
เดชเตเดชเต เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดตเตเดฌเต เดชเตเดเต เดฒเดญเตเดฏเดฎเดพเดฃเตเดเตเดเดฟเตฝ externally_connectable
). Chrome API เดเดเตเดธเดธเต เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ เดเดฐเต เดเดฆเดพเดนเดฐเดฃเด เดเตเดตเดเตเดฏเตเดฃเตเดเต.
// ะกะพะพะฑัะตะฝะธะตะผ ะผะพะถะตั ะฑััั ะปัะฑะพะน JSON ัะตัะธะฐะปะธะทัะตะผัะน ะพะฑัะตะบั
const msg = {a: 'foo', b: 'bar'};
// extensionId ะผะพะถะฝะพ ะฝะต ัะบะฐะทัะฒะฐัั, ะตัะปะธ ะผั ั
ะพัะธะผ ะฟะพัะปะฐัั ัะพะพะฑัะตะฝะธะต 'ัะฒะพะตะผั' ัะฐััะธัะตะฝะธั (ะธะท ui ะธะปะธ ะบะพะฝัะตะฝั ัะบัะธะฟัะฐ)
chrome.runtime.sendMessage(extensionId, msg);
// ะขะฐะบ ะฒัะณะปัะดะธั ะพะฑัะฐะฑะพััะธะบ
chrome.runtime.onMessage.addListener((msg) => console.log(msg))
// ะะพะถะฝะพ ัะปะฐัั ัะพะพะฑัะตะฝะธั ะฒะบะปะฐะดะบะฐะผ ะทะฝะฐั ะธั
id
chrome.tabs.sendMessage(tabId, msg)
// ะะพะปััะธัั ะบ ะฒะบะปะฐะดะบะฐะผ ะธ ะธั
id ะผะพะถะฝะพ, ะฝะฐะฟัะธะผะตั, ะฒะพั ัะฐะบ
chrome.tabs.query(
{currentWindow: true, active : true},
function(tabArray){
tabArray.forEach(tab => console.log(tab.id))
}
)
เดชเตเตผเดฃเตเดฃ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเดคเตเดคเดฟเดจเดพเดฏเดฟ, เดจเดฟเดเตเดเตพเดเตเดเต เดเดฃเดเตเดทเดจเตเดเตพ เดธเตเดทเตเดเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเตเด runtime.connect
. เดชเตเดฐเดคเดฟเดเดฐเดฃเดฎเดพเดฏเดฟ เดจเดฎเตเดเตเดเต เดฒเดญเดฟเดเตเดเตเด runtime.Port
, เด
เดคเดฟเดฒเตเดเตเดเต, เด
เดคเต เดคเตเดฑเดจเตเดจเดฟเดฐเดฟเดเตเดเตเดฎเตเดชเตเตพ, เดจเดฟเดเตเดเตพเดเตเดเต เดเดคเตเดฐ เดธเดจเตเดฆเตเดถเดเตเดเตพ เดตเตเดฃเดฎเตเดเตเดเดฟเดฒเตเด เด
เดฏเดฏเตเดเตเดเดพเด. เดเดชเดญเตเดเตเดคเดพเดตเดฟเดจเตเดฑเต เดญเดพเดเดคเตเดคเต, เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, contentscript
, เดเดคเต เดเดคเตเดชเตเดฒเต เดเดพเดฃเดชเตเดชเตเดเตเดจเตเดจเต:
// ะะฟััั ะถะต extensionId ะผะพะถะฝะพ ะฝะต ัะบะฐะทัะฒะฐัั ะฟัะธ ะบะพะผะผัะฝะธะบะฐัะธะธ ะฒะฝัััะธ ะพะดะฝะพะณะพ ัะฐััะธัะตะฝะธั. ะะพะดะบะปััะตะฝะธะต ะผะพะถะฝะพ ะธะผะตะฝะพะฒะฐัั
const port = chrome.runtime.connect({name: "knockknock"});
port.postMessage({joke: "Knock knock"});
port.onMessage.addListener(function(msg) {
if (msg.question === "Who's there?")
port.postMessage({answer: "Madame"});
else if (msg.question === "Madame who?")
port.postMessage({answer: "Madame... Bovary"});
เดธเตเตผเดตเตผ เด เดฒเตเดฒเตเดเตเดเดฟเตฝ เดชเดถเตเดเดพเดคเตเดคเดฒเด:
// ะะฑัะฐะฑะพััะธะบ ะดะปั ะฟะพะดะบะปััะตะฝะธั 'ัะฒะพะธั
' ะฒะบะปะฐะดะพะบ. ะะพะฝัะตะฝั ัะบัะธะฟัะพะฒ, popup ะธะปะธ ัััะฐะฝะธั ัะฐััะธัะตะฝะธั
chrome.runtime.onConnect.addListener(function(port) {
console.assert(port.name === "knockknock");
port.onMessage.addListener(function(msg) {
if (msg.joke === "Knock knock")
port.postMessage({question: "Who's there?"});
else if (msg.answer === "Madame")
port.postMessage({question: "Madame who?"});
else if (msg.answer === "Madame... Bovary")
port.postMessage({question: "I don't get it."});
});
});
// ะะฑัะฐะฑะพััะธะบ ะดะปั ะฟะพะดะบะปััะตะฝะธั ะฒะฝะตัะฝะธั
ะฒะบะปะฐะดะพะบ. ะััะณะธั
ัะฐััะธัะตะฝะธะน ะธะปะธ ะฒะตะฑ ัััะฐะฝะธั, ะบะพัะพััะผ ัะฐะทัะตัะตะฝ ะดะพัััะฟ ะฒ ะผะฐะฝะธัะตััะต
chrome.runtime.onConnectExternal.addListener(function(port) {
...
});
เดเดฐเต เดธเดเดญเดตเดตเตเดฎเตเดฃเตเดเต onDisconnect
เดฐเตเดคเดฟเดฏเตเด disconnect
.
เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดกเดฏเดเตเดฐเด
เดธเตเดตเดเดพเดฐเตเดฏ เดเตเดเตพ เดธเดเดญเดฐเดฟเดเตเดเตเดจเตเดจเดคเตเด เดชเตเดคเต เดตเดฟเดตเดฐเดเตเดเดณเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดเตโเดธเดธเต เดจเตฝเดเตเดจเตเดจเดคเตเดฎเดพเดฏ เดเดฐเต เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเด เดจเดฎเตเดเตเดเต เดเดฃเตเดเดพเดเตเดเดพเด (เดตเดฟเดฒเดพเดธเด, เดชเตเดคเต เดเต เดชเตเดเตเดฎเดพเดฏเดฟ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเด เดจเดเดคเตเดคเตเดเดฏเตเด เดเดเดชเดพเดเตเดเตพเดเตเดเดพเดฏเดฟ เดเดชเตเดชเต เด เดญเตเดฏเตผเดคเตเดฅเดฟเดเตเดเดพเตป เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เด เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเดณเต เด เดจเตเดตเดฆเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต.
เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดตเดฟเดเดธเดจเด
เดเดเตเดเดณเตเดเต เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดชเดฏเตเดเตเดคเดพเดตเตเดฎเดพเดฏเดฟ เดธเดเดตเดฆเดฟเดเตเดเตเดเดฏเตเด เดเตเตพ เดฐเตเดคเดฟเดเตพเดเตเดเดพเดฏเดฟ เดเดฐเต API เดเดณเตเดณ เดชเตเดเต เดจเตฝเดเตเดเดฏเตเด เดตเตเดฃเด (เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดเดเดชเดพเดเตเดเดณเดฟเตฝ เดเดชเตเดชเดฟเดเตเดจเตเดจเดคเดฟเดจเต). เดเดจเตเดจเต เดเตเดฃเตเดเต เดฎเดพเดคเตเดฐเด เดเตเดฏเตเดฏเตเด contentscript
เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเดฟเดฒเตเดฒ, เดเดพเดฐเดฃเด เดเดคเดฟเดจเต DOM-เดฒเตเดเตเดเต เดฎเดพเดคเตเดฐเดฎเต เดเดเตโเดธเดธเต เดเดณเตเดณเต, เดชเดเตเดทเต เดชเตเดเดฟเดจเตเดฑเต JS-เดฒเตเดเตเดเต เด
เดฒเตเดฒ. เดตเดดเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเด runtime.connect
เดเดเตเดเตพเดเตเดเต เดเดดเดฟเดฏเดฟเดฒเตเดฒ, เดเดพเดฐเดฃเด เดเดฒเตเดฒเดพ เดกเตเดฎเตเดฏเตโเดจเตเดเดณเดฟเดฒเตเด API เดเดตเดถเตเดฏเดฎเดพเดฃเต, เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ เดจเดฟเตผเดฆเตเดฆเดฟเดทเตเดเดต เดฎเดพเดคเตเดฐเดฎเต เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเดฟเตฝ เดตเตเดฏเดเตเดคเดฎเดพเดเตเดเดพเตป เดเดดเดฟเดฏเต. เดคเตฝเดซเดฒเดฎเดพเดฏเดฟ, เดกเดฏเดเตเดฐเด เดเดคเตเดชเตเดฒเต เดเดพเดฃเดชเตเดชเตเดเตเด:
เดฎเดฑเตเดฑเตเดฐเต เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดเดฃเตเดเดพเดเตเด - inpage
, เด
เดคเต เดเดเตเดเตพ เดชเตเดเดฟเดฒเตเดเตเดเต เดเตเดคเตเดคเดฟเดตเดฏเตเดเตเดเตเด. เดเดคเต เด
เดคเดฟเดจเตเดฑเต เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดเดฏเตเด เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเตเดชเตเดชเด เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเดพเตป เดเดฐเต API เดจเตฝเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเด.
เดคเตเดเดเตเดเด
เดเดฒเตเดฒเดพ เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดเตเดกเตเด เดเดตเดฟเดเต เดฒเดญเตเดฏเดฎเดพเดฃเต
เดจเดฎเตเดเตเดเต เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเตเดฏเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดฐเดเดญเดฟเดเตเดเดพเด:
{
// ะะผั ะธ ะพะฟะธัะฐะฝะธะต, ะฒะตััะธั. ะัะต ััะพ ะฑัะดะตั ะฒะธะดะฝะพ ะฒ ะฑัะฐัะทะตัะต ะฒ chrome://extensions/?id=<id ัะฐััะธัะตะฝะธั>
"name": "Signer",
"description": "Extension demo",
"version": "0.0.1",
"manifest_version": 2,
// ะกะบัะธะฟัั, ะบะพัะพััะต ะฑัะดัั ะธัะฟะพะปะฝัััั ะฒ background, ะธั
ะผะพะถะตั ะฑััั ะฝะตัะบะพะปัะบะพ
"background": {
"scripts": ["background.js"]
},
// ะะฐะบะพะน html ะธัะฟะพะปัะทะพะฒะฐัั ะดะปั popup
"browser_action": {
"default_title": "My Extension",
"default_popup": "popup.html"
},
// ะะพะฝัะตะฝั ัะบัะธะฟัั.
// ะฃ ะฝะฐั ะพะดะธะฝ ะพะฑัะตะบั: ะดะปั ะฒัะตั
url ะฝะฐัะธะฝะฐััะธั
ัั ั http ะธะปะธ https ะผั ะทะฐะฟััะบะฐะตะผ
// contenscript context ัะพ ัะบัะธะฟัะพะผ contentscript.js. ะะฐะฟััะบะฐัั ััะฐะทั ะฟะพ ะฟะพะปััะตะฝะธะธ ะดะพะบัะผะตะฝัะฐ ะดะปั ะฒัะตั
ััะตะนะผะพะฒ
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"contentscript.js"
],
"run_at": "document_start",
"all_frames": true
}
],
// ะ ะฐะทัะตัะตะฝ ะดะพัััะฟ ะบ localStorage ะธ idle api
"permissions": [
"storage",
// "unlimitedStorage",
//"clipboardWrite",
"idle"
//"activeTab",
//"webRequest",
//"notifications",
//"tabs"
],
// ะะดะตัั ัะบะฐะทัะฒะฐัััั ัะตััััั, ะบ ะบะพัะพััะผ ะฑัะดะตั ะธะผะตัั ะดะพัััะฟ ะฒะตะฑ ัััะฐะฝะธัะฐ. ะขะพะตััั ะธั
ะผะพะถะฝะพ ะฑัะดะตั ะทะฐะฟัะฐัะธะฒะฐัั fetche'ะผ ะธะปะธ ะฟัะพััะพ xhr
"web_accessible_resources": ["inpage.js"]
}
เดถเตเดจเตเดฏเดฎเดพเดฏ background.js, popup.js, inpage.js, contentscript.js เดเดจเตเดจเดฟเดต เดธเตเดทเตโเดเดฟเดเตเดเตเด. เดเดเตเดเตพ popup.html เดเตเตผเดเตเดเตเดจเตเดจเต - เดเดเตเดเดณเตเดเต เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดคเดฟเดจเดเด เดคเดจเตเดจเต Google Chrome-เตฝ เดฒเตเดกเตเดเตเดฏเตเดฏเดพเดจเตเด เด เดคเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเตเดตเตเดจเตเดจเต เดเดฑเดชเตเดชเดพเดเตเดเดพเดจเตเด เดเดดเดฟเดฏเตเด.
เดเดคเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเดพเตป, เดจเดฟเดเตเดเตพเดเตเดเต เดเตเดกเต เดเดเตเดเตเดเดพเด
เดเดชเตเดชเตเตพ เดเดเตเดเดณเตเดเต เดตเดฟเดชเตเดฒเตเดเดฐเดฃเด เดเตปเดธเตเดฑเตเดฑเดพเตพ เดเตเดฏเตเดฏเตเดเดฏเตเด เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต. เดตเตเดฏเดคเตเดฏเดธเตเดค เดธเดจเตเดฆเตผเดญเดเตเดเตพเดเตเดเดพเดฏเดฟ เดจเดฟเดเตเดเตพเดเตเดเต เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดฐเตเดคเดฟเดฏเดฟเตฝ เดกเดตเดฒเดชเตเดชเตผ เดเตเดณเตเดเตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเตเด:
เดชเตเดชเตเดชเตเด เดชเตเดชเต ->
เดเดณเตเดณเดเดเตเด เดธเตโเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดเตบเดธเตเดณเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดเตโเดธเดธเต เด เดคเต เดธเดฎเดพเดฐเดเดญเดฟเดเตเด เดชเตเดเดฟเดจเตเดฑเต เดเตบเดธเตเตพ เดตเดดเดฟเดฏเดพเดฃเต เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเดคเต.
เดธเดจเตเดฆเตเดถ เดเตเดฎเดพเดฑเตเดฑเด
เด เดคเดฟเดจเดพเตฝ, เดเดเตเดเตพ เดฐเดฃเตเดเต เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏ เดเดพเดจเดฒเตเดเตพ เดธเตเดฅเดพเดชเดฟเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต: เดเตปเดชเตเดเต เดชเดถเตเดเดพเดคเตเดคเดฒเดตเตเด เดชเตเดชเตเดชเตเด เดชเตเดชเต เดชเดถเตเดเดพเดคเตเดคเดฒเดตเตเด. เดจเดฟเดเตเดเตพเดเตเดเต เดคเตเตผเดเตเดเดฏเดพเดฏเตเด เดชเตเตผเดเตเดเดฟเดฒเตเดเตเดเต เดธเดจเตเดฆเตเดถเดเตเดเตพ เด เดฏเดฏเตโเดเตเดเดพเดจเตเด เดจเดฟเดเตเดเดณเตเดเต เดธเตเดตเดจเตเดคเด เดชเตเดฐเตเดเตเดเตเดเตเดเตเตพ เดเดฃเตเดเตเดชเดฟเดเดฟเดเตเดเดพเดจเตเด เดเดดเดฟเดฏเตเด, เดเดจเตเดจเดพเตฝ เดฎเตเดฑเตเดฑเดพเดฎเดพเดธเตเดเต เดเดชเตเดชเตบ เดธเตเดดเตโเดธเต เดชเตเดฐเตเดเดเตเดฑเตเดฑเดฟเตฝ เดเดพเตป เดเดฃเตเด เดธเดฎเตเดชเดจเดฎเดพเดฃเต เดเดพเตป เดเดทเตเดเดชเตเดชเตเดเตเดจเตเดจเดคเต.
Ethereum เดจเตเดฑเตเดฑเตโเดตเตผเดเตเดเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดเดฐเต เดฌเตเดฐเตเดธเตผ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดฎเดพเดฃเดฟเดคเต. เด เดคเดฟเตฝ, เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดฑเต เดตเดฟเดตเดฟเดง เดญเดพเดเดเตเดเตพ dnode เดฒเตเดฌเตเดฐเดฑเดฟ เดเดชเดฏเตเดเดฟเดเตเดเต RPC เดตเดดเดฟ เดเดถเดฏเดตเดฟเดจเดฟเดฎเดฏเด เดจเดเดคเตเดคเตเดจเตเดจเต. เดจเดฟเดเตเดเตพ เดเดฐเต เดเตเดฐเดพเตปเดธเตโเดชเตเตผเดเตเดเต เดเดฏเดฟ เดเดฐเต nodejs เดธเตเดเตเดฐเตเด เดจเตฝเดเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ (เด เดคเดพเดฏเดคเต เดเดฐเต เดเดจเตเดฑเตผเดซเตเดธเต เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจ เดเดฐเต เดเดฌเตโเดเดเตเดฑเตเดฑเต) เดเดฐเต เดเดเตเดธเตเดเตเดเตเดเต เดตเดณเดฐเต เดตเตเดเดคเตเดคเดฟเดฒเตเด เดธเตเดเดฐเตเดฏเดชเตเดฐเดฆเดฎเดพเดฏเตเด เดธเดเดเดเดฟเดชเตเดชเดฟเดเตเดเดพเตป เดเดคเต เดจเดฟเดเตเดเดณเต เด เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต:
import Dnode from "dnode/browser";
// ะ ััะพะผ ะฟัะธะผะตัะต ััะปะพะฒะธะผัั ััะพ ะบะปะธะตะฝั ัะดะฐะปะตะฝะฝะพ ะฒัะทัะฒะฐะตั ััะฝะบัะธะธ ะฝะฐ ัะตัะฒะตัะต, ั
ะพัั ะฝะธัะตะณะพ ะฝะฐะผ ะฝะต ะผะตัะฐะตั ัะดะตะปะฐัั ััะพ ะดะฒัะฝะฐะฟัะฐะฒะปะตะฝะฝัะผ
// Cะตัะฒะตั
// API, ะบะพัะพัะพะต ะผั ั
ะพัะธะผ ะฟัะตะดะพััะฐะฒะธัั
const dnode = Dnode({
hello: (cb) => cb(null, "world")
})
// ะขัะฐะฝัะฟะพัั, ะฟะพะฒะตัั
ะบะพัะพัะพะณะพ ะฑัะดะตั ัะฐะฑะพัะฐัั dnode. ะัะฑะพะน nodejs ัััะธะผ. ะ ะฑัะฐัะทะตัะต ะตััั ะฑะธะฑะธะปะธะพัะตะบะฐ 'readable-stream'
connectionStream.pipe(dnode).pipe(connectionStream)
// ะะปะธะตะฝั
const dnodeClient = Dnode() // ะัะทะพะฒ ะฑะตะท ะฐะณััะผะตะฝัะฐ ะทะฝะฐัะธั ััะพ ะผั ะฝะต ะฟัะตะดะพััะฐะฒะปัะตะผ API ะฝะฐ ะดััะณะพะน ััะพัะพะฝะต
// ะัะฒะตะดะตั ะฒ ะบะพะฝัะพะปั world
dnodeClient.once('remote', remote => {
remote.hello(((err, value) => console.log(value)))
})
เดเดชเตเดชเตเตพ เดเดเตเดเตพ เดเดฐเต เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเตเดฒเดพเดธเต เดธเตเดทเตเดเดฟเดเตเดเตเด. เดเดคเต เดชเตเดชเตเดชเตเด เดชเตเดชเดฟเดจเตเด เดตเตเดฌเต เดชเตเดเดฟเดจเตเดฎเดพเดฏเดฟ API เดเดฌเตโเดเดเตเดฑเตเดฑเตเดเตพ เดธเตเดทเตโเดเดฟเดเตเดเตเดเดฏเตเด เด เดตเดฏเตโเดเตเดเดพเดฏเดฟ เดเดฐเต dnode เดธเตเดทเตโเดเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเด:
import Dnode from 'dnode/browser';
export class SignerApp {
// ะะพะทะฒัะฐัะฐะตั ะพะฑัะตะบั API ะดะปั ui
popupApi(){
return {
hello: cb => cb(null, 'world')
}
}
// ะะพะทะฒัะฐัะฐะตั ะพะฑัะตั API ะดะปั ัััะฐะฝะธัั
pageApi(){
return {
hello: cb => cb(null, 'world')
}
}
// ะะพะดะบะปััะฐะตั popup ui
connectPopup(connectionStream){
const api = this.popupApi();
const dnode = Dnode(api);
connectionStream.pipe(dnode).pipe(connectionStream);
dnode.on('remote', (remote) => {
console.log(remote)
})
}
// ะะพะดะบะปััะฐะตั ัััะฐะฝะธัั
connectPage(connectionStream, origin){
const api = this.popupApi();
const dnode = Dnode(api);
connectionStream.pipe(dnode).pipe(connectionStream);
dnode.on('remote', (remote) => {
console.log(origin);
console.log(remote)
})
}
}
เดเดตเดฟเดเตเดฏเตเด เดคเดพเดดเตเดฏเตเด, เดเดเตเดณ Chrome เดเดฌเตโเดเดเตเดฑเตเดฑเดฟเดจเต เดชเดเดฐเด, เดเดเตเดเตพ extensionApi เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต, เด เดคเต Google-เดจเตเดฑเต เดฌเตเดฐเตเดธเดฑเดฟเตฝ Chrome เดเดเตโเดธเดธเต เดเตเดฏเตเดฏเตเดจเตเดจเต, เดฎเดฑเตเดฑเตเดณเตเดณเดตเดฏเดฟเตฝ เดฌเตเดฐเตเดธเดฑเตเด. เดเตเดฐเตเดธเต-เดฌเตเดฐเตเดธเตผ เด เดจเตเดฏเตเดเตเดฏเดคเดฏเตเดเตเดเดพเดฏเดพเดฃเต เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเต, เดเดจเตเดจเดพเตฝ เด เดฒเตเดเดจเดคเตเดคเดฟเดจเตเดฑเต เดเดฆเตเดฆเตเดถเตเดฏเดเตเดเตพเดเตเดเดพเดฏเดฟ, เดจเดฟเดเตเดเตพเดเตเดเต 'chrome.runtime.connect' เดเดชเดฏเตเดเดฟเดเตเดเดพเด.
เดฌเดพเดเตเดเตเดเตเดฐเตเดฃเตเดเต เดธเตโเดเตเดฐเดฟเดชเตเดฑเตเดฑเดฟเตฝ เดเดฐเต เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเตปเดธเตโเดฑเตเดฑเตปเดธเต เดธเตเดทเตโเดเดฟเดเตเดเดพเด:
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import {SignerApp} from "./SignerApp";
const app = new SignerApp();
// onConnect ััะฐะฑะฐััะฒะฐะตั ะฟัะธ ะฟะพะดะบะปััะตะฝะธะธ 'ะฟัะพัะตััะพะฒ' (contentscript, popup, ะธะปะธ ัััะฐะฝะธัะฐ ัะฐััะธัะตะฝะธั)
extensionApi.runtime.onConnect.addListener(connectRemote);
function connectRemote(remotePort) {
const processName = remotePort.name;
const portStream = new PortStream(remotePort);
// ะัะธ ัััะฐะฝะพะฒะบะต ัะพะตะดะธะฝะตะฝะธั ะผะพะถะฝะพ ัะบะฐะทัะฒะฐัั ะธะผั, ะฟะพ ััะพะผั ะธะผะตะฝะธ ะผั ะธ ะพะฟะฟัะตะดะตะปัะตะผ ะบัะพ ะบ ะฝะฐะผ ะฟะพะดะปััะธะปัั, ะบะพะฝัะตะฝััะบัะธะฟั ะธะปะธ ui
if (processName === 'contentscript'){
const origin = remotePort.sender.url
app.connectPage(portStream, origin)
}else{
app.connectPopup(portStream)
}
}
dnode เดธเตเดเตเดฐเตเดฎเตเดเดณเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดเดฏเตเด เดเดเตเดเตพเดเตเดเต เดเดฐเต เดชเตเตผเดเตเดเต เดฒเดญเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเดพเตฝ, เดเดฐเต เด เดกเดพเดชเตเดฑเตเดฑเตผ เดเตเดฒเดพเดธเต เดเดตเดถเตเดฏเดฎเดพเดฃเต. เดฌเตเดฐเตเดธเดฑเดฟเตฝ nodejs เดธเตเดเตเดฐเตเดฎเตเดเตพ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจ เดฑเตเดกเดฌเดฟเตพ-เดธเตเดเตเดฐเตเด เดฒเตเดฌเตเดฐเดฑเดฟ เดเดชเดฏเตเดเดฟเดเตเดเดพเดฃเต เดเดคเต เดจเดฟเตผเดฎเตเดฎเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเต:
import {Duplex} from 'readable-stream';
export class PortStream extends Duplex{
constructor(port){
super({objectMode: true});
this._port = port;
port.onMessage.addListener(this._onMessage.bind(this));
port.onDisconnect.addListener(this._onDisconnect.bind(this))
}
_onMessage(msg) {
if (Buffer.isBuffer(msg)) {
delete msg._isBuffer;
const data = new Buffer(msg);
this.push(data)
} else {
this.push(msg)
}
}
_onDisconnect() {
this.destroy()
}
_read(){}
_write(msg, encoding, cb) {
try {
if (Buffer.isBuffer(msg)) {
const data = msg.toJSON();
data._isBuffer = true;
this._port.postMessage(data)
} else {
this._port.postMessage(msg)
}
} catch (err) {
return cb(new Error('PortStream - disconnected'))
}
cb()
}
}
เดเดจเดฟ เดจเดฎเตเดเตเดเต เดฏเตเดเดฏเดฟเตฝ เดเดฐเต เดเดฃเดเตเดทเตป เดเดฃเตเดเดพเดเตเดเดพเด:
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import Dnode from 'dnode/browser';
const DEV_MODE = process.env.NODE_ENV !== 'production';
setupUi().catch(console.error);
async function setupUi(){
// ะขะฐะบะถะต, ะบะฐะบ ะธ ะฒ ะบะปะฐััะต ะฟัะธะปะพะถะตะฝะธั ัะพะทะดะฐะตะผ ะฟะพัั, ะพะฑะพัะฐัะธะฒะฐะตะผ ะฒ stream, ะดะตะปะฐะตะผ dnode
const backgroundPort = extensionApi.runtime.connect({name: 'popup'});
const connectionStream = new PortStream(backgroundPort);
const dnode = Dnode();
connectionStream.pipe(dnode).pipe(connectionStream);
const background = await new Promise(resolve => {
dnode.once('remote', api => {
resolve(api)
})
});
// ะะตะปะฐะตะผ ะพะฑัะตะบั API ะดะพัััะฟะฝัะผ ะธะท ะบะพะฝัะพะปะธ
if (DEV_MODE){
global.background = background;
}
}
เดคเตเดเตผเดจเตเดจเต เดเดเตเดเตพ เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเดฟเตฝ เดเดฃเดเตเดทเตป เดธเตเดทเตเดเดฟเดเตเดเตเดจเตเดจเต:
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import PostMessageStream from 'post-message-stream';
setupConnection();
injectScript();
function setupConnection(){
const backgroundPort = extensionApi.runtime.connect({name: 'contentscript'});
const backgroundStream = new PortStream(backgroundPort);
const pageStream = new PostMessageStream({
name: 'content',
target: 'page',
});
pageStream.pipe(backgroundStream).pipe(pageStream);
}
function injectScript(){
try {
// inject in-page script
let script = document.createElement('script');
script.src = extensionApi.extension.getURL('inpage.js');
const container = document.head || document.documentElement;
container.insertBefore(script, container.children[0]);
script.onload = () => script.remove();
} catch (e) {
console.error('Injection failed.', e);
}
}
เดเดเตเดเตพเดเตเดเต API เดเดตเดถเตเดฏเดฎเตเดณเตเดณเดคเต เดเดณเตเดณเดเดเตเด เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเดฟเดฒเดฒเตเดฒ, เดฎเดฑเดฟเดเตเดเต เดจเตเดฐเดฟเดเตเดเต เดชเตเดเดฟเตฝ เดเดฏเดคเดฟเดจเดพเตฝ, เดเดเตเดเตพ เดฐเดฃเตเดเต เดเดพเดฐเตเดฏเดเตเดเตพ เดเตเดฏเตเดฏเตเดจเตเดจเต:
- เดเดเตเดเตพ เดฐเดฃเตเดเต เดธเตเดเตเดฐเตเดฎเตเดเตพ เดธเตเดทเตเดเดฟเดเตเดเตเดจเตเดจเต. เดเดจเตเดจเต - เดชเตเดเดฟเดจเต เดจเตเดฐเต, เดชเตเดธเตเดฑเตเดฑเต เดฎเตเดธเตเดเดฟเดจเต เดฎเตเดเดณเดฟเตฝ. เดเดคเดฟเดจเดพเดฏเดฟ เดเดเตเดเตพ เดเดคเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต
เด เดชเดพเดเตเดเตเดเต เดฎเตเดฑเตเดฑเดพเดฎเดพเดธเตเดเดฟเดจเตเดฑเต เดธเตเดฐเดทเตโเดเดพเดเตเดเดณเดฟเตฝ เดจเดฟเดจเตเดจเต. เดฐเดฃเตเดเดพเดฎเดคเตเดคเต เดธเตเดเตเดฐเตเด เดฒเดญเดฟเดเตเดเตเดจเตเดจเดคเต เดชเตเตผเดเตเดเดฟเดจเตเดฑเต เดชเดถเตเดเดพเดคเตเดคเดฒเดคเตเดคเดฟเดฒเดพเดฃเตruntime.connect
. เดจเดฎเตเดเตเดเต เด เดต เดตเดพเดเตเดเดพเด. เดเดชเตเดชเตเตพ เดชเตเดเดฟเดจเต เดชเดถเตเดเดพเดคเตเดคเดฒเดคเตเดคเดฟเดฒเตเดเตเดเต เดเดฐเต เดธเตเดเตเดฐเตเด เดเดฃเตเดเดพเดเตเด. - DOM-เดฒเตเดเตเดเต เดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดเตเดคเตเดคเดฟเดตเดฏเตเดเตเดเตเด. เดธเตโเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดกเตเตบเดฒเตเดกเต เดเตเดฏเตเดฏเตเด (เด
เดคเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดเตโเดธเดธเต เดฎเดพเดจเดฟเดซเตเดธเตเดฑเตเดฑเดฟเตฝ เด
เดจเตเดตเดฆเดฟเดเตเดเดฟเดฐเตเดจเตเดจเต) เดเตเดเดพเดคเต เดเดฐเต เดเดพเดเต เดธเตเดทเตโเดเดฟเดเตเดเตเด
script
เด เดคเดฟเดจเตเดฑเต เดเดณเตเดณเดเดเตเดเดเตเดเตพ เดเดณเตเดณเดฟเตฝ:
import PostMessageStream from 'post-message-stream';
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
setupConnection();
injectScript();
function setupConnection(){
// ะกััะธะผ ะบ ะฑะตะบะณัะฐัะฝะดั
const backgroundPort = extensionApi.runtime.connect({name: 'contentscript'});
const backgroundStream = new PortStream(backgroundPort);
// ะกััะธะผ ะบ ัััะฐะฝะธัะต
const pageStream = new PostMessageStream({
name: 'content',
target: 'page',
});
pageStream.pipe(backgroundStream).pipe(pageStream);
}
function injectScript(){
try {
// inject in-page script
let script = document.createElement('script');
script.src = extensionApi.extension.getURL('inpage.js');
const container = document.head || document.documentElement;
container.insertBefore(script, container.children[0]);
script.onload = () => script.remove();
} catch (e) {
console.error('Injection failed.', e);
}
}
เดเดชเตเดชเตเตพ เดเดเตเดเตพ เดเตปเดชเตเดเดฟเตฝ เดเดฐเต เดเดชเดฟเด เดเดฌเตโเดเดเตเดฑเตเดฑเต เดธเตเดทเตโเดเดฟเดเตเดเตเดเดฏเตเด เด เดคเต เดเดเตเดณเดฎเดพเดฏเดฟ เดธเดเตเดเดฎเดพเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต:
import PostMessageStream from 'post-message-stream';
import Dnode from 'dnode/browser';
setupInpageApi().catch(console.error);
async function setupInpageApi() {
// ะกััะธะผ ะบ ะบะพะฝัะตะฝััะบัะธะฟัั
const connectionStream = new PostMessageStream({
name: 'page',
target: 'content',
});
const dnode = Dnode();
connectionStream.pipe(dnode).pipe(connectionStream);
// ะะพะปััะฐะตะผ ะพะฑัะตะบั API
const pageApi = await new Promise(resolve => {
dnode.once('remote', api => {
resolve(api)
})
});
// ะะพัััะฟ ัะตัะตะท window
global.SignerApp = pageApi;
}
เดเดเตเดเตพ เดคเดฏเตเดฏเดพเดฑเดพเดฃเต
เดถเตเดจเตเดฏเดฎเดพเดฏ API, เดเดคเตเดญเดตเด. เดชเตเดเดฟเดจเตเดฑเต เดญเดพเดเดคเตเดคเต, เดจเดฎเตเดเตเดเต เดนเดฒเต เดซเดเดเตโเดทเดจเต เดเดคเตเดชเตเดฒเต เดตเดฟเดณเดฟเดเตเดเดพเด:
เดเดงเตเดจเดฟเด JS-เตฝ เดเตเตพเดฌเดพเดเตเดเต เดซเดเดเตโเดทเดจเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเดคเต เดฎเตเดถเด เดชเตเดฐเตเดฎเดพเดฑเตเดฑเดฎเดพเดฃเต, เด เดคเดฟเดจเดพเตฝ เดเดฐเต API เดเดฌเตโเดเดเตเดฑเตเดฑเต เดฏเตเดเตเดเดฟเดฒเตเดเดณเดฟเดฒเตเดเตเดเต เดเตเดฎเดพเดฑเดพเตป เดจเดฟเดเตเดเดณเต เด เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจ เดเดฐเต dnode เดธเตเดทเตโเดเดฟเดเตเดเดพเตป เดจเดฎเตเดเตเดเต เดเดฐเต เดเตเดฑเดฟเดฏ เดธเดนเดพเดฏเดฟ เดเดดเตเดคเดพเด.
API เดเดฌเตโเดเดเตโเดฑเตเดฑเตเดเตพ เดเดชเตเดชเตเตพ เดเดคเตเดชเตเดฒเต เดเดพเดฃเดชเตเดชเตเดเตเด:
export class SignerApp {
popupApi() {
return {
hello: async () => "world"
}
}
...
}
เดเดคเตเดชเตเดฒเตเดฏเตเดณเตเดณ เดฑเดฟเดฎเตเดเตเดเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดฐเต เดเดฌเตเดเดเตเดฑเตเดฑเต เดฒเดญเดฟเดเตเดเตเดจเตเดจเดคเต:
import {cbToPromise, transformMethods} from "../../src/utils/setupDnode";
const pageApi = await new Promise(resolve => {
dnode.once('remote', remoteApi => {
// ะก ะฟะพะผะพััั ััะธะปะธั ะผะตะฝัะตะผ ะฒัะต callback ะฝะฐ promise
resolve(transformMethods(cbToPromise, remoteApi))
})
});
เดเตเตพ เดซเดเดเตโเดทเดจเตเดเตพ เดเดฐเต เดตเดพเดเตเดฆเดพเดจเด เดจเตฝเดเตเดจเตเดจเต:
เด
เดธเดฟเตปเดเตเดฐเดฃเดธเต เดซเดเดเตโเดทเดจเตเดเดณเตเดณเตเดณ เดชเดคเดฟเดชเตเดชเต เดฒเดญเตเดฏเดฎเดพเดฃเต
เดฎเตเดคเตเดคเดคเตเดคเดฟเตฝ, เดเตผโเดชเดฟโเดธเดฟเดฏเตเด เดธเตโเดเตเดฐเตเด เดธเดฎเตเดชเดจเดตเตเด เดคเดฟเดเดเตเดเตเด เด เดฏเดตเตเดณเตเดณเดคเดพเดฏเดฟ เดคเตเดจเตเดจเตเดจเตเดจเต: เดจเดฎเตเดเตเดเต เดธเตเดฑเตเดฑเตเด เดฎเตพเดเตเดเดฟเดชเตเดฒเดเตโเดธเดฟเดเดเต เดเดชเดฏเตเดเดฟเดเตเดเดพเดจเตเด เดตเตเดฏเดคเตเดฏเดธเตเดค เดเตเดฒเดฟเดเตพเดเตเดเดพเดฏเดฟ เดจเดฟเดฐเดตเดงเดฟ เดตเตเดฏเดคเตเดฏเดธเตเดค เดเดชเดฟเดเดเตพ เดธเตเดทเตโเดเดฟเดเตเดเดพเดจเตเด เดเดดเดฟเดฏเตเด. เดคเดคเตเดตเดคเตเดคเดฟเตฝ, dnode เดเดตเดฟเดเตเดฏเตเด เดเดชเดฏเตเดเดฟเดเตเดเดพเด, เดชเตเดฐเดงเดพเดจ เดเดพเดฐเตเดฏเด เดเดฐเต nodejs เดธเตเดเตเดฐเตเด เดฐเตเดชเดคเตเดคเดฟเตฝ เดเดคเดพเดเดคเด เดชเตเดคเดฟเดฏเตเด เดเดจเตเดจเดคเดพเดฃเต.
เดเดฐเต เดฌเดฆเตฝ JSON เดซเตเตผเดฎเดพเดฑเตเดฑเดพเดฃเต, เด เดคเต JSON RPC 2 เดชเตเดฐเตเดเตเดเตเดเตเดเตเตพ เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเตเดจเตเดจเต. เดเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด, เดเดคเต เดจเดฟเตผเดฆเตเดฆเดฟเดทเตเด เดเตเดฐเดพเตปเดธเตเดชเตเตผเดเตเดเตเดเดณเดฟเตฝ (TCP, HTTP(S)) เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเต, เดเดคเต เดเดเตเดเดณเตเดเต เดเดพเดฐเตเดฏเดคเตเดคเดฟเตฝ เดฌเดพเดงเดเดฎเดฒเตเดฒ.
เดเดญเตเดฏเดจเตเดคเดฐ เดธเดเดธเตเดฅเดพเดจเดตเตเด เดชเตเดฐเดพเดฆเตเดถเดฟเด เดธเดเดญเดฐเดฃเดตเตเด
เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดฑเต เดเดจเตเดคเดฐเดฟเด เดจเดฟเดฒ - เดเตเดฑเดเตเดเดคเต เดธเตเดจเดฟเดเดเต เดเตเดเดณเตเดเตเดเดฟเดฒเตเด เดเดเตเดเตพ เดธเดเดญเดฐเดฟเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต. เดชเตเดชเตเดชเตเด เดชเตเดชเต API-เดฏเดฟเตฝ เดจเดฎเตเดเตเดเต เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเดฟเดฒเตเดเตเดเต เดเดฐเต เด เดตเดธเตเดฅเดฏเตเด เด เดคเต เดฎเดพเดฑเตเดฑเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดฐเตเดคเดฟเดเดณเตเด เดตเดณเดฐเต เดเดณเตเดชเตเดชเดคเตเดคเดฟเตฝ เดเตเตผเดเตเดเดพเตป เดเดดเดฟเดฏเตเด:
import {setupDnode} from "./utils/setupDnode";
export class SignerApp {
constructor(){
this.store = {
keys: [],
};
}
addKey(key){
this.store.keys.push(key)
}
removeKey(index){
this.store.keys.splice(index,1)
}
popupApi(){
return {
addKey: async (key) => this.addKey(key),
removeKey: async (index) => this.removeKey(index)
}
}
...
}
เดชเดถเตเดเดพเดคเตเดคเดฒเดคเตเดคเดฟเตฝ, เดเดเตเดเตพ เดเดฒเตเดฒเดพเด เดเดฐเต เดซเดเดเตโเดทเดจเดฟเตฝ เดชเตเดคเดฟเดเตเดเต เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดฌเตโเดเดเตเดฑเตเดฑเต เดตเดฟเตปเดกเตเดฏเดฟเดฒเตเดเตเดเต เดเดดเตเดคเตเด, เด เดคเตเดตเดดเดฟ เดเดเตเดเตพเดเตเดเต เดเตบเดธเตเดณเดฟเตฝ เดจเดฟเดจเตเดจเต เด เดคเต เดเดชเดฏเตเดเดฟเดเตเดเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเดพเดจเดพเดเตเด:
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import {SignerApp} from "./SignerApp";
const DEV_MODE = process.env.NODE_ENV !== 'production';
setupApp();
function setupApp() {
const app = new SignerApp();
if (DEV_MODE) {
global.app = app;
}
extensionApi.runtime.onConnect.addListener(connectRemote);
function connectRemote(remotePort) {
const processName = remotePort.name;
const portStream = new PortStream(remotePort);
if (processName === 'contentscript') {
const origin = remotePort.sender.url;
app.connectPage(portStream, origin)
} else {
app.connectPopup(portStream)
}
}
}
เดฏเตเด เดเตบเดธเตเดณเดฟเตฝ เดจเดฟเดจเตเดจเต เดเตเดฑเดเตเดเต เดเตเดเตพ เดเตเตผเดคเตเดคเต เดธเตเดฑเตเดฑเตเดฑเตเดฑเดฟเตฝ เดเดจเตเดคเดพเดฃเต เดธเดเดญเดตเดฟเดเตเดเตเดจเตเดจเดคเตเดจเตเดจเต เดจเตเดเตเดเดพเด:
เดชเตเดจเดฐเดพเดฐเดเดญเดฟเดเตเดเตเดฎเตเดชเตเตพ เดเตเดเตพ เดจเดทเตโเดเดชเตเดชเตเดเดพเดคเดฟเดฐเดฟเดเตเดเดพเตป เดธเดเดธเตเดฅเดพเดจเด เดธเตเดฅเดฟเดฐเดค เดชเตเดฒเตผเดคเตเดคเตเดฃเตเดเดคเตเดฃเตเดเต.
เดเดเตเดเตพ เดเดคเต เดฒเตเดเตเดเตฝ เดธเตเดฑเตเดฑเตเดฑเตเดเดฟเตฝ เดธเดเดญเดฐเดฟเดเตเดเตเด, เดเดฐเต เดฎเดพเดฑเตเดฑเดคเตเดคเดฟเดฒเตเด เด เดคเต เดคเดฟเดฐเตเดคเตเดคเดฟเดฏเตเดดเตเดคเตเด. เดคเตเดเตผเดจเตเดจเต, เด เดคเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดเตโเดธเดธเต เดฏเตเดเดฏเตโเดเตเดเตเด เดเดตเดถเตเดฏเดฎเดพเดฏเดฟ เดตเดฐเตเด, เดเตเดเดพเดคเต เดฎเดพเดฑเตเดฑเดเตเดเตพ เดธเดฌเตโเดธเตโเดเตเดฐเตเดฌเต เดเตเดฏเตเดฏเดพเดจเตเด เดเดพเตป เดเดเตเดฐเดนเดฟเดเตเดเตเดจเตเดจเต. เดเดคเดฟเดจเต เด เดเดฟเดธเตเดฅเดพเดจเดฎเดพเดเตเดเดฟ, เดจเดฟเดฐเตเดเตเดทเดฟเดเตเดเดพเดตเตเดจเตเดจ เดเดฐเต เดธเดเดญเดฐเดฃเด เดธเตเดทเตเดเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเตเด เด เดคเดฟเดจเตเดฑเต เดฎเดพเดฑเตเดฑเดเตเดเตพ เดธเดฌเตโเดธเตโเดเตเดฐเตเดฌเตเดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเด เดเดคเต เดธเตเดเดฐเตเดฏเดชเตเดฐเดฆเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเด.
เดเดเตเดเตพ mobx เดฒเตเดฌเตเดฐเดฑเดฟ เดเดชเดฏเตเดเดฟเดเตเดเตเด (
เดจเดฎเตเดเตเดเต เดชเตเดฐเดพเดฐเดเดญ เดจเดฟเดฒเดฏเตเดเต เดธเดฎเดพเดฐเดเดญเด เดเตเตผเดคเตเดคเต เดธเตเดฑเตเดฑเตเตผ เดจเดฟเดฐเตเดเตเดทเดฟเดเตเดเดพเดตเตเดจเตเดจเดคเดพเดเตเดเดพเด:
import {observable, action} from 'mobx';
import {setupDnode} from "./utils/setupDnode";
export class SignerApp {
constructor(initState = {}) {
// ะะฝะตัะฝะต store ัะฐะบ ะธ ะพััะฐะฝะตััั ัะตะผ ะถะต ะพะฑัะตะบัะพะผ, ัะพะปัะบะพ ัะตะฟะตัั ะฒัะต ะตะณะพ ะฟะพะปั ััะฐะปะธ proxy, ะบะพัะพััะต ะพััะปะตะถะธะฒะฐัั ะดะพัััะฟ ะบ ะฝะธะผ
this.store = observable.object({
keys: initState.keys || [],
});
}
// ะะตัะพะดั, ะบะพัะพััะต ะผะตะฝััั observable ะฟัะธะฝััะพ ะพะฑะพัะฐัะธะฒะฐัั ะดะตะบะพัะฐัะพัะพะผ
@action
addKey(key) {
this.store.keys.push(key)
}
@action
removeKey(index) {
this.store.keys.splice(index, 1)
}
...
}
"เด เดฃเตเดเตผ เดฆเดฟ เดนเตเดกเต," mobx เดเดฒเตเดฒเดพ เดธเตเดฑเตเดฑเตเตผ เดซเตเตฝเดกเตเดเดณเตเด เดชเตเดฐเตเดเตเดธเดฟ เดเดชเดฏเตเดเดฟเดเตเดเต เดฎเดพเดฑเตเดฑเดฟ เด เดตเดฏเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดฒเตเดฒเดพ เดเตเดณเตเดเดณเตเด เดคเดเดธเตเดธเดชเตเดชเตเดเตเดคเตเดคเตเดจเตเดจเต. เด เดธเดจเตเดฆเตเดถเดเตเดเตพ เดธเดฌเตโเดธเตโเดเตเดฐเตเดฌเต เดเตเดฏเตเดฏเดพเตป เดธเดพเดงเดฟเดเตเดเตเด.
เดเตเดตเดเต เดเดพเตป เดชเดฒเดชเตเดชเตเดดเตเด "เดฎเดพเดฑเตเดฑเตเดฎเตเดชเตเตพ" เดเดจเตเดจ เดชเดฆเด เดเดชเดฏเตเดเดฟเดเตเดเตเด, เดเดคเต เดชเตเตผเดฃเตเดฃเดฎเดพเดฏเตเด เดถเดฐเดฟเดฏเดฒเตเดฒเตเดเตเดเดฟเดฒเตเด. Mobx เดซเตเตฝเดกเตเดเดณเดฟเดฒเตเดเตเดเตเดณเตเดณ เดเดเตเดธเดธเต เดเตเดฐเดพเดเตเดเต เดเตเดฏเตเดฏเตเดจเตเดจเต. เดฒเตเดฌเตเดฐเดฑเดฟ เดธเตเดทเตเดเดฟเดเตเดเตเดจเตเดจ เดชเตเดฐเตเดเตโเดธเดฟ เดเดฌเตโเดเดเตโเดฑเตเดฑเตเดเดณเตเดเต เดเตเดฑเตเดฑเดฑเตเดเดณเตเด เดธเตเดฑเตเดฑเดฑเตเดเดณเตเด เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต.
เดเดเตเดทเตป เดกเตเดเตเดเดฑเตเดฑเตเดฑเตผเดฎเดพเตผ เดฐเดฃเตเดเต เดเดฆเตเดฆเตเดถเตเดฏเดเตเดเตพ เดจเดฟเดฑเดตเตเดฑเตเดฑเตเดจเตเดจเต:
- เดเตปเดซเตเดดเตโเดธเต เดเดเตเดทเตปเดธเต เดซเตเดฒเดพเดเต เดเดณเตเดณ เดเตผเดถเดจเดฎเดพเดฏ เดฎเตเดกเดฟเตฝ, เดธเดเดธเตเดฅเดพเดจเด เดจเตเดฐเดฟเดเตเดเต เดฎเดพเดฑเตเดฑเตเดจเตเดจเดคเต mobx เดจเดฟเดฐเตเดงเดฟเดเตเดเตเดจเตเดจเต. เดเตผเดถเดจเดฎเดพเดฏ เดตเตเดฏเดตเดธเตเดฅเดเดณเดฟเตฝ เดเตเดฒเดฟ เดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดจเดฒเตเดฒ เดถเตเดฒเดฎเดพเดฏเดฟ เดเดฃเดเตเดเดพเดเตเดเดชเตเดชเตเดเตเดจเตเดจเต.
- เดเดฐเต เดซเดเดเตโเดทเตป เด เดตเดธเตเดฅเดฏเต เดชเดฒเดคเดตเดฃ เดฎเดพเดฑเตเดฑเดฟเดฏเดพเดฒเตเด - เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดเตเดกเดฟเดจเตเดฑเต เดจเดฟเดฐเดตเดงเดฟ เดตเดฐเดฟเดเดณเดฟเตฝ เดเดเตเดเตพ เดจเดฟเดฐเดตเดงเดฟ เดซเตเตฝเดกเตเดเตพ เดฎเดพเดฑเตเดฑเตเดจเตเดจเต - เด เดคเต เดชเตเตผเดคเตเดคเดฟเดฏเดพเดเตเดฎเตเดชเตเตพ เดฎเดพเดคเตเดฐเดฎเต เดจเดฟเดฐเตเดเตเดทเดเดฐเต เด เดฑเดฟเดฏเดฟเดเตเดเต. เดซเตเดฐเดฃเตเดเตโเดเตปเดกเดฟเดจเต เดเดคเต เดตเดณเดฐเต เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต, เด เดตเดฟเดเต เด เดจเดพเดตเดถเตเดฏเดฎเดพเดฏ เดธเตเดฑเตเดฑเตเดฑเตเดฑเต เด เดชเตโเดกเตเดฑเตเดฑเตเดเตพ เดฎเตเดฒเดเดเตเดเดณเตเดเต เด เดจเดพเดตเดถเตเดฏเดฎเดพเดฏ เดฑเตเตปเดกเดฑเดฟเดเดเดฟเดฒเตเดเตเดเต เดจเดฏเดฟเดเตเดเตเดจเตเดจเต. เดเดเตเดเดณเตเดเต เดเดพเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดเดฆเตเดฏเดคเตเดคเตเดคเต เดฐเดฃเตเดเดพเดฎเดคเตเดคเตเดคเต เดชเตเดฐเดคเตเดฏเตเดเดฟเดเตเดเต เดชเตเดฐเดธเดเตเดคเดฎเดฒเตเดฒ, เดเดจเตเดจเดพเตฝ เดเดเตเดเตพ เดฎเดฟเดเดเตเด เดฐเตเดคเดฟเดเตพ เดชเดฟเดจเตเดคเตเดเดฐเตเด. เดจเดฟเดฐเตเดเตเดทเดฟเดเตเด เดซเตเตฝเดกเตเดเดณเตเดเต เด เดตเดธเตเดฅเดฏเต เดฎเดพเดฑเตเดฑเตเดจเตเดจ เดเดฒเตเดฒเดพ เดซเดเดเตเดทเดจเตเดเดณเดฟเดฒเตเด เดกเตเดเตเดเดฑเตเดฑเตเดฑเดฑเตเดเตพ เด เดฑเตเดฑเดพเดเตเดเตเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดชเดคเดฟเดตเดพเดฃเต.
เดชเดถเตเดเดพเดคเตเดคเดฒเดคเตเดคเดฟเตฝ เดเดเตเดเตพ เดฒเตเดเตเดเตฝ เดธเตเดฑเตเดฑเตเดฑเตเดเดฟเตฝ เดธเดฎเดพเดฐเดเดญเดฟเดเตเดเตเดเดฏเตเด เดธเดเดธเตเดฅเดพเดจเด เดธเดเดฐเดเตเดทเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเด:
import {reaction, toJS} from 'mobx';
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import {SignerApp} from "./SignerApp";
// ะัะฟะพะผะพะณะฐัะตะปัะฝัะต ะผะตัะพะดั. ะะฐะฟะธััะฒะฐัั/ัะธัะฐัั ะพะฑัะตะบั ะฒ/ะธะท localStorage ะฒะธะดะต JSON ัััะพะบะธ ะฟะพ ะบะปััั 'store'
import {loadState, saveState} from "./utils/localStorage";
const DEV_MODE = process.env.NODE_ENV !== 'production';
setupApp();
function setupApp() {
const initState = loadState();
const app = new SignerApp(initState);
if (DEV_MODE) {
global.app = app;
}
// Setup state persistence
// ะ ะตะทัะปััะฐั reaction ะฟัะธัะฒะฐะธะฒะฐะตััั ะฟะตัะตะผะตะฝะฝะพะน, ััะพะฑั ะฟะพะดะฟะธัะบั ะผะพะถะฝะพ ะฑัะปะพ ะพัะผะตะฝะธัั. ะะฐะผ ััะพ ะฝะต ะฝัะถะฝะพ, ะพััะฐะฒะปะตะฝะพ ะดะปั ะฟัะธะผะตัะฐ
const localStorageReaction = reaction(
() => toJS(app.store), // ะคัะฝะบัะธั-ัะตะปะตะบัะพั ะดะฐะฝะฝัั
saveState // ะคัะฝะบัะธั, ะบะพัะพัะฐั ะฑัะดะตั ะฒัะทะฒะฐะฝะฐ ะฟัะธ ะธะทะผะตะฝะตะฝะธะธ ะดะฐะฝะฝัั
, ะบะพัะพััะต ะฒะพะทะฒัะฐัะฐะตั ัะตะปะตะบัะพั
);
extensionApi.runtime.onConnect.addListener(connectRemote);
function connectRemote(remotePort) {
const processName = remotePort.name;
const portStream = new PortStream(remotePort);
if (processName === 'contentscript') {
const origin = remotePort.sender.url
app.connectPage(portStream, origin)
} else {
app.connectPopup(portStream)
}
}
}
เดชเตเดฐเดคเดฟเดเดฐเดฃ เดชเตเดฐเดตเตผเดคเตเดคเดจเด เดเดตเดฟเดเต เดฐเดธเดเดฐเดฎเดพเดฃเต. เดเดคเดฟเดจเต เดฐเดฃเตเดเต เดตเดพเดฆเดเตเดเดณเตเดฃเตเดเต:
- เดกเดพเดฑเตเดฑ เดธเตเดฒเดเตเดเตผ.
- เด เดกเดพเดฑเตเดฑ เดฎเดพเดฑเตเดฎเตเดชเตเดดเตเดฒเตเดฒเดพเด เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเดเตเดจเตเดจ เดเดฐเต เดนเดพเตปเดกเตโเดฒเตผ.
redux-เตฝ เดจเดฟเดจเตเดจเต เดตเตเดฏเดคเตเดฏเดธเตเดคเดฎเดพเดฏเดฟ, เดเดฐเต เดเตผเดเตเดฏเตเดฎเตเดจเตเดฑเดพเดฏเดฟ เดจเดฎเตเดเตเดเต เดธเดเดธเตเดฅเดพเดจเด เดฒเดญเดฟเดเตเดเตเดจเตเดจเต, เดธเตเดฒเดเตเดเดฑเดฟเดจเตเดณเตเดณเดฟเตฝ เดจเดฎเตเดฎเตพ เดเดเตโเดธเดธเต เดเตเดฏเตเดฏเตเดจเตเดจ เดจเดฟเดฐเตเดเตเดทเดฃเดเตเดเตพ เดเดคเตเดเตเดเตเดฏเดพเดฃเตเดจเตเดจเต mobx เดเตผเดเตเดเตเดจเตเดจเต, เด เดต เดฎเดพเดฑเตเดฎเตเดชเตเตพ เดฎเดพเดคเตเดฐเดฎเต เดนเดพเตปเดกเตโเดฒเดฑเต เดตเดฟเดณเดฟเดเตเดเต.
เดเดคเต เดจเดฟเดฐเตเดเตเดทเดฃเดเตเดเดณเดพเดฃเต เดเดเตเดเตพ เดธเดฌเตโเดธเตโเดเตเดฐเตเดฌเตเดเตเดฏเตเดฏเตเดจเตเดจเดคเตเดจเตเดจเต mobx เดเตเดคเตเดฏเดฎเดพเดฏเดฟ เดเดเตเดเดจเต เดคเตเดฐเตเดฎเดพเดจเดฟเดเตเดเตเดจเตเดจเตเดตเตเดจเตเดจเต เดฎเดจเดธเตเดธเดฟเดฒเดพเดเตเดเตเดฃเตเดเดคเต เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต. เดเดพเตป เดเดคเตเดชเตเดฒเต เดเตเดกเดฟเตฝ เดเดฐเต เดธเตเดฒเดเตเดเตผ เดเดดเตเดคเดฟเดฏเดพเตฝ() => app.store
, เด
เดชเตเดชเตเตพ เดชเตเดฐเดคเดฟเดเดฐเดฃเด เดเดฐเดฟเดเตเดเดฒเตเด เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเดเดฟเดฒเตเดฒ, เดเดพเดฐเดฃเด เดธเดเดญเดฐเดฃเด เดคเดจเตเดจเต เดจเดฟเดฐเตเดเตเดทเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ, เด
เดคเดฟเดจเตเดฑเต เดซเตเตฝเดกเตเดเตพ เดฎเดพเดคเตเดฐเดฎเดพเดฃเต.
เดเดพเตป เดเดเตเดเดจเต เดเดดเตเดคเดฟเดฏเดพเตฝ () => app.store.keys
, เดชเดฟเดจเตเดจเตเดฏเตเด เดเดจเตเดจเตเด เดธเดเดญเดตเดฟเดเตเดเดฟเดฒเตเดฒ, เดเดพเดฐเดฃเด เด
เดฑเต เดเดเดเดเตเดเตพ เดเตเตผเดเตเดเตเดฎเตเดชเตเตพ/เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ, เด
เดคเดฟเดฒเตเดเตเดเตเดณเตเดณ เดฑเดซเดฑเตปเดธเต เดฎเดพเดฑเดฟเดฒเตเดฒ.
Mobx เดเดฆเตเดฏเดฎเดพเดฏเดฟ เดเดฐเต เดธเตเดฒเดเตเดเดฑเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเต, เดเดเตเดเตพ เดเดเตโเดธเดธเต เดเตเดฏเตโเดค เดจเดฟเดฐเตเดเตเดทเดฃเดเตเดเดณเตเดเต เดเตเดฐเดพเดเตเดเต เดฎเดพเดคเตเดฐเด เดธเตเดเตเดทเดฟเดเตเดเตเดจเตเดจเต. เดชเตเดฐเตเดเตเดธเดฟ เดเตเดฑเตเดฑเดฑเตเดเตพ เดตเดดเดฟเดฏเดพเดฃเต เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเต. เด
เดคเดฟเดจเดพเตฝ, เดฌเดฟเตฝเดฑเตเดฑเต-เดเตป เดซเดเดเตเดทเตป เดเดตเดฟเดเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต toJS
. เดเดคเต เดเดฑเดฟเดเดฟเดจเตฝ เดซเตเตฝเดกเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเต เดฎเดพเดฑเตเดฑเดฟ เดเดฒเตเดฒเดพ เดชเตเดฐเตเดเตเดธเดฟเดเดณเตเด เดเดณเตเดณ เดเดฐเต เดชเตเดคเดฟเดฏ เดเดฌเตเดเดเตเดฑเตเดฑเต เดจเตฝเดเตเดจเตเดจเต. เดเดเตเดธเดฟเดเตเดฏเตเดทเตป เดธเดฎเดฏเดคเตเดคเต, เด
เดคเต เดเดฌเตเดเดเตเดฑเตเดฑเดฟเดจเตเดฑเต เดเดฒเตเดฒเดพ เดซเตเตฝเดกเตเดเดณเตเด เดตเดพเดฏเดฟเดเตเดเตเดจเตเดจเต - เด
เดคเดฟเดจเดพเตฝ เดเตเดฑเตเดฑเดฑเตเดเตพ เดเตเดฐเดฟเดเตผ เดเตเดฏเตเดฏเดชเตเดชเตเดเตเดจเตเดจเต.
เดชเตเดชเตเดชเตเด เดชเตเดชเต เดเตบเดธเตเดณเดฟเตฝ เดเดเตเดเตพ เดตเตเดฃเตเดเตเด เดจเดฟเดฐเดตเดงเดฟ เดเตเดเตพ เดเตเตผเดเตเดเตเด. เดเดคเตเดคเดตเดฃ เด เดตเตผ เดฒเตเดเตเดเตฝ เดธเตเดฑเตเดฑเตเดฑเตเดเดฟเดฒเตเด เดเดคเตเดคเดฟ:
เดชเดถเตเดเดพเดคเตเดคเดฒ เดชเตเดเต เดตเตเดฃเตเดเตเด เดฒเตเดกเตเดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ, เดตเดฟเดตเดฐเดเตเดเตพ เด เดคเตเดชเดเดฟ เดจเดฟเดฒเดจเดฟเตฝเดเตเดเตเด.
เดเดคเต เดตเดฐเตเดฏเตเดณเตเดณ เดเดฒเตเดฒเดพ เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเตเดกเตเดเดณเตเด เดเดพเดฃเดพเตป เดเดดเดฟเดฏเตเด
เดธเตเดตเดเดพเดฐเตเดฏ เดเตเดเดณเตเดเต เดธเตเดฐเดเตเดทเดฟเดค เดธเดเดญเดฐเดฃเด
เดตเตเดฏเดเตเดคเดฎเดพเดฏ เดเตเดเตโเดธเตโเดฑเตเดฑเดฟเตฝ เดธเตเดตเดเดพเดฐเตเดฏ เดเตเดเตพ เดธเตเดเตเดทเดฟเดเตเดเตเดจเตเดจเดคเต เดธเตเดฐเดเตเดทเดฟเดคเดฎเดฒเตเดฒ: เดจเดฟเดเตเดเตพ เดนเดพเดเตเดเต เดเตเดฏเตเดฏเดชเตเดชเตเดเดพเดจเตเด เดจเดฟเดเตเดเดณเตเดเต เดเดฎเตเดชเตเดฏเตเดเตเดเดฑเดฟเดฒเตเดเตเดเต เดเดเตโเดธเดธเต เดจเตเดเดพเดจเตเด เดฎเดฑเตเดฑเตเด เดเดฒเตเดฒเดพเดฏเตโเดชเตเดชเตเดดเตเด เดเดฐเต เด เดตเดธเดฐเดฎเตเดฃเตเดเต. เด เดคเดฟเดจเดพเตฝ, เดฒเตเดเตเดเตฝ เดธเตเดฑเตเดฑเตเดฑเตเดเดฟเตฝ เดเดเตเดเตพ เดเตเดเตพ เดชเดพเดธเตโเดตเตเดกเต-เดเตปเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดเตเดฏเตเดค เดฐเตเดชเดคเตเดคเดฟเตฝ เดธเดเดญเดฐเดฟเดเตเดเตเด.
เดเตเดเตเดคเตฝ เดธเตเดฐเดเตเดทเดฏเตโเดเตเดเดพเดฏเดฟ, เดเดเตเดเตพ เด เดชเตเดฒเดฟเดเตเดเตเดทเดจเดฟเดฒเตเดเตเดเต เดเดฐเต เดฒเตเดเตเดเต เดเตเดฏเตโเดค เด เดตเดธเตเดฅ เดเตเตผเดเตเดเตเด, เด เดคเดฟเตฝ เดเตเดเดณเดฟเดฒเตเดเตเดเต เดเดเตโเดธเดธเต เดเดฃเตเดเดพเดเดฟเดฒเตเดฒ. เดเดพเดฒเดนเดฐเดฃเดชเตเดชเตเดเตเดเดคเดฟเดจเดพเตฝ เดเดเตเดเตพ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเด เดธเตเดตเดฏเดฎเตเดต เดฒเตเดเตเดเต เดเตเดฏเตเดค เดจเดฟเดฒเดฏเดฟเดฒเตเดเตเดเต เดฎเดพเดฑเตเดฑเตเด.
เดเดฑเตเดฑเดตเตเด เดเตเดฑเดเตเด เดกเดพเดฑเตเดฑ เดฎเดพเดคเตเดฐเด เดธเดเดญเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต Mobx เดจเดฟเดเตเดเดณเต เด เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต, เดฌเดพเดเตเดเดฟเดฏเตเดณเตเดณเดต เด เดคเดฟเดจเตเดฑเต เด เดเดฟเดธเตเดฅเดพเดจเดคเตเดคเดฟเตฝ เดฏเดพเดจเตเดคเตเดฐเดฟเดเดฎเดพเดฏเดฟ เดเดฃเดเตเดเดพเดเตเดเตเดจเตเดจเต. เดเดตเดฏเดพเดฃเต เดเดฎเตเดชเตเดฏเตเดเตเดเต เดชเตเดฐเตเดชเตเดชเตผเดเตเดเดฟเดเตพ เดเดจเตเดจเต เดตเดฟเดณเดฟเดเตเดเดชเตเดชเตเดเตเดจเตเดจเดต. เดกเดพเดฑเตเดฑเดพเดฌเตเดธเตเดเดณเดฟเดฒเต เดเดพเดดเตเดเดเดณเตเดฎเดพเดฏเดฟ เด เดตเดฏเต เดคเดพเดฐเดคเดฎเตเดฏเด เดเตเดฏเตเดฏเดพเด:
import {observable, action} from 'mobx';
import {setupDnode} from "./utils/setupDnode";
// ะฃัะธะปะธัั ะดะปั ะฑะตะทะพะฟะฐัะฝะพะณะพ ัะธััะพะฒะฐะฝะธั ัััะพะบ. ะัะฟะพะปัะทััั crypto-js
import {encrypt, decrypt} from "./utils/cryptoUtils";
export class SignerApp {
constructor(initState = {}) {
this.store = observable.object({
// ะฅัะฐะฝะธะผ ะฟะฐัะพะปั ะธ ะทะฐัะธััะพะฒะฐะฝะฝัะต ะบะปััะธ. ะัะปะธ ะฟะฐัะพะปั null - ะฟัะธะปะพะถะตะฝะธะต locked
password: null,
vault: initState.vault,
// ะะตััะตัั ะดะปั ะฒััะธัะปะธะผัั
ะฟะพะปะตะน. ะะพะถะฝะพ ะฟัะพะฒะตััะธ ะฐะฝะฐะปะพะณะธั ั view ะฒ ะฑะด.
get locked(){
return this.password == null
},
get keys(){
return this.locked ?
undefined :
SignerApp._decryptVault(this.vault, this.password)
},
get initialized(){
return this.vault !== undefined
}
})
}
// ะะฝะธัะธะฐะปะธะทะฐัะธั ะฟัััะพะณะพ ั
ัะฐะฝะธะปะธัะฐ ะฝะพะฒัะผ ะฟะฐัะพะปะตะผ
@action
initVault(password){
this.store.vault = SignerApp._encryptVault([], password)
}
@action
lock() {
this.store.password = null
}
@action
unlock(password) {
this._checkPassword(password);
this.store.password = password
}
@action
addKey(key) {
this._checkLocked();
this.store.vault = SignerApp._encryptVault(this.store.keys.concat(key), this.store.password)
}
@action
removeKey(index) {
this._checkLocked();
this.store.vault = SignerApp._encryptVault([
...this.store.keys.slice(0, index),
...this.store.keys.slice(index + 1)
],
this.store.password
)
}
... // ะบะพะด ะฟะพะดะบะปััะตะฝะธั ะธ api
// private
_checkPassword(password) {
SignerApp._decryptVault(this.store.vault, password);
}
_checkLocked() {
if (this.store.locked){
throw new Error('App is locked')
}
}
// ะะตัะพะดั ะดะปั ัะธััะพะฒะบะธ/ะดะตัะธััะพะฒะบะธ ั
ัะฐะฝะธะปะธัะฐ
static _encryptVault(obj, pass){
const jsonString = JSON.stringify(obj)
return encrypt(jsonString, pass)
}
static _decryptVault(str, pass){
if (str === undefined){
throw new Error('Vault not initialized')
}
try {
const jsonString = decrypt(str, pass)
return JSON.parse(jsonString)
}catch (e) {
throw new Error('Wrong password')
}
}
}
เดเดชเตเดชเตเตพ เดเดเตเดเตพ เดเตปเดเตเดฐเดฟเดชเตเดฑเตเดฑเต เดเตเดฏเตเดค เดเตเดเดณเตเด เดชเดพเดธเตโเดตเตเดกเตเด เดฎเดพเดคเตเดฐเด เดธเดเดญเดฐเดฟเดเตเดเตเดจเตเดจเต. เดฌเดพเดเตเดเดฟ เดเดฒเตเดฒเดพเด เดเดฃเดเตเดเตเดเตเดเตเดเดฟ. เดธเดเดธเตเดฅเดพเดจเดคเตเดคเต เดจเดฟเดจเตเดจเต เดชเดพเดธเตโเดตเตเดกเต เดจเตเดเตเดเด เดเตเดฏเตเดคเตเดเตเดฃเตเดเต เดเดเตเดเตพ เดฒเตเดเตเดเต เดเตเดฏเตเดค เด เดตเดธเตเดฅเดฏเดฟเดฒเตเดเตเดเต เดเตเดฎเดพเดฑเตเดฑเด เดเตเดฏเตเดฏเตเดจเตเดจเต. เดชเดฌเตเดฒเดฟเดเต เดเดชเดฟเดเดฏเตเดเตเดเต เดเดชเตเดชเตเตพ เดธเตเดฑเตเดฑเตเดฑเตเดเต เดเดฐเดเดญเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดเดฐเต เดฐเตเดคเดฟเดฏเตเดฃเตเดเต.
เดเตปเดเตเดฐเดฟเดชเตเดทเตป เดตเตเดฃเตเดเดฟ เดเดดเตเดคเดฟเดฏเดคเต
import CryptoJS from 'crypto-js'
// ะัะฟะพะปัะทัะตััั ะดะปั ะพัะปะพะถะฝะตะฝะธั ะฟะพะดะฑะพัะฐ ะฟะฐัะพะปั ะฟะตัะตะฑะพัะพะผ. ะะฐ ะบะฐะถะดัะน ะฒะฐัะธะฐะฝั ะฟะฐัะพะปั ะทะปะพัะผััะปะตะฝะฝะธะบั ะฟัะธะดะตััั ัะดะตะปะฐัั 5000 ั
ะตัะตะน
function strengthenPassword(pass, rounds = 5000) {
while (rounds-- > 0){
pass = CryptoJS.SHA256(pass).toString()
}
return pass
}
export function encrypt(str, pass){
const strongPass = strengthenPassword(pass);
return CryptoJS.AES.encrypt(str, strongPass).toString()
}
export function decrypt(str, pass){
const strongPass = strengthenPassword(pass)
const decrypted = CryptoJS.AES.decrypt(str, strongPass);
return decrypted.toString(CryptoJS.enc.Utf8)
}
เดฌเตเดฐเตเดธเดฑเดฟเดจเต เดเดฐเต เดจเดฟเดทเตโเดเตเดฐเดฟเดฏ API เดเดฃเตเดเต, เด
เดคเดฟเดฒเตเดเต เดจเดฟเดเตเดเตพเดเตเดเต เดเดฐเต เดเดตเดจเตเดฑเดฟเดฒเตเดเตเดเต เดธเดฌเตโเดธเตโเดเตเดฐเตเดฌเตเดเตเดฏเตเดฏเดพเดจเดพเดเตเด - เด
เดตเดธเตเดฅ เดฎเดพเดฑเตเดฑเดเตเดเตพ. เดธเดเดธเตเดฅเดพเดจเด, เด
เดคเดจเตเดธเดฐเดฟเดเตเดเต, เดเดเดพเด idle
, active
ะธ locked
. เดจเดฟเดทเตโเดเตเดฐเดฟเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดจเดฟเดเตเดเตพเดเตเดเต เดธเดฎเดฏเดชเดฐเดฟเดงเดฟ เดธเดเตเดเตเดเดฐเดฟเดเตเดเดพเด, เดเตเดเดพเดคเต OS เดคเดจเตเดจเต เดฌเตเดฒเตเดเตเดเต เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ เดฒเตเดเตเดเต เดเตเดฏเตโเดคเดคเต เดธเดเตเดเตเดเดฐเดฟเดเตเดเตเด. เดฒเตเดเตเดเตฝ เดธเตเดฑเตเดฑเตเดฑเตเดเดฟเตฝ เดธเดเดฐเดเตเดทเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเดพเดฏเดฟ เดเดเตเดเตพ เดธเตเดฒเดเตเดเดฑเตเด เดฎเดพเดฑเตเดฑเตเด:
import {reaction, toJS} from 'mobx';
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import {SignerApp} from "./SignerApp";
import {loadState, saveState} from "./utils/localStorage";
const DEV_MODE = process.env.NODE_ENV !== 'production';
const IDLE_INTERVAL = 30;
setupApp();
function setupApp() {
const initState = loadState();
const app = new SignerApp(initState);
if (DEV_MODE) {
global.app = app;
}
// ะขะตะฟะตัั ะผั ัะฒะฝะพ ัะทัะฒะฐะตะผ ะฟะพะปะต, ะบะพัะพัะพะผั ะฑัะดะตั ะฟัะพะธัั
ะพะดะธัั ะดะพัััะฟ, reaction ะพััะฐะฑะพัะฐะตั ะฝะพัะผะฐะปัะฝะพ
reaction(
() => ({
vault: app.store.vault
}),
saveState
);
// ะขะฐะนะผะฐัั ะฑะตะทะดะตะนััะฒะธั, ะบะพะณะดะฐ ััะฐะฑะพัะฐะตั ัะพะฑััะธะต
extensionApi.idle.setDetectionInterval(IDLE_INTERVAL);
// ะัะปะธ ะฟะพะปัะทะพะฒะฐัะตะปั ะทะฐะปะพัะธะป ัะบัะฐะฝ ะธะปะธ ะฑะตะทะดะตะนััะฒะพะฒะฐะป ะฒ ัะตัะตะฝะธะต ัะบะฐะทะฐะฝะฝะพะณะพ ะธะฝัะตัะฒะฐะปะฐ ะปะพัะธะผ ะฟัะธะปะพะถะตะฝะธะต
extensionApi.idle.onStateChanged.addListener(state => {
if (['locked', 'idle'].indexOf(state) > -1) {
app.lock()
}
});
// Connect to other contexts
extensionApi.runtime.onConnect.addListener(connectRemote);
function connectRemote(remotePort) {
const processName = remotePort.name;
const portStream = new PortStream(remotePort);
if (processName === 'contentscript') {
const origin = remotePort.sender.url
app.connectPage(portStream, origin)
} else {
app.connectPopup(portStream)
}
}
}
เด เดเดเตเดเดคเตเดคเดฟเดจเต เดฎเตเดฎเตเดชเตเดณเตเดณ เดเตเดกเต เดเดคเดพเดฃเต
เดเดเดชเดพเดเตเดเตพ
เด
เดคเดฟเดจเดพเตฝ, เดเดเตเดเตพ เดเดฑเตเดฑเดตเตเด เดชเตเดฐเดงเดพเดจเดชเตเดชเตเดเตเด เดเดพเดฐเตเดฏเดคเตเดคเดฟเดฒเตเดเตเดเต เดตเดฐเตเดจเตเดจเต: เดฌเตเดฒเตเดเตเดเตเดเตเดฏเดฟเดจเดฟเตฝ เดเดเดชเดพเดเตเดเตพ เดธเตเดทเตเดเดฟเดเตเดเตเดเดฏเตเด เดเดชเตเดชเดฟเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต. เดเดเตเดเตพ WAVES เดฌเตเดฒเตเดเตเดเตเดเตเดฏเดฟเดจเตเด เดฒเตเดฌเตเดฐเดฑเดฟเดฏเตเด เดเดชเดฏเตเดเดฟเดเตเดเตเด
เดเดฆเตเดฏเด, เดเดชเตเดชเดฟเดเตเดฃเตเด เดธเดจเตเดฆเตเดถเดเตเดเดณเตเดเต เดเดฐเต เดจเดฟเดฐ เดธเดเดธเตเดฅเดพเดจเดคเตเดคเดฟเดฒเตเดเตเดเต เดเตเตผเดเตเดเดพเด, เดคเตเดเตผเดจเตเดจเต เดเดฐเต เดชเตเดคเดฟเดฏ เดธเดจเตเดฆเตเดถเด เดเตเตผเดเตเดเตเดจเตเดจเดคเดฟเดจเตเด เดเดชเตเดชเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเตเด เดจเดฟเดฐเดธเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเตเดฎเตเดณเตเดณ เดฐเตเดคเดฟเดเตพ เดเตเตผเดเตเดเตเด:
import {action, observable, reaction} from 'mobx';
import uuid from 'uuid/v4';
import {signTx} from '@waves/waves-transactions'
import {setupDnode} from "./utils/setupDnode";
import {decrypt, encrypt} from "./utils/cryptoUtils";
export class SignerApp {
...
@action
newMessage(data, origin) {
// ะะปั ะบะฐะถะดะพะณะพ ัะพะพะฑัะตะฝะธั ัะพะทะดะฐะตะผ ะผะตัะฐะดะฐะฝะฝัะต ั id, ััะฐัััะพะผ, ะฒััะตะผะตะฝะตะผ ัะพะทะดะฐะฝะธั ะธ ัะด.
const message = observable.object({
id: uuid(), // ะะดะตะฝัะธัะธะบะฐัะพั, ะธัะฟะพะปัะทััั uuid
origin, // Origin ะฑัะดะตะผ ะฒะฟะพัะปะตะดััะฒะธะธ ะฟะพะบะฐะทัะฒะฐัั ะฒ ะธะฝัะตััะตะนัะต
data, //
status: 'new', // ะกัะฐัััะพะฒ ะฑัะดะตั ัะตัััะต: new, signed, rejected ะธ failed
timestamp: Date.now()
});
console.log(`new message: ${JSON.stringify(message, null, 2)}`);
this.store.messages.push(message);
// ะะพะทะฒัะฐัะฐะตะผ ะฟัะพะผะธั ะฒะฝัััะธ ะบะพัะพัะพะณะพ mobx ะผะพะฝะธัะพัะธั ะธะทะผะตะฝะตะฝะธั ัะพะพะฑัะตะฝะธั. ะะฐะบ ัะพะปัะบะพ ััะฐััั ะฟะพะผะตะฝัะตััั ะผั ะทะฐัะตะทะพะปะฒะธะผ ะตะณะพ
return new Promise((resolve, reject) => {
reaction(
() => message.status, //ะัะดะตะผ ะพะฑัะตัะฒะธัั ััะฐััั ัะพะพะฑัะตะฝั
(status, reaction) => { // ะฒัะพัะพะน ะฐัะณัะผะตะฝั ััะพ ัััะปะบะฐ ะฝะฐ ัะฐะผ reaction, ััะพะฑั ะตะณะพ ะผะพะถะฝะพ ะฑัะปะพ ัะฝะธััะพะถัั ะฒะฝัััะธ ะฒัะทะพะฒะฐ
switch (status) {
case 'signed':
resolve(message.data);
break;
case 'rejected':
reject(new Error('User rejected message'));
break;
case 'failed':
reject(new Error(message.err.message));
break;
default:
return
}
reaction.dispose()
}
)
})
}
@action
approve(id, keyIndex = 0) {
const message = this.store.messages.find(msg => msg.id === id);
if (message == null) throw new Error(`No msg with id:${id}`);
try {
message.data = signTx(message.data, this.store.keys[keyIndex]);
message.status = 'signed'
} catch (e) {
message.err = {
stack: e.stack,
message: e.message
};
message.status = 'failed'
throw e
}
}
@action
reject(id) {
const message = this.store.messages.find(msg => msg.id === id);
if (message == null) throw new Error(`No msg with id:${id}`);
message.status = 'rejected'
}
...
}
เดเดเตเดเตพเดเตเดเต เดเดฐเต เดชเตเดคเดฟเดฏ เดธเดจเตเดฆเตเดถเด เดฒเดญเดฟเดเตเดเตเดฎเตเดชเตเตพ, เดเดเตเดเตพ เด
เดคเดฟเตฝ เดฎเตเดฑเตเดฑเดพเดกเดพเดฑเตเดฑ เดเตเตผเดเตเดเตเดจเตเดจเต, เดเตเดฏเตเดฏเตเด observable
เดเดชเตเดชเด เดเตเตผเดเตเดเตเด store.messages
.
เดเดฒเตเดฒเตเดเตเดเดฟเตฝ observable
เดธเตเดตเดฎเตเดงเดฏเดพ, เด
เดฑเตเดฏเดฟเดฒเตเดเตเดเต เดธเดจเตเดฆเตเดถเดเตเดเตพ เดเตเตผเดเตเดเตเดฎเตเดชเตเตพ mobx เด
เดคเต เดธเตเดตเดฏเด เดเตเดฏเตเดฏเตเด. เดเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด, เดเดคเต เดเดฐเต เดชเตเดคเดฟเดฏ เดเดฌเตโเดเดเตโเดฑเตเดฑเต เดธเตเดทเตโเดเดฟเดเตเดเตเด, เด
เดคเดฟเตฝ เดเดเตเดเตพเดเตเดเต เดเดฐเต เดฑเดซเดฑเตปเดธเต เดเดฒเตเดฒ, เดชเดเตเดทเต เด
เดเตเดคเตเดค เดเดเตเดเดคเตเดคเดฟเดจเดพเดฏเดฟ เดเดเตเดเตพเดเตเดเต เด
เดคเต เดเดตเดถเตเดฏเดฎเดพเดฃเต.
เด เดเตเดคเตเดคเดคเดพเดฏเดฟ, เดธเดจเตเดฆเตเดถ เดจเดฟเดฒ เดฎเดพเดฑเตเดฎเตเดชเตเตพ เดชเดฐเดฟเดนเดฐเดฟเดเตเดเตเดจเตเดจ เดเดฐเต เดตเดพเดเตเดฆเดพเดจเด เดเดเตเดเตพ เดจเตฝเดเตเดจเตเดจเต. เดชเตเดฐเดคเดฟเดเดฐเดฃเดคเตเดคเดฟเดฒเตเดเต เดธเตเดฑเตเดฑเดพเดฑเตเดฑเดธเต เดจเดฟเดฐเตเดเตเดทเดฟเดเตเดเดชเตเดชเตเดเตเดจเตเดจเต, เด เดคเต เดธเตเดฑเตเดฑเดพเดฑเตเดฑเดธเต เดฎเดพเดฑเตเดฎเตเดชเตเตพ "เดธเตเดตเดฏเด เดเตเดฒเตเดฒเตเด".
เดฐเตเดคเดฟ เดเตเดกเต approve
ะธ reject
เดตเดณเดฐเต เดฒเดณเดฟเดคเดฎเดพเดฃเต: เดเดตเดถเตเดฏเดฎเตเดเตเดเดฟเตฝ เดเดชเตเดชเดฟเดเตเดเดคเดฟเดจเตเดถเตเดทเด เดเดเตเดเตพ เดธเดจเตเดฆเตเดถเดคเตเดคเดฟเดจเตเดฑเต เดธเตเดฑเตเดฑเดพเดฑเตเดฑเดธเต เดฎเดพเดฑเตเดฑเตเดจเตเดจเต.
UI API-เตฝ เดเดเตเดเตพ เด เดเดเตเดเดฐเดฟเดเตเดเตเดเดฏเตเด เดจเดฟเดฐเดธเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดจเตเดจเต, เดชเตเดเต API-เดฏเดฟเตฝ newMessage:
export class SignerApp {
...
popupApi() {
return {
addKey: async (key) => this.addKey(key),
removeKey: async (index) => this.removeKey(index),
lock: async () => this.lock(),
unlock: async (password) => this.unlock(password),
initVault: async (password) => this.initVault(password),
approve: async (id, keyIndex) => this.approve(id, keyIndex),
reject: async (id) => this.reject(id)
}
}
pageApi(origin) {
return {
signTransaction: async (txParams) => this.newMessage(txParams, origin)
}
}
...
}
เดเดชเตเดชเตเตพ เดเดเตเดธเตเดฑเตเดฑเตปเดทเตป เดเดชเดฏเตเดเดฟเดเตเดเต เดเดเดชเดพเดเต เดเดชเตเดชเดฟเดเดพเตป เดถเตเดฐเดฎเดฟเดเตเดเดพเด:
เดชเตเดคเตเดตเต, เดเดฒเตเดฒเดพเด เดคเดฏเตเดฏเดพเดฑเดพเดฃเต, เด
เดตเดถเตเดทเดฟเดเตเดเตเดจเตเดจเดคเต เดเดฒเตเดฒเดพเด
UI
เดเดจเตเดฑเตผเดซเตเดธเดฟเดจเต เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดจเดฟเดฒเดฏเดฟเดฒเตเดเตเดเต เดเดเตเดธเดธเต เดเดตเดถเตเดฏเดฎเดพเดฃเต. UI เดตเดถเดคเตเดคเต เดเดเตเดเตพ เดเตเดฏเตเดฏเตเด observable
เด เด
เดตเดธเตเดฅเดฏเต เดฎเดพเดฑเตเดฑเตเดจเตเดจ API-เดฏเดฟเดฒเตเดเตเดเต เดเดฐเต เดซเดเดเตเดทเตป เดชเตเดฐเดธเตเดคเดพเดตเดฟเดเตเดเตเดเดฏเตเด เดเตเตผเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเด. เดจเดฎเตเดเตเดเต เดเตเดเตเดเดฟเดเตเดเตเตผเดเตเดเดพเด observable
เดชเดถเตเดเดพเดคเตเดคเดฒเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เดฒเดญเดฟเดเตเด API เดเดฌเตเดเดเตเดฑเตเดฑเดฟเดฒเตเดเตเดเต:
import {observable} from 'mobx'
import {extensionApi} from "./utils/extensionApi";
import {PortStream} from "./utils/PortStream";
import {cbToPromise, setupDnode, transformMethods} from "./utils/setupDnode";
import {initApp} from "./ui/index";
const DEV_MODE = process.env.NODE_ENV !== 'production';
setupUi().catch(console.error);
async function setupUi() {
// ะะพะดะบะปััะฐะตะผัั ะบ ะฟะพััั, ัะพะทะดะฐะตะผ ะธะท ะฝะตะณะพ ัััะธะผ
const backgroundPort = extensionApi.runtime.connect({name: 'popup'});
const connectionStream = new PortStream(backgroundPort);
// ะกะพะทะดะฐะตะผ ะฟัััะพะน observable ะดะปั ัะพััะพัะฝะธั background'a
let backgroundState = observable.object({});
const api = {
//ะัะดะฐะตะผ ะฑะตะบะณัะฐัะฝะดั ััะฝะบัะธั, ะบะพัะพัะฐั ะฑัะดะตั ะพะฑะฝะพะฒะปััั observable
updateState: async state => {
Object.assign(backgroundState, state)
}
};
// ะะตะปะฐะตะผ RPC ะพะฑัะตะบั
const dnode = setupDnode(connectionStream, api);
const background = await new Promise(resolve => {
dnode.once('remote', remoteApi => {
resolve(transformMethods(cbToPromise, remoteApi))
})
});
// ะะพะฑะฐะฒะปัะตะผ ะฒ background observable ัะพ ััะตะนัะพะผ
background.state = backgroundState;
if (DEV_MODE) {
global.background = background;
}
// ะะฐะฟััะบ ะธะฝัะตััะตะนัะฐ
await initApp(background)
}
เด เดตเดธเดพเดจเด เดเดเตเดเตพ เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดจเตเดฑเตผเดซเตเดธเต เดฑเตเตปเดกเตผ เดเตเดฏเตเดฏเดพเตป เดคเตเดเดเตเดเตเดจเตเดจเต. เดเดคเตเดฐเต เดฑเดฟเดฏเดพเดเตเดเต เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเดพเดฃเต. เดชเดถเตเดเดพเดคเตเดคเดฒ เดเดฌเตโเดเดเตโเดฑเตเดฑเต เดชเตเดฐเตเดชเตเดชเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเต เดฒเดณเดฟเดคเดฎเดพเดฏเดฟ เดเดเดจเตเดจเตเดชเตเดเตเดจเตเดจเต. เดฐเตเดคเดฟเดเตพเดเตเดเดพเดฏเดฟ เดเดฐเต เดชเตเดฐเดคเตเดฏเตเด เดธเตเดตเดจเดตเตเด เดธเดเดธเตเดฅเดพเดจเดคเตเดคเดฟเดจเดพเดฏเดฟ เดเดฐเต เดธเตเดฑเตเดฑเตเดฑเตเด เดเดฃเตเดเดพเดเตเดเตเดจเตเดจเดคเต เดถเดฐเดฟเดฏเดพเดฃเต, เดเดจเตเดจเดพเตฝ เด เดฒเตเดเดจเดคเตเดคเดฟเดจเตเดฑเต เดเดตเดถเตเดฏเดเตเดเตพเดเตเดเต เดเดคเต เดฎเดคเดฟเดฏเดพเดเตเด:
import {render} from 'react-dom'
import App from './App'
import React from "react";
// ะะฝะธัะธะฐะปะธะทะธััะตะผ ะฟัะธะปะพะถะตะฝะธะต ั background ะพะฑัะตะบัะพะผ ะฒ ะบะฐัะตัั ะฒะต props
export async function initApp(background){
render(
<App background={background}/>,
document.getElementById('app-content')
);
}
เดกเดพเดฑเตเดฑ เดฎเดพเดฑเตเดฎเตเดชเตเตพ เดฑเตเตปเดกเดฑเดฟเดเดเต เดเดฐเดเดญเดฟเดเตเดเตเดจเตเดจเดคเต mobx เดเดชเดฏเตเดเดฟเดเตเดเต เดตเดณเดฐเต เดเดณเตเดชเตเดชเดฎเดพเดฃเต. เดชเดพเดเตเดเตเดเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดฌเตเดธเตผเดตเตผ เดกเตเดเตเดเดฑเตเดฑเตเดฑเตผ เดเดเตเดเตพ เดคเตเดเตเดเดฟเดฏเดฟเดเตเด
import React, {Component, Fragment} from 'react'
import {observer} from "mobx-react";
import Init from './components/Initialize'
import Keys from './components/Keys'
import Sign from './components/Sign'
import Unlock from './components/Unlock'
@observer // ะฃ ะะพะผะฟะพะฝะตัะฐ ั ััะธะผ ะดะตะบะพัะฐัะพะผ ะฑัะดะตั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฒัะทะฒะฐะฝ ะผะตัะพะด render, ะตัะปะธ ะฑัะดัั ะธะทะผะตะฝะตะฝั observable ะฝะฐ ะบะพัะพััะต ะพะฝ ัััะปะฐะตััั
export default class App extends Component {
// ะัะฐะฒะธะปัะฝะพ ะบะพะฝะตัะฝะพ ะฒัะฝะตััะธ ะปะพะณะธะบั ัะตะฝะดะตัะฐ ัััะฐะฝะธั ะฒ ัะพััะธะฝะณ ะธ ะฝะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะปะพะถะตะฝะฝัะต ัะตัะฝะฐัะฝัะต ะพะฟะตัะฐัะพัั,
// ะธ ะฟัะธะฒัะทัะฒะฐัั observable ะธ ะผะตัะพะดั background ะฝะตะฟะพััะตะดััะฒะตะฝะฝะพ ะบ ัะตะผ ะบะพะผะฟะพะฝะตะฝัะฐะผ, ะบะพัะพััะต ะธั
ะธัะฟะพะปัะทััั
render() {
const {keys, messages, initialized, locked} = this.props.background.state;
const {lock, unlock, addKey, removeKey, initVault, deleteVault, approve, reject} = this.props.background;
return <Fragment>
{!initialized
?
<Init onInit={initVault}/>
:
locked
?
<Unlock onUnlock={unlock}/>
:
messages.length > 0
?
<Sign keys={keys} message={messages[messages.length - 1]} onApprove={approve} onReject={reject}/>
:
<Keys keys={keys} onAdd={addKey} onRemove={removeKey}/>
}
<div>
{!locked && <button onClick={() => lock()}>Lock App</button>}
{initialized && <button onClick={() => deleteVault()}>Delete all keys and init</button>}
</div>
</Fragment>
}
}
เดถเตเดทเดฟเดเตเดเตเดจเตเดจ เดเดเดเดเตเดเตพ เดเตเดกเดฟเตฝ เดเดพเดฃเดพเตป เดเดดเดฟเดฏเตเด
เดเดชเตเดชเตเตพ เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเตเดฒเดพเดธเดฟเตฝ เดจเดฟเดเตเดเตพ เดฏเตเดเดฏเตโเดเตเดเดพเดฏเดฟ เดเดฐเต เดธเตเดฑเตเดฑเตเดฑเตเดฑเต เดธเตเดฒเดเตเดเตผ เดเดฃเตเดเดพเดเตเดเตเดเดฏเตเด เด
เดคเต เดฎเดพเดฑเตเดฎเตเดชเตเตพ เดฏเตเดเดฏเต เด
เดฑเดฟเดฏเดฟเดเตเดเตเดเดฏเตเด เดตเตเดฃเด. เดเดคเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต, เดจเดฎเตเดเตเดเต เดเดฐเต เดฐเตเดคเดฟ เดเตเตผเดเตเดเดพเด getState
ะธ reaction
เดตเดฟเดณเดฟเดเตเดเตเดจเตเดจเต remote.updateState
:
import {action, observable, reaction} from 'mobx';
import uuid from 'uuid/v4';
import {signTx} from '@waves/waves-transactions'
import {setupDnode} from "./utils/setupDnode";
import {decrypt, encrypt} from "./utils/cryptoUtils";
export class SignerApp {
...
// public
getState() {
return {
keys: this.store.keys,
messages: this.store.newMessages,
initialized: this.store.initialized,
locked: this.store.locked
}
}
...
//
connectPopup(connectionStream) {
const api = this.popupApi();
const dnode = setupDnode(connectionStream, api);
dnode.once('remote', (remote) => {
// ะกะพะทะดะฐะตะผ reaction ะฝะฐ ะธะทะผะตะฝะตะฝะธั ััะตะนัะฐ, ะบะพัะพััะน ัะดะตะปะฐะตั ะฒัะทะพะฒะตั ัะดะฐะปะตะฝะฝั ะฟัะพัะตะดััั ะธ ะพะฑะฝะพะฒะธั ััะตะนั ะฒ ui ะฟัะพัะตััะต
const updateStateReaction = reaction(
() => this.getState(),
(state) => remote.updateState(state),
// ะขัะตััะธะผ ะฐัะณัะผะตะฝัะพะผ ะผะพะถะฝะพ ะฟะตัะตะดะฐะฒะฐัั ะฟะฐัะฐะผะตััั. fireImmediatly ะทะฝะฐัะธั ััะพ reaction ะฒัะฟะพะปะฝะธัััั ะฟะตัะฒัะน ัะฐะท ััะฐะทั.
// ะญัะพ ะฝะตะพะฑั
ะพะดะธะผะพ, ััะพะฑั ะฟะพะปััะธัั ะฝะฐัะฐะปัะฝะพะต ัะพััะพัะฝะธะต. Delay ะฟะพะทะฒะพะปัะตั ัััะฐะฝะพะฒะธัั debounce
{fireImmediately: true, delay: 500}
);
// ะฃะดะฐะปะธะผ ะฟะพะดะฟะธัะบั ะฟัะธ ะพัะบะปััะตะฝะธะธ ะบะปะธะตะฝัะฐ
dnode.once('end', () => updateStateReaction.dispose())
})
}
...
}
เดเดฐเต เดตเดธเตเดคเต เดธเตเดตเตเดเดฐเดฟเดเตเดเตเดฎเตเดชเตเตพ remote
เดธเตเดทเตเดเดฟเดเตเดเต reaction
UI เดตเดถเดคเตเดคเตเดณเตเดณ เดซเดเดเตโเดทเดจเต เดตเดฟเดณเดฟเดเตเดเตเดจเตเดจ เด
เดตเดธเตเดฅ เดฎเดพเดฑเตเดฑเดพเตป.
เดตเดฟเดชเตเดฒเตเดเดฐเดฃ เดเดเตเดเดฃเดฟเตฝ เดชเตเดคเดฟเดฏ เดธเดจเตเดฆเตเดถเดเตเดเดณเตเดเต เดชเตเดฐเดฆเตผเดถเดจเด เดเตเตผเดเตเดเตเด เดเดจเตเดจเดคเดพเดฃเต เด เดตเดธเดพเดจ เดเดเตเดเต:
function setupApp() {
...
// Reaction ะฝะฐ ะฒัััะฐะฒะปะตะฝะธะต ัะตะบััะฐ ะฑะตะดะถะฐ.
reaction(
() => app.store.newMessages.length > 0 ? app.store.newMessages.length.toString() : '',
text => extensionApi.browserAction.setBadgeText({text}),
{fireImmediately: true}
);
...
}
เด เดคเดฟเดจเดพเตฝ, เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดคเดฏเตเดฏเดพเดฑเดพเดฃเต. เดเดเดชเดพเดเตเดเตพเดเตเดเดพเดฏเดฟ เดตเตเดฌเต เดชเตเดเตเดเตพ เดเดชเตเดชเต เด เดญเตเดฏเตผเดคเตเดฅเดฟเดเตเดเตเดเตเดเดพเด:
เดเตเดกเต เดเดตเดฟเดเต เดฒเดญเตเดฏเดฎเดพเดฃเต
เดคเตเดฐเตเดฎเดพเดจเด
เดจเดฟเดเตเดเตพ เดฒเตเดเดจเด เด
เดตเดธเดพเดจเด เดตเดฐเต เดตเดพเดฏเดฟเดเตเดเดฟเดเตเดเตเดฃเตเดเตเดเตเดเดฟเดฒเตเด เดเดชเตเดชเตเดดเตเด เดเตเดฆเตเดฏเดเตเดเดณเตเดฃเตเดเตเดเตเดเดฟเตฝ, เดจเดฟเดเตเดเตพเดเตเดเต เด
เดตเดฐเตเดเต เดเตเดฆเดฟเดเตเดเดพเด
เดฏเดฅเดพเตผเดคเตเดฅ เดตเดฟเดชเตเดฒเตเดเดฐเดฃเดคเตเดคเดฟเดจเดพเดฏเตเดณเตเดณ เดเตเดกเต เดจเตเดเตเดเดพเตป เดจเดฟเดเตเดเตพเดเตเดเต เดคเดพเตฝเดชเตเดชเดฐเตเดฏเดฎเตเดฃเตเดเตเดเตเดเดฟเตฝ, เดจเดฟเดเตเดเตพเดเตเดเต เดเดคเต เดเดฃเตเดเตเดคเตเดคเดพเดจเดพเดเตเด
เดเตเดกเต, เดถเตเดเดฐเด, เดเตเดฒเดฟ เดตเดฟเดตเดฐเดฃเด เดเดจเตเดจเดฟเดตเดฏเดฟเตฝ เดจเดฟเดจเตเดจเต
เด เดตเดฒเดเดฌเด: www.habr.com