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

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.

Related

Chrome Extension

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.

Add new CSS properties in Chromium to be used through V8 Javascripting engine

I am using chrome V8 scripting engine.
I want to add new CSS properties to V8/Chrome to be interpreted by my application when integrated with Chromium and V8.
I am trying following code:-
Object.defineProperty(CSSStyleDeclaration.prototype, "myproperty", {
get: function () {
return (this.getPropertyValue('-my-property'));
},
set: function (myproperty) {
return this.setProperty("-my-property", myproperty);
},
});`
element.style.myproperty = 'customvalue';
console.log(element.style.myproperty);
Output:- Empty string
But this code does not work and 'myproperty' is not set.
If instead of '-my-property', I use the name prefixed with double hyphen '--my-property', it works fine.
But I want to add new properties with single prefix.
I googled and found that one option is that I need to get complete chromium code, add my new CSS property and check the code:-
https://www.chromium.org/blink/runtime-enabled-features
As this is very lengthy process, I just want to know if there is any other option to add a new CSS property and get/set it through Element.style.prop. For example is there any possibility through any of the following:-
CSS Polyfills.
Chrome Extensions.
Extending V8 by making it aware of new properties( I searched and found that for this option I have to run V8 in embedded mode and provide the complete C++ implementation. Just want to know if it is possible to provide implementation for only new properties and reused the existing ones.).
Thanks in advance.

Is there an equivilant of phpinfo for jquery?

server side background, getting deeper and deeper into client side.
I've got a site with a lot of legacy that I'm new to, and I'm just trying to get a handle on how things are working/what's available.
Is there a way to have jquery tell me(for a page/pages) all its current info and any plugins it can/is use/ing, similar to what phpinfo does?
Some proof of concept how you can get names for all plugins
var plugins = (function() {
var plugins = [];
for(var plugin in jQuery.fn) {
plugins.push(plugin)
}
return plugins;
}());
var filterValue = ['constructor', 'init', 'add', 'parents'] // // you must add all standard methods here
filterValue.forEach(function(value) {
var position = function(value) {
return plugins.indexOf(value);
}
while(position(value) >= 0) {
plugins.splice(position(value), 1)
}
})
console.log(plugins)
You can use the following for jQuery
console.log( jQuery.fn.jquery );
To answer your question directly, No jQuery does not have a mechanism that lists installed plug-ins.
jQuery does not keep such a registry of installed plugins. The jQuery plugin mechanism is to just add a method to the jQuery prototype (right along-side all the other jQuery methods). So, there's no separate list of which methods have been added by some outside agent (e.g. a plug-in). In addition, there's no one-to-one correspondence between methods and a particular plug-in as a single plug-in could add multiple methods.
It would be possible to create a master list (for any specific jQuery version) of what methods are there by default and then enumerate a jQuery object to find out which methods have been added since then, but you'd have to create that master list ahead of time and store it or create the master list immediately after jQuery was loaded before any plug-ins were loaded.
You can always test to see if any specific jQuery plug-in is loaded by just checking to see if any of its signature methods are available on a jQuery object.
So, if you really just wanted to know which of 10 plugins happen to be available in any given page, you could write a quick function that would test for each of the 10 plugins (by looking for the existence of known methods in those plugins) and would return a list of the ones installed, but this has to be done with specific knowledge of each plugin as there is no "generic plugin identification mechanism" since a plug-in is nothing more than a piece of code that adds methods to the jQuery prototype. It doesn't actually have any identity of its own.

Printing a (part of) webpage with Javascript

I am aware of two ways of calling the "print" dialog of browser (I used the Search, of course):
document.print()
document.execCommand('print', false, null)
What is the difference between them? Support across browsers? Papers, docs or standards? Which is more correct thing to use?
Another question: what is the most straight way to print given part of a webpage? I know we can create new window or iframe to call any of two print methods above. Which one has less pitfalls?
I've tested different ways of printing part of webpage across browsers:
Chrome, Firefox, Opera (12 and new), IE11, 10, 9 and 8. I've tried to create new window, new iframe, or use existing iframe on the page. And then tried .print() and .execCommand('print').
Note: Keep in mind that .print() is called on window, and .execCommand() is called on document.
Code used for testing can be found here
Correct me if my testing code is wrong, I just wanted to find the clearest way to do the job. My conclusions:
Opera 12 can not print part of a webpage (?)
IEs don't print() iframes and windows, except current window.
Calling print() on documents inside iframes or created windows in IEs breaks the print() on current document. Be careful!
jQuery plugin printThis uses tricks for IE to do the job, and it just works. The only exception is Opera 12. By the way, this plugin uses print().
execCommand('print') works almost everywhere and with any approach (iframes, window). It's not supported by Firefox though.
execCommand() returns false if call was unsuccessful, so if you don't want to use plugins and magic tricks, create window or iframe, call execCommand('print') and if it returns false, call print().
One more thing:
Creating an iframe is tricky: you can't access its window or document directly (yes, you have ContentDocument property, which behaves differently across browsers). You should name it and then call window.frames[name] to get window object from that iframe. Do not try to call window.frames(id) - it will return the iframe.
That last method mentioned in the accepted answer, then, ends up looking like this:
iframe = document.getElementById('iframe-id');
var printed = iframe.contentWindow.document.execCommand('print', false, null);
if (!printed) window.print();
alternative:
try {
iframe = document.getElementById('iframe-id');
iframe.contentWindow.document.execCommand('print', false, null);
}
catch(e) {
window.print();
}
similar method used by printThis
if (document.queryCommandSupported("print")) {
$iframe[0].contentWindow.print();
$iframe[0].contentWindow.document.execCommand("print", false, null);
} else {
$iframe[0].contentWindow.focus();
$iframe[0].contentWindow.print();
}
You can use the combination of window.open and execComand (saveas
exemple:
<script type= "text/javascript">
function saveas() {
var oPrntWin = window.open("","_blank","width=1,height=1,left=1,top=1,menubar=yes,toolbar=yes,resizable=yes,location=no,scrollbars=yes");
oPrntWin.document.open();
oPrntWin.document.write(editeur.innerHTML);
oPrntWin .document.execCommand("SaveAs",true,"C:\\My Documents\\Saved Content.html");
oPrntWin.document.close();
}
</script>
editeur.html is a part of my document
you can do same for your frame
replace the writting in a new Window by the property "src" for the body

Is saving elements as object properties good practice?

I'm writing a small JavaScript framework for fun and possible implementation similar to backbone(hence the tag). I've started saving elements as object properties, as shown below. I'm not sure if I've seen this done, so I was curious if this causes any issues.
Similarly, If the module depends on other modules I list those at the top of the object in the form of....another object.
I wanted a way to list dependencies ( page elements or JavaScript modules ) and detect any issues up front. This has similar ( not same ) benefits as dependency injection.
This is a specific question on this code review post which explains a bit further on how the framework works.
/*MUserTry
**
**
**
*/
$A.modelAjax({
Name: 'MUserTry',
S: {
DynSma: SDynSma,
DynTwe: SDynTwe,
DynArc: SDynArc,
AniFlipPage: SAniFlipPage,
ClientStorage: SClientStorage
},
E: {
but: $A('#ut_but')[0]
},
J: {
box: $('#ut_box')
},
init: function () {
var pipe = {},
this_hold = this;
this.J.box.draggable();
this.E.but.addEventListener("click", function () {
pipe = $A.definePipe(this_hold.Name);
$A.ajaxMachine(pipe);
}, false);
},
pre: function (pipe) {
pipe.page.email = this.e_button.getAttribute('data-email');
pipe.proceed = true;
},
post: function (pipe) {
this.S.ClientStorage.setAll(pipe.server.smalls);
this.S.DynSma.run(pipe.server.smalls);
this.S.DynArc.run(pipe.server.arcmarks);
this.S.DynTwe.run(pipe.server.tweets);
this.S.AniFlipPage.run('ma');
},
finish: function (pipe) {
$A.log(pipe);
}
});
Ok first off let me offer the obligatory "you'll never get a better wheel by re-inventing the wheel" warning. Whatever you're trying to accomplish, you're almost certainly going to be more successful with it if you use an existing library. And even if there is good cause for you to make your own, it would still benefit you immensely to at least look at existing libraries.
But ... maybe you're just having fun with this project, and looking at other projects isn't fun so you're not doing it. Fair enough.
In any case, if you do look at Backbone, you'll find that this practice is core to the Backbone View class. Every View in Backbone has an "el" and "$el" property, which refer to the raw DOM element for the view and the jQuery-wrapped version of that element.
Backbone has no real performance issues with this because variables/properties in JS are just pointers; in other words, when you set the property of an object to an element, you aren't duplicating that element, you're just adding a reference to it (to put it another way, it's more like you're an A tag rather than a whole new document).
The one time Backbone does have a problem though (and your framework will too) is with stale references. In other words, if you just remove element X from the page, the browser will stop using memory for it (eventually, via garbage collection). But if there is an object out there which points to that element, it won't get garbage-collected, because anything with a reference isn't "garbage".
So, the main thing you have to watch out for is making sure that these objects either:
A) get deleted whenever their elements do, or
B) get rid of their references (eg. delete obj.reference) when their elements get deleted
If you don't do that, things will still probably work just fine ... until you use it on a page with lots of elements being created/deleted, at which point Firefox will start popping up "this script took way too long to run, are you really sure you want to be doing this?" messages.

Categories