SIFR3 & jQuery for a styleswitcher script, need a last tip please! ;o) - sifr

I spent a lot of time trying to configure a styleswitcher script that replace my html background and css from one color to another, I got some texts using SIFR3, mainly h1, h2 tahs and h2 a: links...
My only problem is that when I'm switching, the flash text doesnt take the color change into consideration, I've tried to play with rollBack but I'm out of luck.
I found an interessant solution here :
function changeColor(hexValue) {
var css = '.sIFR-root { color: ' + hexValue + '; }';
for (var i = 0; i < sIFR.replacements['h1'].length; i++) {
sIFR.replacements['h1'][i].changeCSS(css);
}
for (var i = 0; i < sIFR.replacements['h2'].length; i++) {
sIFR.replacements['h2'][i].changeCSS(css);
}
}
// after switching stylesheet:
changeColor('#FF9900');
It works for h1, h2 but not for my h2 a: links...
Can you tell me how to adjust this?? It would be really really nice.
Right now when firing this function, my links just turn in their old html look with underline text decoration. Thanks !!

You need to pass in the new (or existing) styles for the a as well.

Related

jQuery UI sortable drag initiation is slow when container has hidden items

I have an unordered 'source' list that can contain up to around 1,000 list items. I want to be able to drag the items from the source list into a connected 'destination' list. I have everything working great until my source list gets filtered. I'm using the jquery quicksearch plugin to filter (search) my source list. The filter is accomplished by setting 'display:none;' on items that don't match the search.
When 1..n items in my source list are hidden, the drag operation is not fluid when initiated. Meaning, I click on the item I want to drag, move my mouse around the screen, but the item I'm dragging does not appear under my cursor until about a full second after I've initiated the drag.
For diagnosis, I've slimmed down my use case to just one list that I want to sort. I've completely eliminated the use of quicksearch by just hard coding half of my list items as hidden. I'm still able to reproduce the 'non-fluid' behavior. My example is here:
http://pastebin.com/g0mVE6sc
If I remove the overflow style from the list in my example, the performance is a little better, but still slower than I'd hope to see.
Does anyone have any suggestions for me before I start considering other options?
Thanks in advance.
As you can see on this jsferf example, calculating outerWidth()/outerHeight() (this is what the plugin does - see below) for hidden elements (with display none) is terribly slower than for visible elements, wether it is achieved by a style attribute or a class.
The only way I have found to bypass this and still achieve the same result is to set the height for the elements to hide to zero, instead of working with the display property, whether using the style atttibute or a class:
<li style="height: 0;">b</li>
<li class="hidden">b</li>
.hidden { height: 0 }
DEMO (with class) - DEMO (with style attr)
What's happenning with sortable when dragging an element ?
When starting dragging, the plugin refreshes the list of all items and recalculates positions of all elements. The plugin actually gets outerWidth and outerHeight:
_mouseStart: function(event, overrideHandle, noActivation) {
...
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
this.refreshPositions();
...
}
refreshPositions: function(fast) {
...
for (var i = this.items.length - 1; i >= 0; i--) {
var item = this.items[i];
...
if (!fast) {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
...
return this;
},​
If you still want to use display:none, this is a simple fix to the jQuery UI source specified in Didier's answer:
if (!fast) {
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
}
else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
}
This is my very first post on stackoverflow, so do let me know if I messed something up.
I was also having a similar problem, but with hidden drop containers instead of sortable items. Here is my solution applying Jordan's answer to both sortable items and their containers and simply replacing the relvent method.
$.ui.sortable.prototype.refreshPositions = function(fast) {
//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
if(this.offsetParent && this.helper) {
this.offset.parent = this._getParentOffset();
}
for (var i = this.items.length - 1; i >= 0; i--){
var item = this.items[i];
//We ignore calculating positions of all connected containers when we're not over them
if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
continue;
var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
if (!fast) {
/********** MODIFICATION ***********/
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
} else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
/********** END MODIFICATION ***********/
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
if(this.options.custom && this.options.custom.refreshContainers) {
this.options.custom.refreshContainers.call(this);
} else {
for (var i = this.containers.length - 1; i >= 0; i--){
/********** MODIFICATION ***********/
if (this.containers[i].element.css('display') == 'none') {
this.containers[i].containerCache.left = 0;
this.containers[i].containerCache.top = 0;
this.containers[i].containerCache.width = 0;
this.containers[i].containerCache.height = 0;
} else {
var p = this.containers[i].element.offset();
this.containers[i].containerCache.left = p.left;
this.containers[i].containerCache.top = p.top;
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
}
/********** END MODIFICATION ***********/
};
}
return this;
};
I came across with the same problem...
I've searched for a solution, but it seems there is no solution to the jquery problem, only some workaround...
I didn't found either a solution, just another workaround.
In my case I just created a general method to to a search in a sortable list, where on keyup, the code goes and do a find on every element in the list and was hiding it by fadeout if didn't match the value.
This was working very well, but when you have hundreds of items in a list, the of hidden gets big enough to trigger the slow effect on the drag&drop.
My solution was to reorder the list, bringing to the top the matched items..
Just remove and appendTo again...
This way I don't have problems with the hidden elements :)
Sorry this was no solution, but just another workaround..
Regards
More recently I came accross with this issue again... and found that my workaround was not the best solution anymore. Since the issue is the height... I've just create a CSS class with
.hidden {display: block; line-height:0; height: 0; overflow: hidden; padding: 0; margin: 0; }
and instead of setting the element hidden with just add this class and remove it to show/hide the element..
Regards,
AP
I got the same issue today with sortable + draggable table rows.
The solution was simple : use visibility:collapse instead of display:none and removing the jQuery hide/show function for the hidden lines did the trick. It's a lot faster now.
Hope I will help.

Styling Panels of a Firefox Addon

So I created a Widget that the user clicks on and it opens up a Panel, I have a couple of Questions about the panel.
How Do I style the Panels borders, background color, etc..? I'm including an HTML file in it's contentURL, can I add CSS to alter it? If so how do I select it via CSS?
I also want to add a Close Button and keep the panel open always unless they click the close button.
On second thought, for the Add-on i'm trying to program it might be better if I make a window, is a window pretty stylable so I can make it look cooler?
Thanks for any help.
I don't think you can style panel borders. The panel border styles depend on the operating system and you cannot touch them. You can only really influence the inner area of the panel, effectively you get an iframe inside the panel that you can play with. E.g. to change the background your panel can contain:
<style type="text/css">
html
{
background-color: red;
}
</style>
You cannot, the panel is not a real HTML object, but a XUL window with an iframe or HTML inside.
I believe since Firefox 30 you can access to this object, you can read:
Avoid panel to autoHide in Firefox extension
Of course it's a kind of hack, looks like Mozilla is not really "open" ^^
I was able to modify the border of the panel:
/*run this first*/
var win = Services.wm.getMostRecentWindow('navigator:browser');
var panel = win.document.createElement('panel');
var screen = Services.appShell.hiddenDOMWindow.screen;
var props = {
noautohide: true,
noautofocus: false,
level: 'top',
style: 'padding:15px; margin:0; width:150px; height:200px; background-color:steelblue;border-radius:15px'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
win.document.querySelector('#mainPopupSet').appendChild(panel);
panel.addEventListener('dblclick', function () {
panel.parentNode.removeChild(panel)
}, false);
panel.openPopup(null, 'overlap', screen.availLeft, screen.availTop);
So if you know the panel of your id just do this:
var sss = Cc['#mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
var css = '';
css += '#YourPanelIdHere { border-radius:15px; opacity:.5; border:1px solid red; }';
var cssEnc = encodeURIComponent(css);
var newURIParam = {
aURL: 'data:text/css,' + cssEnc,
aOriginCharset: null,
aBaseURI: null
}
var cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI);
sss.loadAndRegisterSheet(cssUri, sss.USER_SHEET);
//sss.unregisterSheet(cssUri, sss.USER_SHEET);
That will style your panel. You don't have to use panel id in the style sheet, just anything that target your panel will do.

Rails & prototype - insert a div and position it

For my rails site, when somebody attempts to delete an item, I wish to pop up a custom div (as opposed to a javascript alert box) asking for confirmation before doing so.
At the moment, the way that I am doing this, is that clicking on the delete link will call a function (in application_helper.rb) as below:
def show_delete_box(object, name)
update_page do |page|
page.insert_html :before, "content", render(:partial => "shared/generic_delete_box", :locals => { :object => object, :name => name })
page << "$('delete_box').Center"
end
end
The rendered partial is intended to appear in the middle of the screen, and the locals are what will be used to create the appropriate delete link in the div.
However, my problem here is attempting to make it appear in the middle of the screen. I've always massively suffered with javascript and this is driving me insane as well. (Ya, I've tried to use firebug as well, but those long lines of javascript mean nothing to me. >.< )
The 2nd line in my update_page block is meant to call a javascript function that center's the inserted div.
The function that I've written and stuck into my application.js file is as follows:
Element.Center = function(element) {
var vH, vW, eH, eW;
var d = Element.getDimensions(element);
eH = d.height;
eW = d.width;
vH = document.viewport.getHeight();
vW = document.viewport.getWidth();
var y = (vH/2) - (eH/2) + "px";
var x = (vW/2) - (eW/2) + "px";
var style = { position: 'absolute'; top: y + 'px'; left: x + 'px'};
element.setStyle(style);
}
What happens when I click, is that the partial div is created, and inserted into the page at the appropriate spot. However it is not being positioned in anyway that I can tell.
So, I'm looking for help! What am I doing wrong in the javascript function, or in attempting to call the function?
Thanks in advance!
--edit--
I'm not sure if this will help... This is the relevant CSS code for delete_box.
#delete_box {
background-color: green;
border: 5px solid #999;
padding: 15px;
width: 600px;
}
So the CSS doesn't touch the positioning in any way.
There are several prebaked libraries out there that do just what you're saying, might be easier than writing it yourself. Redbox is a rails plugin that works in Prototype, for one example.

Problems with sIFR Implementation - need help

I have 3 main problems with my sifr implementation . Has taken me 2 days of trying to fix without any tangible results.
cant get navigation lists to work in firefox. I have followed all suggested fixes for this, including setting the replace on a higher level element - still doesnt work! here is my current code:
sIFR.replace(louisiana, {
selector: 'ul.tabs3 li'
,css: [ '.sIFR-root { font-size: 20px;}', 'a { color: #cc3333; text-decoration: none; padding:0px 8px; margin: 0;}', 'a:link { color: #555555; }', 'a:hover { color: #cc3333; }' ]
,thickness: 50
,wmode: 'transparent'
});
it works in safari, but clicking on each navigational link is like an exercise in patience - extremely slow to load.
cant get content in jquery tabs to losd. only first tab works. I have read the proposed fixes about using something like the code below on the scrolling div - doesnt work for me.
position: absolute;
left: -10000px;
i have also come across a solution which says to use a call back function with my tab code. I have no idea how to do that. here is my tab code:
$(function() {
$("ul.tabs3").tabs("div.panes3 > div",
{ history: true,
current: 'current',
// event:'mouseover',
effect: 'fade'
});
});
</script>
I cant get the code to exclude certain elements to be replaced to work. at the top of my config file I have:
parseSelector.pseudoClasses = {
'not': function(nodes, selector) {
var result = [];
each: for(var i = 0, node; i < nodes.length; i++) {
node = nodes[i];
var ignore = parseSelector(selector, node.parentNode);
for(var j = 0; j < ignore.length; j++) {
if(ignore[j] == node) continue each;
}
result.push(node);
}
return result;
}
}
and the replace code is :
sIFR.replace(louisiana, {
selector: "h2, div:not(.filter) h2"
,css: '.sIFR-root { font-size: 30px; color: #444444; }'
,thickness: 70
,forceSingleLine: true
,wmode: 'transparent'
});
I really need help with this - have been going for 2 days and totally clueless at this point.
sIFR shouldn't cause any slowdowns if you click on a link inside a sIFR movie, not sure what's up there. The selector looks good, but you might want to try without the transparency.
Wouldn't immediately know how to fix the tab thing either. sIFR is, by nature, hard to make work with tab interfaces. It's not really designed for menus either.
When you use the selector h2, div:not(.filter) h2 you're replacing all <h2>s and those not in div.filter. Try removing the h2, bit and see if that helps.

sIFR and changing the background

Hey all, I'm using this code to change my sIFR (version 3) H1 and H2 tags dynamically (thanks to Mark Wubben for the code), but I need to change my H2 background color in the same function.. Can anyone help me get the code working? Apparently sIFR and changeCSS doesn't work for background colors..
function changeColor(hexValue) {
var css1 = '.sIFR-root { color: '+ hexValue +'; }';
var css2 = '.sIFR-root { color: #080808; background-color: '+hexValue+'; }';
for (var i = 0; i < sIFR.replacements['h1'].length; i++) {
sIFR.replacements['h1'][i].changeCSS(css1);
};
for (var i = 0; i < sIFR.replacements['h2'].length; i++) {
sIFR.replacements['h2'][i].changeCSS(css2);
};
};
sIFR only supports a background color for the entire Flash movie, and this can't be changed later.
Your best bet is to enable transparency for the replacements, and set the background color on the HTML element replaced by sIFR (the <h2>). You're advised however to use transparency only when strictly necessary, and please keep in mind that transparency is largely unsupported on Linux. It will fall back to the specified background-color instead.

Resources