2

Ich versuche eine Chrome-Erweiterung zu machen und als Teil davon muss ich die URL der besuchten Seite mit dieser Erweiterung holen in der Lage sein, es zu verwalten. Aber kann das nicht tun, weil dieser Fehler: angular.min.js: 117 Typeerror: kann nicht lesen Eigenschaft 'GetSelected' undefinierterIch versuche, URL der Seite in der Erweiterung zu bekommen, aber chrome.tabs.getSelected() gibt undefined zurück

Mein manifest.json:

{ 
    "manifest_version": 2, 

    "name": "Bookmark Manager Plugin", 
    "description": "This extension will manage the users visiting history", 
    "version": "1.0", 
    "content_scripts": [{ 
     "matches": [ 
      "http://*/*", 
      "https://*/*" 
     ], 
     "js": ["app/scripts/chrome.js"], 
     "run_at": "document_end" 
    }], 
    "browser_action": { 
     "default_title": "Thumbnail Opener", 
     "default_popup": "app/index.html", 
     "default_icon": "app/favicon.ico" 
    }, 
    "background": { 
     "scripts": ["app/scripts/controllers/mainController.js"], 
     "persistent": false 
    }, 
    "permissions": [ 
     "tabs", 
     "http://*/*", 
     "activeTab" 
    ] 
} 

Meine Popup-HTML-Datei:

<!DOCTYPE html> 
<html ng-app="somename"> 
<head lang="en"> 
    <meta charset="UTF-8"> 
    <title>Bookmarks Manager</title> 
    <link rel="stylesheet" href="components/bootstrap/css/bootstrap.min.css"> 
    <script src="components/jquery.min.js"></script> 
    <script src="components/angular.min.js"></script> 
    <script src="components/bootstrap/js/bootstrap.min.js"></script> 
    <script src="scripts/chrome.js"></script> 
</head> 
<body ng-controller="mainCtrl"> 
    <div style="margin-top:40px;"></div> 
    <div class="container"> 
     <div class="row"> 
      <div class="col-lg-10 col-lg-offset-1 text-center"> 
       <form id=> 
        <fieldset class="form-group"> 
         <label for="input_1">Please Enter Keyword Pattern</label> 
         <input type="text" id="input_1" class="form-control" ng-model="inputValue"/> 
         <input type="hidden" id="hidd" name="url"/> 
         <button type="button" class="btn btn-primary">ADD</button> 
        </fieldset> 
       </form> 
      </div> 
     </div> 
     <div class="row"> 
      <div class="col-lg-10 col-lg-offset-1 text-center"> 
       <p ng-repeat="pattern in existingData">{{pattern.name}} - {{pattern.url}}</p> 
      </div> 
     </div> 
    </div> 
    <script src="scripts/controllers/mainController.js"></script> 
</body> 
</html> 

Meine content_script Datei:

function getURL() { 
    chrome.tabs.getSelected(null, function(tab) { 
     var myURL = tab.url; 
    }); 
    return myURL; 
} 

Mein Hintergrund js-Datei:

angular 
    .module('somename', []) 
    .controller('mainCtrl', ['$scope', '$location', function($scope, $location) { 
     $scope.inputValue = getURL(); 
     $scope.showSuggestions = false; 
     $scope.existingData = [{ 
       name: 'chrome extensions', 
       url: 'https://www.sitepoint.com/create-chrome-extension-10-minutes-flat/' 
      }, { 
       name: 'yii', 
       url: 'http://www.yiiframework.com/download/' 
      }, { 
       name: 'Jquery', 
       url: 'https://jquery.com/' 
      }, 
     ]; 
     $scope.searchDatabase = function() { 
      $scope.existingData.forEach(function(el) { 
       if (el.name.indexOf($scope.inputValue) > -1) { 
        $scope.showSuggestions = true; 
       } else { 
        var url; 
       } 
      }) 
     }; 
    }]); 

Kann jemand bitte helfen, warum chrome.tabs nicht definiert ist und wie man das funktioniert?

habe ich versucht, dies zu:

in Service-Datei:

angular.module('somename').factory('getURL', ['$http', function ($http) { 
    return { 

     promiseToHaveData: function() { 

      return $http.get(chrome.tabs.query(null, function (tab) { 

       return tab; 
      })).then(function (tab) { 

       var result = tab.url; 

       return result; 
      }, function (response) { 

       console.log('Error has ocurred'); 
      }); 
     } 
    }; 
}]); 

und in der Steuerung:

angular.module('somename', []) 
    .controller('mainCtrl', ['$scope', 'getURL', function ($scope, getURL) { 

     getURL.promiseToHaveData().then(function (url) { 

      $scope.inputValue = url; 
     }) 
    } 

aber wieder nicht funktioniert - angular.min.js:117 TypeError: Cannot read property 'query' of undefined

+0

Zunächst einmal, warum erstes Argument 'chrome.tabs.query' ist null? Es ist Funktion nimmt Objekt (kann leer sein {}) und Rückruf. – UserName

+0

Zweitens, ich denke, Sie brauchen verwenden [deaktiviert] (https://docs.angularjs.org/api/ng/service/$q) -Objekt, weil, wie ich verstehe, http verwendet, wenn die Kommunikation mit Remote-HTTP-Servern. Das heißt, Sie erstellen eine Umbruchfunktion und darin das 'chrome.tabs.query' Ergebnis dieses Durchlaufs, um dieses Objekt 'zu lösen'. Etwas wie [das] (http://pastebin.com/06tG5EQ3). Dann rufen Sie die Wrap-Funktion auf und können .then() verwenden. Dieses [Beispiel] (https://thinkster.io/a-better-way-to-learn-angularjs/promises) emuliert eine asynchrone Funktion. Umsetzung Versprechen in Ihrem Code mir schien seltsam. Deshalb habe ich den zweiten Absatz geschrieben. – UserName

+0

Vielen Dank, es funktioniert jetzt – LachezarB

Antwort

2

Ich weiß nicht, AngularJS, aber Ihr Code in content_scripts tut funktioniert nicht, weil:

content_scripts hat keinen Zugriff auf chrome.api.

Here are some examples of what content scripts can do:

  • Find unlinked URLs in web pages and convert them into hyperlinks

  • Increase the font size to make text more legible

  • Find and process microformat data in the DOM

However, content scripts have some limitations. They cannot:

  • Use chrome.* APIs, with the exception of:

    • extension (getURL , inIncognitoContext , lastError , onRequest , sendRequest)

    • i18n

    • runtime (connect , getManifest , getURL , id , onConnect , onMessage , sendMessage)

    • storage

  • Use variables or functions defined by their extension's pages

  • Use variables or functions defined by web pages or by other content scripts

$scope.inputValue=getURL(); 

Und background hat keinen Zugang zu content_scripts.

Sie müssen die Funktion in background übertragen.

Content Scripts | Architecture


Ihre Funktion Ergebnis nicht zurück, weil chrome.tabs.getSelected asynchron ist, ist dieses Ergebnis wird zurückgegeben (undefined), während chrome.tabs.getSelected Ausführung nicht beendet ist.

Stattdessen return müssen Sie Aktionen in Callback-Funktion ausführen.

Asynchronous vs. synchronous methods


Zusätzlich chrome.tabs.getSelected ist deprecated seit Chrome 33. Sie chrome.tabs.query verwenden müssen:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){ 

    if(tabs.length != 0) { 

     // Something 
    } 
}); 

Der Code gibt aktive Reiter im aktuellen Fenster.

chrome.tabs.query

+0

Danke für die Antwort, aber ich habe bereits alle diese Dokumentation gelesen und weil ich keine Antwort gefunden habe, entscheide mich hier meine Frage zu stellen. Also bitte, wenn Sie eine Idee haben, erklären Sie es in weiteren Einzelheiten. Zum Beispiel, was zu tun, anstatt in getURL() zurückzukehren? – LachezarB

+0

@LachezarB, müssen Sie die Logik der Arbeitsregisterkarten in Hintergrundskripte übertragen. Ich weiß nicht, was Sie mit 'getURL' im Kontext AngularJS tun können. Sie können versuchen, 'getURL' in Ihr Winkelmodul zu übertragen und die folgenden Aktionen auszuführen, ruft externe Methode auf. Sehen Sie sich an, wie chrome.api in diesem Beispiel verwendet wird: [ToDo Chrome Extension] (https://angular-tutorial.quora.com/Make-a-Todo-Chrome-Extension-with-AngularJS-1). Oder wenn es eine Möglichkeit gibt, das Ergebnis der Funktion von außen nach $ scope zu übertragen. – UserName

+0

Möglicherweise benötige ich eine Berechtigung wie hier geschrieben: https://developer.chrome.com/extensions/permissions – LachezarB