Chrome Extension - javascript

I am trying to create a chrome extension that once I click a certain button in my extension, it will highlight the current tab. However, I am having a little bit of trouble.
Right now I have
document.getElementById("button").addEventListener("click", function () {} in my JS file, but I can't seem to find a solution on how to colour the current tab. I know something is supposed to go in {}, but I am not exactly sure what. Any help would be appreciated.

As of this writing, there are no methods or properties available as part of the tabs API for Chrome Extensions that allow you to set/modify the color of a tab.
Thus, this is not (currently) possible to accomplish from within the extension context within Chrome.
EDIT: On second thought, this actually might be possible, albeit in a bit of a shoehorned manner. By adding the example function to get the current tab (and then its id property), you can pass it to the chrome.tabs.group() method, then access the returned tabGroup in the callback parameter to set its color property:
chrome.tabs.group(
options: {
tabIds: (await getCurrentTab()).id
},
callback: function(groupId) {
chrome.tabGroups.update(
groupId: groupId,
updateProperties: {
color: "red"
}
);
}
);
However, it's not clear if the resulting visual meets your requirements or not.

Related

How to one-way process html data for the view in CKEditor 5?

In the CKEditor view for authors I need to change links to files so that the session ID of the author gets attached. However in the actual content for normal users the specific user ID is added automatically. Therefore the authors ID must not be saved in the content the author edits with CKEditor, it just has to be there in the view while he edits so that he can see an image for example. On save the 'clean' link without any IDs need to be saved.
In CKEditor 5 there seem to be more possibilities to achieve such a one-way data filtering for example with
Conversions
the Editing Engine generally
the HtmlDataProcessor specifically
However I couldn't find a good example respectively an easy and clean approach to achieve this. (My tries turned out to become quite complicated and didn't work properly...) I'd guess this is a quite common use case so maybe I'm overlooking something. Is there a good solution to this?
Update 1: Example links would be:
"clean link" how it has to be saved but will never work:https://example.com/some-image.png
modified link for specific users in content (and how it has to be modified in ckeditor view for authors as well): https://example.com/some-image.png?sessionId=currentUsersSessionId
Update 2:
While I was working further with CKEditor I came across more things like this which simply are very unpleasant from a developers point of view. And it seems this is by design, since quote from a Contributor 'fredck':
[...] we want to bring the editor out of the "HTML Editor" thing, making it the perfect soluting for "quality content writing".
Implicitly this means, if you are a developer and you have advanced users with advanced use cases (which may be likely the case if you are on Stackoverflow) you are not the target audience and shouldn't use CKEditor in the first place.
You can read more about this for example in the discussion here (also it is about another feature): https://github.com/ckeditor/ckeditor5/issues/592
To modify downloaded links you can write a custom downcast converter, which modifies obtained href.
Here is a working sample which adds the current timestamp to URLs:
https://codepen.io/msamsel/pen/zVMvZN?editors=1010
editor.conversion.for( 'dataDowncast' ).add( dispatcher => {
dispatcher.on(
'attribute:linkHref',
( evt, data, conversionApi ) => {
if ( !conversionApi.consumable.test( data.item, 'attribute:linkHref' ) ) {
return;
}
if ( data.attributeNewValue ) {
data.attributeNewValue += `#time=${ ( new Date() ).getTime() }`;
}
},
{ priority: 'high' }
);
} );
Few words how it works.
There is created listener which reacts on attribute:linkHref changes (it's fired only when data are obtained anyway because it's dataDowncast). Listeners fires with 'high' priority to change URL before the actual Link plugin will create an output. First is checked if the given model element is not consumed, but without consuming it, because we want to preserve native behavior which will process this same element again. The attribute value is extended with a timestamp, what finish this listener. After that, the native behaviour is fired, which has 'normal' priority.
A similar approach was used to implement custom link attributes. More about dispatcher and conversion process might be found here:
https://ckeditor.com/docs/ckeditor5/latest/framework/guides/architecture/editing-engine.html#conversion
https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_conversion_downcastdispatcher-DowncastDispatcher.html

Functionally test that an Element is visible (no elements covering) with Intern

I am currently using the JavaScript framework Intern to test my site, I am wanting to ensure that specific element's are truly visible. Intern currently has an option "isDisplayed" which half does this. But what I am wanting to also do is check that it would be truly visible to the user and that any other elements on the page do not cover (perhaps by z-index issues) etc.
Does anyone have an suggestions?
Thanks in advance.
Usually, it's better to focus on your unit tests and make sure the styles you expect to be setting are coming back correctly from the utility/helper functions you use to do so. Otherwise, you're going to end up testing things you probably don't mean to, such as functionality of the browser itself to compute the styles. Therefor, it's bad practice in many situations.
However, if you do need this, such as when testing a 3rd party JavaScript library against a customer's site, Intern's Leadfoot provides a .execute() method you'll want to use.
Example:
return this.remote // represents the browser
.get('mysite.com') // navigate to a page
.execute( // send a callback to the browser
function (selector) {
var elem = document.querySelector(selector),
result;
// collect some data for analysis...
result = getComputedStyle(elem).zIndex;
return result;
},
['div'] // arguments to send to the remote callback
)
.then(
function (zIndex) {
// analyze the data and make assertions about it...
assert(zIndex > 999);
}
);
Please note: This is awesome but be careful. Most of your test runs inside of Node.js, but the callback to .execute() does not and so it does not have access to any of your previously defined variables, etc.
As for strategies to determine when an element is truly visible to the user, it's very subjective, but getBoundingClientRect() is going to be your friend for determining when one element is overlapping another. There are good techniques here: Determine visibility / real z-index of html elements

Is it possible to use the findbar with a non-browser element?

Is there a way use findbar for non-browser element?
I'm trying adopt findbar to use it on listbox in a prefwindow.
Unfortunately, the <findbar> widget is really meant to be used with a browser element. You can use it with other data if you fake the necessary browser APIs but there is no guarantee whatsoever that it will continue to work in future. In particular, the APIs in question changed from synchronous to asynchonous in Firefox 26 which broke every extension that was implementing them such as Adblock Plus or Stylish.
In the implementation of the <findbar> widget you can see what it currently expects from a browser:
Components.utils.import("resource://gre/modules/Services.jsm");
var fakeBrowser = {
finder: new Finder(),
_lastSearchString: "",
_lastSearchHighlight: false,
currentURI: Services.io.newURI("http://example.com/"),
contentWindow: null,
addEventListener: function() {}
removeEventListener: function() {},
};
This fake browser can be assigned to the findbar.browser property. The important part here is the finder property, normally that's a Finder object defined by Finder.jsm. You would want to implement your own object providing the same API of course.

Watch for a property creation event?

I need to be able to determine when an object is created (not a DOM element -- a JavaScript object).
An answer to this question has some very useful looking code for creating observable properties, so you can have a function fire when a property changes.
In my situation I need to do something when the object/property is created, not an existing property changed, and my limited understanding of such matters did not help me figure out if or how I could use that code to do this after much squinting.
The situation is: page loads a bunch of scripts. Some of the scripts create things that are needed by other scripts, e.g:
ThisStuff = (function () {
// blah blah
return self;
} ());
Some other code needs to initialize this ThisStuff, whenever it's available, which may be after the DOM is done loading. The user doesn't actually need ThisStuff right away, so it's fine for it to happen whenever the script is done loading. So I would like to do something along lines of:
$(document).ready(function() {
wheneverIsAvailable(window,'ThisStuff', function(object) {
object.init(args);
})
});
I realize there are other solutions to this problem (changing script order, or loading scripts on demand) but those are difficult because of the architecture. So I'm only interested in a way to do this versus other solutions. If jQuery offers some such functionality, that's fine also as I'm using it.
You could have a setInterval checking a number of times a second to watch the specific variable. You can check whether it is created using obj.hasOwnProperty(prop). When it is created, you invoke the function, and clear the interval.
It might be dirty but it might also just work fine for you.
Edit: I coded this for you: http://jsfiddle.net/jhXJ2/2/. It also supports passing additional arguments to the function.
window.__intervals = [];
function wheneverIsAvailable(obj, prop, func) {
var id = (Math.random()+"").substring(2);
var args = arguments;
window.__intervals[id] = window.setInterval(function() {
if(obj.hasOwnProperty(prop)) {
window.clearInterval(window.__intervals[id]);
func(Array.prototype.slice.call(args, 3));
// Call function with additional parameters passed
// after func (from index 3 and on)
}
}, 1000/ 50);
}
wheneverIsAvailable(window, 'test', function() {
alert(arguments[0]);
}, 'Woot!');
window.setTimeout('window.test = 123', 1000);
This is a bit far-fetched but it might work.
You would need to use knockoutjs, a javascript library. It's awesome but is built for a slightly different purpose.
Anyways it has a dependentObservable thing which allows to fire up an event whenever a certain value changes. Now I know you want on creation but you can check whether your variable holds any value (other than what you provided initially), if yes then consider it initialize.
Let me know if you think this sounds feasible.

How to code firefox extension which run javascript code in the page's context like firebug does

I know that for safety reasons that this is not easy to achieve, however there would be a way to do so as firebug does...
Please help, would like to invoke some script in the page's context to achieve some effect...
Basically, I would like to achieve two functionality:
1. add jQuery to any web page automatically if not already exist.
2. when open certain address, call a method of that page to auto notify the server. (an ajax functionality of the page)
I have tried to inject on the body, no luck.
tried to get the window object, which however do not have access to call the function.
Will try to change the location to something like: javascript:alert('test inject');
Many thx.
OK, after reading some official documentation and the GreaseMonkey's source, I get the following method which basically works for me.
Hope it will save sb's hour:
var appcontent = document.getElementById("appcontent"); // browser
if (appcontent) {
appcontent.addEventListener("DOMContentLoaded", function (evnt) {
var doc = evnt.originalTarget;
var win = doc.defaultView;
var unsafeWin = win.wrappedJSObject;
// vote.up is the function on the page's context
// which is take from this site as example
unsafeWin.vote.up(...);
}, true);
}
}
Greasemonkey does that. If you are developing your own extension with similar functionality, you can use Components.utils.evalInSandbox.

Categories