Can I remove extra text in the tab name? - firefox

There's a change to the tab name when I receive a notification on social networking sites.
It'll change from Website to 3 Notifications | Website
I'm curious about ways on Firefox I can prevent that sort of change.
Is it possible to filter out certain words from tab names?

You unfortunately cannot prevent tabs from updating the title in any modern browser. The only solution that I've seen, although not ideal, is to use a script to record the initial title of the page and keep the tab updated with that saved value. You can use a greasemonkey script for such a task:
var script = document.createElement("script");
script.textContent = "(" + t.toString() + ")()";
document.body.appendChild(script);
var title = document.title;
var updateTitle = function ()
{
document.title = title;
};
window.setInterval(updateTitle, 0);

The title is usually changed by assigning a new value to the document.title. You can freeze its value after the page is loaded with this user script:
// ==UserScript==
// #name Freeze title page
// #match *://*/*
// #run-at document-idle
// ==/UserScript==
const unsafeDocument = document.wrappedJSObject || document;
let title;
try {
title = unsafeDocument.head.getElementsByTagName('title')[0].innerText;
} catch { }
if (!title) {
title = unsafeDocument.title;
}
Object.defineProperty(unsafeDocument, 'title', {
get() {
return title;
},
set() { },
});
To avoid race condition with other scripts which might change document.title the title is read from <title> tag.
Note that this solution won't work if the title of the page is set to something like 3 Notifications | Website with the <title> element and not via scripts. In such case I have no idea how to do what you want in a generic way. You can hovewer force a manually-defined title on a per URL basis.

Related

Anyone having problems with Greasemonkey #includes not firing?

I write Greasemonkey scripts to do all sorts of automation and screen scraping for my job. I've got a list of items/accounts to work on and I iterated through them pulling data from various web tools.
I trap the document ready event and start my processing from there, and when I'm done I'll load the next page in sequence either with a window.href or just clicking a link to the next page.
Every now and then when the page loads Greasemonkey doesn't run. There's no errors in the consoles and if I just refresh the page it works. It's like the #include directives are failing. I'd say the URL was changing but it's not, and a page refresh starts the script just fine (albeit with me having to stop what I'm doing and hit F5).
Anyone seen this before? Is there anything I can do about it (short of switching to Selenium)?
// ==UserScript==
// #name testG
// #version 1
// #grant none
// #require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// ==/UserScript==
var mySearches = localStorage.getItem('mySearches');
var myResults = localStorage.getItem('myResults');
if (mySearches){
mySearches = JSON.parse(mySearches);
}else{
mySearches = ["one", "two", "three","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39"];
localStorage.setItem('mySearches', JSON.stringify(mySearches));
}
if (myResults){
myResults = JSON.parse(myResults);
}else{
myResults = [];
}
$(document).ready( function() {
var search = $("input[title='Search']");
console.log("mySearches is " + JSON.stringify(mySearches));
var mySearch = mySearches.shift();
myResults.push(mySearch);
localStorage.setItem('myResults', JSON.stringify(myResults));
search.val( mySearch );
if ( mySearches.length < 1){
localStorage.removeItem('mySearches');
alert (myResults);
}else{
myResults.push(mySearch);
localStorage.setItem('mySearches', JSON.stringify(mySearches));
window.location.replace("https://www.google.com");
}
} );//END DOCUMENT READY

How to change the label of widget(Firefox Add-on SDK)

I want to change the label of a widget when user click it, then I write the code looks like this:
var widgets = require("sdk/widget");
var statusBar = widgets.Widget({
id: "patchouliStatus",
label: "Wait Page Loading...",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(){
this.contentURL = "http://www.google.com/favicon.ico";
this.label = "Clicked";
}
});
When I click the widget, the icon has changed, but nothing happen to the label.I move the mouse to the widget and it still show "Wait Page Loading...".Is there a way to dynamically change the label?
Firefox: v27.0.1
Add-on SDK: v1.15
Widget's label is read-only. You must use tooltip attribute to show the user a text on mouse hover, this way:
var widgets = require("sdk/widget");
var statusBar = widgets.Widget({
id: "patchouliStatus",
label: "Wait Page Loading...",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(){
this.contentURL = "http://www.google.com/favicon.ico";
this.tooltip = "Clicked";
}
});
As docs says somewhere in this section -I think it could be more clearly documented-, tooltip value is an "optional text to show when the user's mouse hovers over the widget. If not given, the label is used". Also, examples in that section don't make it clear enough as I think they should.
Ok man thanks for the XPI, change changeLabel function to this, my above was really bugged.
function changeLabel(str){
var DOMWindows = Services.wm.getEnumerator('navigator:browser');
while (DOMWindows.hasMoreElements()) {
var aDOMWindow = DOMWindows.getNext();
var myWidget = aDOMWindow.document.getElementById('widget:jid1-njALX8gXKY872g#jetpack-patchouliStatus');
if (myWidget) {
Services.appShell.hiddenDOMWindow.console.info('myWidget:', myWidget);
myWidget.setAttribute('label', str);
myWidget.setAttribute('tooltiptext', 'tooltip changed');
} else {
Services.appShell.hiddenDOMWindow.console.info('myWidget null:', myWidget);
}
}
}
It also seems that the id of your widget starts with tyour addon id name.
Now I gave you the enumerator function because that goes over all windows and you can add event listener. But really if you just want to target the one that was clicked just get the most recent window, as that will obviously hold the correct window with your widget as we just clicked there and the event listener fires on click.
Change changeLabel to this:
function changeLabel(str){
var aDOMWindow = Services.wm.getMostRecentWindow('navigator:browser');
var myWidget = aDOMWindow.document.getElementById('widget:jid1-njALX8gXKY872g#jetpack-patchouliStatus');
if (myWidget) {
Services.appShell.hiddenDOMWindow.console.info('myWidget:', myWidget);
myWidget.setAttribute('label', str);
myWidget.setAttribute('tooltiptext', 'tooltip changed');
} else {
Services.appShell.hiddenDOMWindow.console.info('myWidget null:', myWidget);
}
}
Also that Services.appShell.hiddenDOMWindow.console.info is just something nice to debug, I left it in there so you can see how it works. It logs to "Browser Console" (Ctrl+Shift+J).
As a final note I used a non-sdk solution by requiring chrome. they advise you not to do that because they want you to use the SDK functions I don't know about SDK but you can use the getEnumerator and recentWindow function by requiring window/utils it looks like:
Read window/utils article here
I'll give you non-sdk solution here but someone will have to help convert it to sdk solution. You can paste this in your code it will work though.
Im not sure how the element is inserted into the dom but I guessed.
var {Cu, Ci} = require('chrome'); //if you want to paste this into scratchpad with with Environemnt set to Browser than dont need this line, this line is for sdk
var DOMWindows = Services.wm.getWindowEnumerator(null);
while (DOMWindows.hasMoreElements()) {
var aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
var myWidget = aDOMWindow.querySelector('#patchouliStatus'); //im not exactly sure how the element is inserted in the dom but im guessing here
if (myWidget) {
myWidget.label = 'rawr';
}
}

Count tabs with same title in Firefox add-on using Add-on SDK

I am trying to count firefox tabs with same specific title (like Google title) on Firefox add-on builder.
I know about
var tabs = require("tabs");
for each (var tab in tabs)
but how to get count number of tabs with same name?
Thank you in advance!
How do you get the titles of the tabs? Is this possible? Once you've worked that out, declare an object for storing title counts, where the title is the property.
ttabs_obj = ttabs_obj || {}; // your retrieved tabs
titles_count = titles_count || {};
ttabs_obj.forEach(function(tab, titles_count){
title = ''; //get title from tab here, replacing characters invalid in property names with '_'
if (!(title in titles_count)) {
titles_count[title] = 0;
}
titles_count[title] += 1;
});
This worked for me:
//Set up namespace
var app={};
app.tabs = require("sdk/tabs");
//Takes an array and returns an object.
//In this case, keys are tab titles and values are tab counts.
app.summarize=function(arr){
return arr.reduce(function(memo,item){
if (typeof memo[item]==='undefined'){
memo[item]=1;
}
else{
memo[item]++;
}
return memo;
},{});
};
//Whenever a tab loads, recalculate and output to console
//Need to enable console logging:
app.tabs.on('ready',function(){
//app.tabs is a pseudo-array. Convert to array
var tabsArr=Array.prototype.slice.call(app.tabs);
var tabsTitles=tabsArr.map(function(tab){
return tab.title;
});
console.log(app.summarize(tabsTitles));
});
The documentation for tabs is here:
https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/tabs
There were two problems: getting tab titles and getting the number of occurrences of each tab title. For getting tab titles, see:
https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/tabs
For getting the number of occurrences of each item in an array, see:
http://jsfiddle.net/cz2SG/
Note that in order to see the console logging you need to enable it:
https://blog.mozilla.org/addons/2013/03/27/changes-to-console-log-behaviour-in-sdk-1-14/

KendoUI PanelBar remember expanded items

I try implement Kendo UI PanelBar (see http://demos.kendoui.com/web/panelbar/images.html) If I open some items (Golf, Swimming) and next click to "Videos Records", I have expanded items. But when I do refresh page (click on some link), all expanded structure is lost.
On KendoUI forum I found, that I can get only possition of selected item and after reload page I must calculate all noded. Is there any way, how can I have expanded items in my situation? If do not need, I don't want to use the html frames.
Best regards,
Peter
Thank you for your answer, was very usefull. I add here code of skeleton of jQuery which remember 1 selected item now. Required add jquery.cookie.js [https://github.com/carhartl/jquery-cookie]
function onSelect(e) {
var item = $(e.item),
index = item.parentsUntil(".k-panelbar", ".k-item").map(function () {
return $(this).index();
}).get().reverse();
index.push(item.index());
$.cookie("KendoUiPanelBarSelectedIndex", index);
//alert(index);
}
var panel = $("#panelbar").kendoPanelBar({
select: onSelect
}).data("kendoPanelBar");
//$("button").click(function () {
// select([0, 2]);
//});
function select(position) {
var ul = panel.element;
for (var i = 0; i < position.length; i++) {
var item = ul.children().eq(position[i]);
if (i != position.length - 1) {
ul = item.children("ul");
if (!ul[0])
ul = item.children().children("ul");
panel.expand(item, false);
} else {
panel.select(item);
}
}
}
// on page ready select value from cookies
$(document).ready(function () {
if ($.cookie("KendoUiPanelBarSelectedIndex") != null) {
//alert($.cookie("KendoUiPanelBarSelectedIndex"));
var numbersArray = $.cookie("KendoUiPanelBarSelectedIndex").split(',');
select(numbersArray);
}
else {
// TEST INIT MESSAGE, ON REAL USE DELETE
alert("DocumenReadyFunction: KendoUiPanelBarSelectedIndex IS NULL");
}
});
The opening of the panels happens on the client. When the page is refreshed, the browser will render the provided markup, which does not include any additional markup for the selected panel.
In order to accomplish this, you will need to somehow store a value indicating the opened panel. The easiest way to accomplish this would be with a cookie (either set by JavaScript or do an AJAX call to the server).
Then, when the panelBar is being rendered, it will use the value in the cookie to set the correct tab as the selected one.
You can use this block to work withe the selected. in this example, i am just expanding the panel item. You can do other things such as saving panel item in your dom for later use or may be saving it somewhere to use it later:
var panelBar = $("#importCvPanelbar").data("kendoPanelBar");
panelBar.bind("select", function(e) {
var itemId = $(e.item)[0].id;
panelBar.expand(itemId);// will expand the selected one
});

firefox addon page-mod - when url doesn't match

I want to be able to activate a widget if a url matches some pattern, but the problem is I also want to disable the widget when page-mod rule doesn't match the url.
So if I have few tabs open and if I switch between them I should be able to somehow disable the widget if an active tab's url doesn't match the rule, or in other case activate it. The state of widget(on/off) should be changed on loading pages and switching through tabs.
I've been struggling with this for a while and still haven't found a solution.
This is where I'm at right now:
// Activates on matching one of the site domains, but I also want to deactivate
// it when it does not match
var pageMod = require("page-mod");
pageMod.PageMod({
include: ["*.site1.com","*.site2.com"],
onAttach: function() {
alert("Widget activated!");
});
});
Thank you for any help!
If I understand correctly what you are trying to do then page-mod is the wrong solution - you simply want to listen to the active tab. Use tabs module for that, listen to ready (new URL loaded) and activate (active tab changed) events:
var tabs = require("tabs");
tabs.on("ready", function(tab)
{
if (tab == tabs.activeTab)
updateActiveTab(tab);
});
tabs.on("activate", function(tab)
{
updateActiveTab(tab);
});
Your updateActiveTab() function would need to check tab.url and activate or deactivate the widget then. If you want to use patterns for that like the ones you specify for page-mod then you need to use the internal match-pattern module, like this:
var {MatchPattern} = require("match-pattern");
var patterns = [
new MatchPattern("*.site1.com"),
new MatchPattern("*.site2.com")
];
function updateActiveTab(tab)
{
var matches = false;
for (var i = 0; i < patterns.length; i++)
if (patterns[i].test(tab.url))
matches = true;
if (matches)
activateWidget();
else
deactivateWidget();
}
But of course you can just use a regular expression or something like this to test tab.url, you don't have to use the match-pattern module.
Disclaimer: The code examples are only there to make the approach easier to understand, they haven't been tested.

Resources