Apply Angular.js to new DOM Element in Chrome Extension Content Script - javascript

Okay, so I've been at this for a while.
In the red box, I want to have some angular functionality (ng-repeats, data binding, etc...) This red box appears when text on any webpage is double clicked. However, I can't seem to find out how to actually get angular wired/hooked up to the text box example in the red popup.
It seems fairly trivial to use angular in a badge popup in chrome, as well as on options pages, etc...but I can't seem to get it working in this instance.
inject.js (which is included as a content script in manifest, below)
var displayPopup = function(event) {
var mydiv = document.createElement('div');
var $div = $('#divid').closest('.sentence');
mydiv.innerHTML = getSelectionText();
mydiv.innerHTML += currentSentence.innerHTML;
//Next line is where I want to apply some angular functionality
mydiv.innerHTML += '<div ng-app="myApp" scroll-to-me><input type="text" ng-model="data.test"><div ng-model="data.test">{{data.test}}</div></div>';
mydiv.id = "popup";
mydiv.style.position = "fixed";
mydiv.style.top = event.clientY + "px";
mydiv.style.left = event.clientX + "px";
mydiv.style.border = "4px solid #d00";
mydiv.style.background = "#fcc";
$("body").append(mydiv);
$.getJSON('http://local.wordly.com:3000/words/definitions/test', function(data) {
console.log(data);
});
}
and my manifest.json content script array looks like:
"content_scripts": [
{
"matches": [
"https://www.google.com/*"
],
"css": [
"src/inject/inject.css"
]
},
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"js/angular/angular.js", "app.js", "js/jquery/jquery.js", "src/inject/inject.js"
]
}
]
and app.js, also included in manifest, for just some skeletal app to get up and running.
var myApp = angular.module("myApp", []);
myApp.factory('Data', function(){
//return {message: "I'm data from a service"};
});
myApp.controller("SecondCtrl", function($scope, $http){
});

You need to bootstrap manually if you’re injecting the markup after the page loads. Angular will only run ng-app if it’s present when the document is loaded. Afterwards, you pass the module name to angular.bootstrap:
angular.bootstrap(mydiv, ['myApp'])
Example.

Related

Google Chrome Extension: How to use an external script

I am trying to make a markdown preview tab for a forum I often use that uses markdown in it's formatting but currently does not have any way to preview what that markdown will look like.
I want to use the page down markdown converter however I don't know how to use the files inside the content script
here is my manifest.json
{
"name": "Forum Post Previewer",
"version": "0.1",
"manifest_version":2,
"description":"Adds a preview tab on the post editor",
"permissions": [
"activeTab",
"*://*/*"
],
"content_scripts": [
{
"js": ["previewtab.js"]
}
],
}
and here is the previewtab.js
// Adding the preview tab
var tabs = document.getElementsByClassName("nav nav-tabs");
var list = document.createElement("li");
var tab = document.createElement("a");
tab.innerHTML = "Preview";
tab.setAttribute("data-toggle", "tab");
tab.setAttribute("href", "#tab3");
list.appendChild(tab);
document.getElementById("post-editor").parentElement.firstElementChild.appendChild(list);
var content = document.createElement("div");
content.setAttribute("class", "tab-pane");
content.setAttribute("id", "tab3");
var bar = document.createElement("div");
bar.setAttribute("id", "wmd-button-bar");
var textarea = document.createElement("textarea");
textarea.setAttribute("id", "wmd-input");
textarea.setAttribute("class", "wmd-input");
var preview = document.createElement("div");
preview.setAttribute("id", "wmd-preview");
preview.setAttribute("class", "wmd-panel wmd-preview");
content.appendChild(bar);
content.appendChild(textarea);
content.appendChild(preview);
document.getElementById("post-editor").appendChild(content);
// Using the converter
var converter = Markdown.getSanitizingConverter();
var editor = new Markdown.Editor(converter);
editor.run();
right now I get errors when using the converter because it does not know where Markdown has come from.
Can you help me to find out how to use this external script in a chrome extension
Thanks
Just add the .js files to your extension and include them as content scripts before yours, like this:
"content_scripts": [
{
"js": ["Markdown.Converter", "Markdown.Editor", "Markdown.Sanitizer", "previewtab.js"]
}
],

Chrome extension disables js triggers

I have made a little Chrome extension that injects some code in the current page.
This extension has a weird behaviour though, whenever the code is injected, none of the page's Javascript triggers seem to work anymore.
Would one of you have any idea what that happens? On top of fixing the code I'd really like to know why this happens.
Example : on this page : http://www.acti.fr/success-story/ghd/ if the extension injects the picture, I cannot click on either the menu or "continuer la lecture" at the bottom.
Here are the manifest and the actual code :
manifest.json
{
"manifest_version": 2,
"name": "wpi",
"description": "just an other extension",
"version": "1.0",
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["my-style.js"]
}]
}
my-script.js :
function wpkm_check_content(wpkm_text) {
var wpkm_word = wpkm_text.split(" ");
var wpkm_c = wpkm_word[0].localeCompare("Wordpress");
if (wpkm_c == 1)
return (1);
return (0);
}
var wpkm_html = '<div id="wpkm-bloc" style="position:absolute;right:10px;top:10px;z-index:99999">';
wpkm_html += '<img id="wpkm-img" src="https://nathanarnold.files.wordpress.com/2009/02/ssim51.gif">';
wpkm_html += '</div>';
var wpkm_sdomain = document.domain;
var wpkm_request = new XMLHttpRequest();
wpkm_request.open('GET', '/license.txt', true);
wpkm_request.onreadystatechange = function(){
if (wpkm_request.readyState === 4){
if (wpkm_request.status === 200
&& wpkm_check_content(wpkm_request.responseText) == 1) {
document.body.innerHTML += wpkm_html;
}
else {
console.log("Oh no, it does not exist!");
}
}
};
wpkm_request.send();
Any hints will be appreciated :D
You're effectively reassigning the entire innerHTML of the document body by using += append operator which causes reevaluation and recreation of the entire page and of course all previously attached event handlers aren't reattached automatically.
Use insertAdjacentHTML instead:
document.body.insertAdjacentHTML("beforeend", wpkm_html);

Content JavaScript Not Executing in Content Script

My Chrome extension has a Content Script that adds a DIV with a button. The OnClick JS function defined for the button, however, never executes (defined in the same Content Script), so the button does nothing. Why is that?
contentscript.js
var msg = "Click this button <button onclick='test()'>Test</button>";
var div = document.createElement( 'div' );
div.id = 'testDiv';
document.body.appendChild( div );
document.getElementById('testDiv').innerHTML = msg;
function test()
{
alert('in test()'); // Never gets here
}
manifest.json
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"css": ["contentstyle.css"],
"js": ["jquery-1.11.2.min.js", "contentscript.js"]
Look at the official docs regarding policies. Inline javascript is strictly prohibited. The docs explain how to do it. https://developer.chrome.com/extensions/contentSecurityPolicy

Element created by Content script on page creating issue with Gmail,Facebook,stackoverflow etc

I am developing a Chrome extension and my requirement is to create element(button) on page for each tab open and wants to show simple alert message on clicking button..it works properly for all but it always creating issue with Gmail,Facebook and Stackoverflow..please help me to resolve this issue.
I am having the code of adding button to a web page in my Content script.
manifest.json
....
....
"content_scripts": [
{
"matches":["http://*/*", "https://*/*"],
"css": [ "style.css" ],
"js":["contentScript.js"],
"all_frames": false,
"run_at": "document_idle"
}
]
....
....
contentScript.js
....
....
function addButton() {
document.body.innerHTML += '<button id="my_button" class="buttonCss">Show Button</button>';
var button = document.getElementById("my_button");
button.addEventListener("click", function () {
alert("hello");
}, false);
}
.....
.....
....
I think some Gmail security features is creating the issue.
document.body.innerHTML += /* ... */
I think this is your issue right there. It forces Chrome to re-create the entire DOM of body, losing attached events/data.
The proper way would be to construct and append a DOM node:
var button = document.createElement("button");
button.id = "my_button";
button.className = "buttonCss";
button.textContent = "Show Button";
document.body.appendChild(button);

Create sidebar by manipulating the DOM of the loaded webpage

My simple Chrome extension is injecting a DIV at the top of document.body, then you can drag text from your page into the extension. The problem is that I want the extension DIV not to be located at top, but instead be something like a side bar to the left.
In other words I need to know how to programatically rearrange already loaded DOM structure so that all content is moved to the right and horizontally compressed and then the left area is accessible to further manipulations.
One option I was considering was to do this:
tmp = document.body.innerHTML
document.body.innerHTML = '<table><tr><td id=sidebar></td><td>'
+ tmp + '</td></tr></table>'
But this will be inneficient, will cause rerender and may have other undesired side effects.
By the way current version of the extension will inject every page "on load", but this is just a temporary solution, the side bar must be displayed when the extension button is clicked. This is not part of this question, I know how to do that. Just to let you know that the sidebar creation could be done at any time when user chooses to click the button. That's why using innerHTML is not a good option.
pageload.js
function allowDrop(ev) {ev.preventDefault()}
function drop(ev) {
ev.preventDefault();
var t = 'text', T = Array.prototype.slice.apply(ev.dataTransfer.types)
if (T.indexOf('text/html') >= 0)
t = "text/html"
console.log('text type:', t)
d1.innerHTML += '<div style="display:inline;border:2px solid #000000;">'+ev.dataTransfer.getData(t)+'</div> '
}
function createDragbar(id) {
var n = document.createElement('div')
// n.style.position = "absolute";
n.setAttribute('id', id)
n.style.border = '1px solid #aaaaaa'
n.style.height = 532
n.style.background = "teal"
n.innerHTML = "Drop your text here "
n.ondrop = drop
n.ondragover = allowDrop
document.body.insertBefore(n, document.body.firstChild)
}
createDragbar('d1')
manifest.json
{
"name": "Yakov's Demo Extension",
"description": "Just a demo",
"version": "0.1",
"permissions": [
"activeTab"
],
"content_scripts": [{
"matches": ["http://*/*", "https://*/*", "file://*/*"],
"js": ["pageload.js"]
}],
"manifest_version": 2
}
What about element.insertAdjacentHTML(position, text)?
https://developer.mozilla.org/en-US/docs/Web/API/Element.insertAdjacentHTML

Categories