एक Google Chrome एक्सटेंशन का इतिहास

एक अच्छा दिन, अपने काम के खत्म होने से कुछ घंटे पहले, मुझे यह काम मिलता है: “मुझे एक ब्राउज़र एप्लिकेशन लिखना होगा जो उपयोगकर्ता की क्लिक द्वारा एक पेज से क्लाइंट की साइट पर डेटा भेजना चाहिए। किस तरह का एप्लिकेशन और कौन सा ब्राउज़र पूरी तरह से आपके ऊपर है ... ”।

थोड़ा सोचा के साथ, मैं Google क्रोम एक्सटेंशन विकल्प के साथ आया:



जब मेरे विचार थोड़ा शांत हो गए, तो सबसे पहले मैंने Google Chrome एक्सटेंशन में harb की खोज में प्रवेश किया। इस विषय पर लेखों का एक व्यापक संस्करण देखकर, मैं मन की शांति के साथ घर गया, पूरी तरह से विश्वास है कि कल सुबह उन्हें पढ़ने के बाद, दिन के अंत तक यह " टोपी पहनना " होगा (तब मैं कितना गलत था)। उनमें से एक जोड़े को पढ़ने के बाद, मुझे इस बात का सामान्य विचार था कि यह कैसे काम करता है, लेकिन यह मेरे विचारों को लागू करने के लिए पर्याप्त नहीं था। खैर, चलिए शुरू करते हैं ...

Google क्रोम खोलें, क्रोम दर्ज करें : // एक्सटेंशन , डेवलपर मोड चेकबॉक्स की जांच करें, लोड अनपैक्ड एक्सटेंशन बटन पर क्लिक करें, फ़ोल्डर का चयन करें, ठीक क्लिक करें।



शुरुआत में यह शब्द प्रकट था। नीचे आप इस फ़ाइल की सामग्री देख सकते हैं (मैनिफ़ेस्ट। मेसन मेनिफ़ेस्ट फ़ाइल का आवश्यक नाम है)

manifest.json
{ "manifest_version": 2, "name": "My application", //     "version": "0.9", "icons": { "16": "./16x16.png", "32": "./32x32.png", "48": "./48x48.png", "128": "./128x128.png" }, "permissions": [ "tabs", "http://*/*", "https://*/*" ], "background" : { "page": "background.html" }, "content_scripts":[{ "matches": [ "http://*/*", "https://*/*" ], "js": [ "script_in_content.js" ] }], "browser_action": { "default_title": "Application", "default_icon" : "./16x16.png" // "default_popup": "login.html" //   html- ,       ,    JS   html  } } 


मैनिफ़ैस्ट_वर्जन - वर्तमान में 2 का मान आवश्यक है।
संस्करण - आपके एक्सटेंशन का संस्करण, केवल संख्याएँ और `.` हो सकता है (वे। '2.1.12', '0.59', आदि)
आइकन उन सभी चिह्नों की एक सूची है, जो ब्राउज़र में अलग-अलग स्थानों पर प्रदर्शित होंगे (पता बार में 16, सभी एक्सटेंशन की सूची में 48, आदि)
अनुमतियाँ - अनुमतियों के साथ एक सरणी यहाँ सूचीबद्ध है, मुझे केवल tabs.http की आवश्यकता है और किसी भी साइट के साथ ajax एक्सचेंज के लिए https की आवश्यकता है, और यह भी ताकि script_in_content.js पृष्ठभूमि पृष्ठ - background.html के साथ डेटा का आदान-प्रदान कर सके।
बैकग्राउंड बैकग्राउंड पेज का नाम है। पृष्ठभूमि पृष्ठ एक महत्वपूर्ण तत्व हैं, हालांकि कुछ अनुप्रयोगों के लिए यह आवश्यक नहीं है। थोड़ी देर बाद इसकी आवश्यकता क्यों है।
content_scripts - यह कहता है कि script_in_content.js फ़ाइल टैब में खोले गए पृष्ठ के लिए स्वचालित रूप से लोड की जाएगी। पृष्ठ उन साइटों से खुला होना चाहिए जो http: // * / * उन सभी साइटों में हैं जिनमें http, लेकिन https नहीं है, हालाँकि आप उन्हें निर्दिष्ट भी कर सकते हैं।
Browser_action - एक्सटेंशन आइकन प्रदर्शित करने के लिए 2 विकल्प हैं: browser_action और page_action

पेज_एक्शन कहता है कि एक्सटेंशन प्रत्येक टैब के लिए अलग-अलग है, अर्थात, पता बार में आइकन प्रदर्शित किया जाएगा। इस आइकन को जेएस के उपयोग से छिपाया / प्रदर्शित किया जा सकता है जैसा कि मामला हो सकता है।

browser_action, इसके विपरीत, व्यक्तिगत नहीं माना जाता है और पता बार में प्रदर्शित नहीं किया जाता है, लेकिन एक्सटेंशन के लिए पैनल में। यह आइकन जेएस पर छिपाया नहीं जा सकता (लेकिन अवरुद्ध किया जा सकता है), यह लगातार प्रदर्शित होता है। Browser_action का page_action पर एक लाभ है, browser_action आइकन के शीर्ष पर आप कुछ सुंदर अक्षर लिख सकते हैं (मैं केवल 4 वर्ष)।



मैंने Browser_action चुना, क्योंकि मुझे एक साइट के साथ नहीं, बल्कि कई के साथ काम करने की आवश्यकता है। और हाँ, आइकन के लिए सुंदर अक्षर लागू करना।
Google इस बारे में क्या कहता है:

सुविधाओं के लिए पृष्ठ क्रिया का उपयोग करें जो केवल कुछ पृष्ठों के लिए समझ में आता है
उन विशेषताओं के लिए पृष्ठ क्रियाओं का उपयोग न करें जो अधिकांश पृष्ठों के लिए समझ में आती हैं। इसके बजाय ब्राउज़र क्रियाओं का उपयोग करें।


और इसलिए, हमारा आवेदन क्या करेगा; मैं तुरंत ही कहूंगा, बाद में जो एप्लिकेशन वर्णित किया जाएगा वह क्लाइंट के लिए किया गया एक छोटा सा हिस्सा है। जब प्रबंधक अनुबंध / रिक्ति के बारे में जानकारी देखने के लिए hantim.ru साइट पर जाता है, तो एप्लिकेशन पृष्ठ के HTML कोड को पार्स करता है और जानकारी (रिक्ति, शहर, आदि) को ढूंढता है। जब आप एक्सटेंशन आइकन पर क्लिक करते हैं, तो एक लॉगिन फ़ॉर्म प्रदर्शित होता है जहां प्रबंधक अपने डेटा में प्रवेश करता है, और फिर कॉर्पोरेट वेबसाइट पर अपने प्रोफ़ाइल में चयनित रिक्ति / अनुबंध जोड़ सकता है।

अब यह कैसे काम करता है, इसके बारे में। Google हमें यह चित्र प्रदान करता है:


1) निरीक्षण विंडो वह है जिसे हमने टैब में खोला है, सामग्री स्क्रिप्ट हमारी script_in_content.js है, इसमें पृष्ठ के DOM तक पूर्ण पहुंच है।
2) बैकग्राउंड पेज एप्लिकेशन का दिल है, हमारे मामले में यह बैकग्राउंड.html है।
3) DevTools पेज - जब आप एक्सटेंशन आइकन (हमारे मामले में login.html या find.html) पर क्लिक करते हैं तो यह प्रदर्शित होता है।

केवल एक चीज जो मुझे इस तस्वीर में परेशान करती है, वह है DevTools पेज और इंस्पायर्ड विंडो के बीच का कनेक्शन। मुझे एक क्षेत्र से दूसरे क्षेत्र में डेटा स्थानांतरित करने का कोई समाधान नहीं मिला। लेकिन अगर आप एक मध्यस्थ के रूप में पृष्ठभूमि पृष्ठ को उजागर करते हैं, और इसके माध्यम से इस डेटा को स्थानांतरित करते हैं, तो सब कुछ काम करेगा।

और इसलिए, कोड का समय आ गया है। अदृश्य पक्ष से शुरू करते हैं।

background.html
 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="lib.js"></script> <script type="text/javascript" src="bg.js"></script> </head> <body></body> </html> 


उम्मीद है कि इससे सवाल नहीं उठने चाहिए। एक टिप्पणी: "background.html - यह ब्राउज़र के काम करने के दौरान पूरे समय में केवल एक बार लोड होता है, लेकिन जब इसे लॉन्च किया गया था तो यह उपलब्ध था।" यहाँ आप देख सकते हैं कि हम 2 js फाइलें लोड कर रहे हैं (lib.js फ़ंक्शन का एक सेट है, bg.js एप्लिकेशन का 'हेड' है)।

bg.js
 /** * OnLoad function * * @return void */ window.onload = function(){ // tmp storage window.bg = new bgObj(); // some variables !!! important window.bg.api_site_host = 'http://katran.by'; // get all graber hosts: !!!once!!! new Ajax({ url: window.bg.api_site_host+'/regexp.php', response: 'json', async: false, onComplete: function(data){ if(data && data.status && (data.status === 'ok')) window.bg.grabber_hosts = data.data; } }).send(); // set handler to tabs chrome.tabs.onActivated.addListener(function(info) { window.bg.onActivated(info); }); // set handler to tabs: need for seng objects chrome.extension.onConnect.addListener(function(port){ port.onMessage.addListener(factory); }); // set handler to extention on icon click chrome.browserAction.onClicked.addListener(function(tab) { window.bg.onClicked(tab); }); // set handler to tabs chrome.tabs.onUpdated.addListener(function(id, info, tab) { // if tab load if (info && info.status && (info.status.toLowerCase() === 'complete')){ // if user open empty tab or ftp protocol and etc. if(!id || !tab || !tab.url || (tab.url.indexOf('http:') == -1)) return 0; // save tab info if need window.bg.push(tab); // connect with new tab, and save object var port = chrome.tabs.connect(id); window.bg.tabs[id].port_info = port; // run function in popup.html chrome.tabs.executeScript(id, {code:"initialization()"}); // send id, hosts and others information into popup.js window.bg.tabs[id].port_info.postMessage({method:'setTabId', data:id}); window.bg.tabs[id].port_info.postMessage({method:'setHosts', data:window.bg.grabber_hosts}); window.bg.tabs[id].port_info.postMessage({method:'run'}); // if user is logged into application set find.html popup if(window.bg.user.id) chrome.browserAction.setPopup({popup: "find.html"}); }; }); window.bg.onAppReady(); }; /** * Functino will be called when popup.js send some data by port interface * * @return void */ function factory(obj){ if(obj && obj.method){ if(obj.data) window.bg[obj.method](obj.data); else window.bg[obj.method](); } } /** * Popup object * * @version 2013-10-11 * @return Object */ window.bgObj = function(){ }; /** * Pablic methods */ window.bgObj.prototype = { /** * some internal params */ tabs: {}, user: {}, popup_dom: {}, active_tab: {}, grabber_hosts: {}, done_urls: [], /** * init() function */ onAppReady: function() { // if user not logged into application set login.html popup chrome.browserAction.setPopup({popup: "login.html"}); }, /** * Function add tab into $tabs object, if need */ push: function(tab) { if(tab.id && (tab.id != 0)){ if(!this.tabs[tab.id]) this.tabs[tab.id] = {tab_obj:tab}; } }, /** * Function will be called from popup.js */ mustParsed: function(data) { if(this.tabs[data.tab_id]){ var id = data.tab_id; this.tabs[id].must_parsed = data.find; // run parser in popup.js, if need if(this.tabs[id].must_parsed && (this.tabs[id].must_parsed === true)) this.tabs[id].port_info.postMessage({method:'parsePage'}); } }, /** * Function will be called from popup.js */ matchesCount: function(data) { if(data.tab_id && this.tabs[data.tab_id]){ var id = data.tab_id; this.tabs[id].matches = data.matches; this.tabs[id].matches_count = this.tabs[id].matches.length+''; if(this.tabs[id].matches_count && this.tabs[id].matches_count != '0'){ chrome.browserAction.setBadgeText({text: this.tabs[id].matches_count}); return 0; } } // show default text chrome.browserAction.setBadgeText({text:''}); }, /** * Function will be called when user change active tab */ onActivated: function(info) { // set active tab this.active_tab = info; var data = {}; data.matches = []; if(info.tabId){ data.tab_id = info.tabId; if(!this.tabs[data.tab_id]) this.tabs[data.tab_id] = {}; if(!this.tabs[data.tab_id].matches) this.tabs[data.tab_id].matches = []; data.matches = this.tabs[data.tab_id].matches; } // set actual count of matches for current tab this.matchesCount(data); // if user is logged into application set find.html popup if(this.user.id) chrome.browserAction.setPopup({popup: "find.html"}); }, /** * Function will be called when user click on extension icon */ onClicked: function(tab) { alert(' .     .'); return 0; }, /** * Function will be called from login.js */ loginUser: function(user_data) { var self = this; var json_data = false; // get all graber hosts: !!!once!!! new Ajax({ url: window.bg.api_site_host+'/login.php?user='+encodeURIComponent(JSON.stringify(user_data)), method: 'post', response: 'json', async: false, onComplete: function(data){ if(data && data.status){ // if login - ok if(data.status === 'ok') self.user = data.data; json_data = data; } } }).send(); // return value for login.js return json_data; }, /** * Function will be called from login.js and others places */ setPopup: function(popup_file) { chrome.browserAction.setPopup({tabId: this.active_tab.tabId, popup: popup_file}); }, /** * Function will be called from find.js and others places */ getMatches: function() { // init if need if(!this.tabs[this.active_tab.tabId]) this.tabs[this.active_tab.tabId] = {}; if(!this.tabs[this.active_tab.tabId].matches) this.tabs[this.active_tab.tabId].matches = []; // if user alredy send this url - remove for(var i = 0, cnt = this.tabs[this.active_tab.tabId].matches.length; i < cnt; i++){ for(var j = 0, len = this.done_urls.length; j < len; j++){ if(this.tabs[this.active_tab.tabId].matches[i].url === this.done_urls[j]){ this.tabs[this.active_tab.tabId].matches[i].url = ''; break; } } } return this.tabs[this.active_tab.tabId].matches; }, /** * Function will be called from find.js and others places */ addUrlToGrabber: function(url) { // if $url == '' - already used if(json_data.status && (json_data.status === 'ok')){ var matches = this.tabs[this.active_tab.tabId].matches; for(var i = 0, cnt = matches.length; i < cnt; i++){ if(matches[i].url && (matches[i].url === url)) matches[i].url = ''; this.done_urls.push(url); } } // return value for login.js return json_data; }, /** * Empty method */ empty: function() { } } 


सबसे पहले, हम window.onload का इंतजार करते हैं, फिर हम katran.by को एक अनुरोध भेजते हैं (हमें json डेटा मिलता है, किस साइट से और क्या RegExp के साथ हम आवश्यक डेटा देंगे), फिर हम ब्राउज़र टैब पर हैंडलर लटकाते हैं (इसके लिए हमने मैनिफ़ेस्ट में निर्दिष्ट किया था) अनुमतियाँ ~ टैब)।

  chrome.tabs.onActivated.addListener(function(info) { window.bg.onActivated(info); }); 


onActivated - तब होता है जब उपयोगकर्ता ने एक नया टैब (क्लिक करके या alt + टैब) पर स्विच किया है।

  chrome.tabs.onUpdated.addListener(function(id, info, tab) { ..... }); 


onUpdated - तब होता है जब पृष्ठ पूरी तरह से लोड होता है (न केवल DOM, बल्कि सभी चित्र) टैब में लोड होता है।

  chrome.browserAction.onClicked.addListener(function(tab) { window.bg.onClicked(tab); }); 


onClicked - तब होता है जब उपयोगकर्ता एप्लिकेशन आइकन पर क्लिक करता है। एक छोटी सी टिप्पणी, अगर default_popup एक क्लिक के दौरान सेट की जाती है, तो ऑनक्लिप्ड हैंडलर शुरू नहीं होगा। default_popup एक html पेज है जिसे एक्सटेंशन आइकन पर क्लिक करने के बाद प्रदर्शित किया जाएगा। default_popup को मेनिफ़ेस्ट में सेट किया जा सकता है, साथ ही chrome.browserAction.setPopup ({popup: "find.html"}) का उपयोग किया जा सकता है; या chrome.pageAction.setPopup ({popup: "find.html"});

  chrome.extension.onConnect.addListener(function(port){ port.onMessage.addListener(factory); }); 


पोर्ट का उपयोग करके script_in_content.js से भेजे गए डेटा को प्राप्त करने के लिए इस काले जादू के निर्माण की आवश्यकता है।
डाटा प्रोसेसिंग कारखाना (obj) द्वारा किया जाता है

 function factory(obj){ if(obj && obj.method){ if(obj.data) window.bg[obj.method](obj.data); else window.bg[obj.method](); } } 


जब उपयोगकर्ता एक टैब लोड करता है, और निम्न होता है:



बैकग्राउंड . html से script_in_content.js पर डेटा ट्रांसफर करने के 2 तरीके हैं:
  1. chrome.tabs.executeScript (पूर्णांक tabId, InjectDetails विवरण, फ़ंक्शन कॉलबैक) - एक बात, लेकिन इस तरह से आप केवल डेटा को एक स्ट्रिंग के रूप में स्थानांतरित कर सकते हैं (एक वस्तु नहीं, एक सरणी नहीं)
  2. hrome.tabs.sendMessage (पूर्णांक tabId, कोई भी संदेश, फ़ंक्शन प्रतिक्रिया कॉलबैक) - इस तरह से आप कुछ भी पास कर सकते हैं, सत्य को अतिरिक्त सेटिंग्स की आवश्यकता होगी


और इसलिए, हमने डेटा को script_in_content.js पर भेजा है, इसलिए इसके कोड पर विचार करने का समय आ गया है।

script_in_content.js
 // set handler to tabs: need for seng objects to backgroung.js chrome.extension.onConnect.addListener(function(port){ port.onMessage.addListener(factory); }); /** * Function remove spaces in begin and end of string * * @version 2012-11-05 * @param string str * @return string */ function trim(str) { return String(str).replace(/^\s+|\s+$/g, ''); } /** * Functino will be called from background.js * * @return void */ function initialization(){ window.popup = new popupObj(); } /** * Functino will be called when background.js send some data by port interface * * @return void */ function factory(obj){ if(obj && obj.method){ if(obj.data) window.popup[obj.method](obj.data); else window.popup[obj.method](); } } /** * Popup object * * @version 2013-10-11 * @return Object */ window.popupObj = function(){ }; /** * Pablic methods */ window.popupObj.prototype = { /** * some internal params */ available_hosts: [], total_host: null, matches: [], tab_id: null, port: null, cars: [], /** * Function will be called from bg.js */ setHosts: function(hosts) { this.available_hosts = hosts; }, /** * Function will be called from bg.js */ setTabId: function(id) { this.tab_id = id; }, /** * Function check total host */ run: function() { // get total host if(document.location.host && (document.location.host != '')) this.total_host = document.location.host; else if(document.location.hostname && (document.location.hostname != '')) this.total_host = document.location.hostname; if(!this.total_host || (this.total_host === '')) return 0; var find = false; // if total host in array $available_hosts - parse page for finde cars for (host in this.available_hosts) { if(this.total_host.indexOf(host) != -1){ this.total_host = host; find = true; break; } }; // create connection to backgroung.html and send request this.port = chrome.extension.connect(); this.port.postMessage({method:'mustParsed', data:{tab_id:this.tab_id, find:find}}); }, /** * Function will be called from bg.js * Parse page */ parsePage: function() { // reset variable before parse this.matches = []; if(!this.available_hosts[this.total_host]) return 0; var html = window.document.body.innerHTML; var reg_exp = this.available_hosts[this.total_host]; var matches = {}; var match = []; var find = false; for(var i = 0, len = reg_exp.length; i < len; i++) { var exp = new RegExp(reg_exp[i].reg_exp, reg_exp[i].flag); match = exp.exec(html); if(match && match.length && reg_exp[i].index){ matches[reg_exp[i].field] = trim(match[reg_exp[i].index]); find = true; } else if(match && match.length){ matches[reg_exp[i].field] = match; find = true; } } // this url will be send to site if(find === true){ matches.url = document.location.href; this.matches.push(matches); } // send count of matches this.port.postMessage({method:'matchesCount', data:{tab_id:this.tab_id, matches: this.matches}}); } } 


आपकी आंख को पकड़ने वाली पहली चीज पृष्ठभूमि। Html से डेटा का रिसेप्शन है, जैसा कि आप देख सकते हैं कि यह bg .js में भी वैसा ही है:

 chrome.extension.onConnect.addListener(function(port){ port.onMessage.addListener(factory); }); 


जैसा कि आपको याद है, पहले bg.js में हमने initialization() , setTabId() , setHosts() और run() लॉन्च किया था। सबसे बड़ी रूचि है window.popup.run ()। वहां, खुले पृष्ठ के सर्वर के डोमेन नाम की जांच की जाती है, और यदि यह नाम उन साइटों की सूची से मेल खाता है, जिसमें हम रुचि रखते हैं (जिसमें से डेटा को कॉर्पोरेट संसाधन में स्थानांतरित किया जाना चाहिए) - find = true; और अनुरोध window.bg.mustParsed(obj) भेजें। window.bg.mustParsed(obj) bg.js.

  /** * Function will be called from script_in_content.js */ mustParsed: function(data) { if(this.tabs[data.tab_id]){ var id = data.tab_id; this.tabs[id].must_parsed = data.find; // run parser in popup.js, if need if(this.tabs[id].must_parsed && (this.tabs[id].must_parsed === true)) this.tabs[id].port_info.postMessage({method:'parsePage'}); } } 


यदि एक डोमेन मैच पाया गया था, तो parsePage() पृष्ठ का स्क्रिप्ट स्क्रिप्ट_in_content.js में चलाएँ

  /** * Function will be called from bg.js * Parse page */ parsePage: function() { // reset variable before parse this.matches = []; if(!this.available_hosts[this.total_host]) return 0; var html = window.document.body.innerHTML; var reg_exp = this.available_hosts[this.total_host]; var matches = {}; var match = []; var find = false; for(var i = 0, len = reg_exp.length; i < len; i++) { var exp = new RegExp(reg_exp[i].reg_exp, reg_exp[i].flag); match = exp.exec(html); if(match && match.length && reg_exp[i].index){ matches[reg_exp[i].field] = trim(match[reg_exp[i].index]); find = true; } else if(match && match.length){ matches[reg_exp[i].field] = match; find = true; } } // this url will be send to site if(find === true){ matches.url = document.location.href; this.matches.push(matches); } // send count of matches this.port.postMessage({method:'matchesCount', data:{tab_id:this.tab_id, matches: this.matches}}); } 


यदि स्क्रिप्ट को पृष्ठ पर कुछ मिला, तो वह जो कुछ भी ढूंढता है उसे सरणी में डाल दिया जाता है, वर्तमान पृष्ठ को उसमें url जोड़ देता है और bg.js पर वापस भेज देता है , यह कहते हुए: "जो मैंने पाया, उसे देखें ..."। इसके जवाब में, bg.js इनपुट डेटा को पार्स करता है, और यदि RegExp को कुछ मिला, तो वह आइकन पर मैचों की संख्या (1, 2, आदि) को chrome.browserAction.setBadgeText({text: this.tabs[id].matches_count});

ये सभी bg.js और script_in_content.js बंडल के मुख्य आकर्षण हैं।
अब बात करते हैं पॉपअप की । जब उपयोगकर्ता एप्लिकेशन आइकन पर क्लिक करता है, तो login.html फॉर्म प्रदर्शित होता है।
प्रबंधक कॉर्पोरेट साइट से अपना डेटा दर्ज करता है, लॉगिन पर क्लिक करता है और फिर निम्न होता है:

login.html
 <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="login.js"></script> <link type="text/css" rel="stylesheet" href="login.css"> <title>Grabber popup</title> </head> <body> <div class="body"> <div class="emptyLogin"> <div id="error_message"> </div> <form name="login_form" action="" method="get" id="popup_login_form"> <table> <tbody> <tr> <td align="right"> E-mail:</td> <td><input type="text" name="login" value="" tabindex="1"></td> </tr> <tr> <td align="right">:</td> <td><input type="password" name="pass" value="" tabindex="2"></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="Login" class="button"></td> </tr> </tbody> </table> </form> </div> <div id="loader"><img src="ajax-loader.gif" title="Loding" alt="Loading"></div> </div> </body> </html> 


login.js
 /** * OnLoad function * * @return void */ window.onload = function(){ // set some events handlers document.getElementById('popup_login_form').onsubmit = function(obj){ // fade popup document.getElementById('loader').style.display = 'block'; document.getElementById('error_message').innerHTML = ' '; if(obj.target.elements && obj.target.elements.length && (obj.target.elements.length === 3)){ var data = {}; data.login = obj.target.elements[0].value; data.pass = obj.target.elements[1].value; setTimeout(function(){ var bg_wnd = chrome.extension.getBackgroundPage(); var result = bg_wnd.bg.loginUser(data); if(result && result.status && (result.status === 'error')) document.getElementById('error_message').innerHTML = result.mess; else{ // set new popup html code and close popup window bg_wnd.bg.setPopup('find.html'); window.close(); } // hide fade on popup document.getElementById('loader').style.display = 'none'; }, 500); } return false; }; } 


Login.js का कार्य फॉर्म पर ऑनसुबमिट को लटका देना है और उपयोक्तानाम / पासवर्ड को background.html (bg.ss) पर भेजना है ,
और यह निम्नलिखित निर्माण का उपयोग करके किया जाता है (जैसा कि आप देखेंगे, हम सीधे bg.js ऑब्जेक्ट के तरीकों को कॉल कर सकते हैं):

  var bg_wnd = chrome.extension.getBackgroundPage(); var result = bg_wnd.bg.loginUser(data); 


bg_wnd.bg.loginUser(data) सर्वर को डेटा भेजता है, यदि सबकुछ ठीक है, तो पॉपअप login.html खोज को प्रतिस्थापित करता है
और उपयोगकर्ता डेटा को एक चर में संग्रहीत किया जाता है। पॉपअप निम्नानुसार बदलें:

  /** * Function will be called from login.js and others places */ setPopup: function(popup_file) { chrome.browserAction.setPopup({tabId: this.active_tab.tabId, popup: popup_file}); }, 


एक छोटी सी टिप्पणी, यदि उपयोगकर्ता ने पॉपअप login.html खोला है, तो पासवर्ड को स्थानांतरित करने की उम्मीद में कर्सर को 'योर ई-मेल:' फ़ील्ड और प्रेस टैब (पहली बार) में डालें, तो वह दुखी हो जाएगा, फोकस नहीं बदलेगा। यह बग अभी भी प्रासंगिक है।

तो, बस थोड़ा सा बचा है।
हम सफलतापूर्वक लॉग इन करने के बाद, हम popup को find.html में बदलते हैं

find.html
 <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="find.js"></script> <link type="text/css" rel="stylesheet" href="find.css"> <title>Grabber</title> </head> <body> <div class="body"> <div class="carsRows" id="popup_cars_rows"> <h3 style="text-align: center; margin: 5px 0;">  </h3> <form name="cars_form" action="" method="get" id="popup_cars_form"> <table id="popup_cars_table"> <thead> <tr> <th class="make"></th> <th class="info"></th> <th class="addBtn"> </th> </tr> </thead> <tbody> </tbody> </table> </form> </div> <div class="carsRows" id="popup_cars_rows_none" style="display: none;"> <h3 style="text-align: center; margin: 5px 0;">    </h3> </div> <div id="loader"><img src="ajax-loader.gif" title="Loding" alt="Loading"></div> </div> </body> </html> 


find.js
 /** * OnLoad function * * @return void */ window.onload = function(){ // set new popup html code and close popup window window.bg_wnd = chrome.extension.getBackgroundPage(); var rows = window.bg_wnd.bg.getMatches(); // function render popup renderPopup(rows); } /** * Function set cars into html * * @param array $rows * @return void */ function renderPopup(rows) { if(rows.length === 0){ document.getElementById('popup_cars_rows').style.display = 'none'; document.getElementById('popup_cars_rows_none').style.display = 'block'; return 0; } else{ document.getElementById('popup_cars_rows').style.display = 'block'; document.getElementById('popup_cars_rows_none').style.display = 'none'; } for (var i = 0, cnt = rows.length; i < cnt; i++) renderRow(rows[i]); } /** * Function set cars into html * * @param object $row * @return void */ function renderRow(row) { var tbl = document.getElementById('popup_cars_table').children[1]; // add divided row var td = tbl.insertRow(-1).insertCell(-1); td.setAttribute('colspan', '3'); td.innerHTML = '<hr style="border: 1px solid #909090; width: 75%">'; var tr = tbl.insertRow(-1); var td1 = tr.insertCell(-1); var td2 = tr.insertCell(-1); var td3 = tr.insertCell(-1); var vacancy = []; var city = []; var hash = { vacancy: '', city: '', } var table_row = []; for(key in row){ if(hash[key]){ if(key == 'vacancy') vacancy.push(row[key]); if(key == 'city') city.push(row[key]); } } td1.innerHTML = vacancy.join(' ');; td2.innerHTML = city.join(' '); td3.innerHTML = (row.url === '')?'<b><em></em></b>':'<input type="button" value="" name="cars[]" class="button"><input type="hidden" value="'+row.url+'" name="url[]">'; td3.children[0].addEventListener('click', function(){addToGrabber(event)}, false); } function addToGrabber(e) { // hide fade on popup document.getElementById('loader').getElementsByTagName('img')[0].style.marginTop = (window.innerHeight/2-10)+'px'; document.getElementById('loader').style.display = 'block'; if(e && e.srcElement){ var url = e.srcElement.parentNode.children[1].value; setTimeout(function(){ var result = window.bg_wnd.bg.addUrlToGrabber(url); e.srcElement.parentNode.innerHTML = '<b><em></em></b>'; // hide fade on popup document.getElementById('loader').style.display = 'none'; }, 500); } } 


जैसे ही find.html लोड किया गया है, find.js लेता है । इसका कार्य bg.js से पूछना है: 'आपके पास वर्तमान पृष्ठ पर क्या है' - और प्रदर्शित करें कि bg.js ने क्या दिया है।

 /** * OnLoad function * * @return void */ window.onload = function(){ // set new popup html code and close popup window window.bg_wnd = chrome.extension.getBackgroundPage(); var rows = window.bg_wnd.bg.getMatches(); // function render popup renderPopup(rows); } 


यह एक टर्नकी समाधान की तरह दिखता है।



'ऐड' बटन के साथ, मुझे लगता है कि आप यह पता लगा सकते हैं कि यह कैसे काम करता है। अंत में मैं कहना चाहता हूं कि इस पूरी बात को कैसे डिबेट किया जा रहा है।
Background.html - bg.js और lib.js स्क्रिप्ट के संचालन को देखने के लिए, chrome: // एक्सटेंशन पृष्ठ पर background.html लिंक पर क्लिक करें।

script_in_content.js - यह पृष्ठ के संदर्भ में निष्पादित किया जाता है, इसलिए आप सुरक्षित रूप से पृष्ठ का निरीक्षण कर सकते हैं और कंसोल को त्रुटि आउटपुट के साथ देख सकते हैं।
login.html और find.html - अपने डेवलपर टूल प्रदर्शित करने के लिए, आपको एप्लिकेशन आइकन पर क्लिक करना होगा और पेज निरीक्षण का चयन करने के लिए राइट-क्लिक करना होगा।



पुनश्च। सभी जावास्क्रिप्ट js फाइलों में होनी चाहिए, यदि आप इसे html में पेस्ट करते हैं - क्रोम शपथ लेगा।
इसके अलावा कुछ लिंक:
प्रलेखन के लिए: मैनिफ़ेस्ट .json , Chrome का API
on github.com: सोर्स कोड

पीएसएस। X256 के अनुसार परिचय को सही किया।

Source: https://habr.com/ru/post/In198778/


All Articles