I'm trying to set some css to the CKEDITOR 4 programmaticly.
This because when a new user comes to the editor i would like to identify him with a different color.
Within the registered style array i do see the added row(CKEDITOR.stylesSet.registered.user0). but the style isn't visible in the editor?
Why is this? and what am i doing wrong?
setStyling: function(editor)
{
var userIds = this.getUserIds(editor);// returns an array with id's
var colors = editor.config.Colors; // Colors are set in the config
for(var i = 0; userIds.length > i; i++)
{
if(CKEDITOR.stylesSet.get('user' + i) === null)
{
CKEDITOR.stylesSet.add('user' + i, [
{ name: 'userColor', element: 'span[data-uid="' + userIds[i] +'"]', styles: { color: colors[i] }}
]);
}
}
}
Another aproach did the job:
var $head = $("iframe").contents().find("head");
var $style = $("iframe").contents().find("#uniqueStyle");
var css = "";
for(var i = 0; userIds.length > i; i++)
{
css += "span[data-uid='" + userIds[i] + "'] { color: " + colors[i] + "; } ";
}
if($style)
{
$style.remove();
}
$('<style id="uniqueStyle" type="text/css"></style>')
.html(css)
.appendTo($head);
Related
How and Why does the polyfill can work?
w.matchMedia = w.matchMedia || (function( doc, undefined ) {
var bool,
docElem = doc.documentElement,
refNode = docElem.firstElementChild || docElem.firstChild,
// fakeBody required for <FF4 when executed in <head>
fakeBody = doc.createElement( "body" ),
div = doc.createElement( "div" );
div.id = "mq-test-1";
div.style.cssText = "position:absolute;top:-100em";
fakeBody.style.background = "none";
fakeBody.appendChild(div);
return function(q){
div.innerHTML = "<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";
docElem.insertBefore( fakeBody, refNode );
bool = div.offsetWidth === 42;
docElem.removeChild( fakeBody );
return {
matches: bool,
media: q
};
};
}( w.document ));
paulirish alse implement it in another similar way, https://github.com/paulirish/matchMedia.js/blob/master/matchMedia.js
the key code is as following
info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
styleMedia = {
matchMedium: function(media) {
var text = '#media ' + media + '{ #matchmediajs-test { width: 1px; } }';
// 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
if (style.styleSheet) {
style.styleSheet.cssText = text;
} else {
style.textContent = text;
}
// Test if media query is true or false
return info.width === '1px';
}
};
Both work the same way.
They just inject the media that you pass as a parameter, and use it to aply a predefined style (a width of 42 px for the first, and of 1px for the second),
If the width of the element is really the predefined one, the media is working and the function evaluates to true
clip-path:shape() does not seem to work in IE (no surprise) and Firefox (a bit surprised). Is there a way to test for clip-path support? I use modernizr. (By the way, I know I can get this to work using SVGs and -webkit-clip-path:url(#mySVG))
You asked this a while ago, and to be honest, I'm not sure if Modernizr has yet to add support for this, but it's pretty easy to roll your own test in this case.
The steps are:
Create, but do not append, a DOM element.
Check that it supports any kind of clipPath by checking the JS style attribute of the newly created element (element.style.clipPath === '' if it can support it).
Check that it supports CSS clip path shapes by making element.style.clipPath equal some valid CSS clip path shape.
Of course, it's a little more complex than that, as you have to check for vendor-specific prefixes.
Here it is all together:
var areClipPathShapesSupported = function () {
var base = 'clipPath',
prefixes = [ 'webkit', 'moz', 'ms', 'o' ],
properties = [ base ],
testElement = document.createElement( 'testelement' ),
attribute = 'polygon(50% 0%, 0% 100%, 100% 100%)';
// Push the prefixed properties into the array of properties.
for ( var i = 0, l = prefixes.length; i < l; i++ ) {
var prefixedProperty = prefixes[i] + base.charAt( 0 ).toUpperCase() + base.slice( 1 ); // remember to capitalize!
properties.push( prefixedProperty );
}
// Interate over the properties and see if they pass two tests.
for ( var i = 0, l = properties.length; i < l; i++ ) {
var property = properties[i];
// First, they need to even support clip-path (IE <= 11 does not)...
if ( testElement.style[property] === '' ) {
// Second, we need to see what happens when we try to create a CSS shape...
testElement.style[property] = attribute;
if ( testElement.style[property] !== '' ) {
return true;
}
}
}
return false;
};
Here's a codepen proof-of-concept: http://codepen.io/anon/pen/YXyyMJ
You can test with Modernizr.
(function (Modernizr) {
// Here are all the values we will test. If you want to use just one or two, comment out the lines of test you don't need.
var tests = [{
name: 'svg',
value: 'url(#test)'
}, // False positive in IE, supports SVG clip-path, but not on HTML element
{
name: 'inset',
value: 'inset(10px 20px 30px 40px)'
}, {
name: 'circle',
value: 'circle(60px at center)'
}, {
name: 'ellipse',
value: 'ellipse(50% 50% at 50% 50%)'
}, {
name: 'polygon',
value: 'polygon(50% 0%, 0% 100%, 100% 100%)'
}
];
var t = 0, name, value, prop;
for (; t < tests.length; t++) {
name = tests[t].name;
value = tests[t].value;
Modernizr.addTest('cssclippath' + name, function () {
// Try using window.CSS.supports
if ('CSS' in window && 'supports' in window.CSS) {
for (var i = 0; i < Modernizr._prefixes.length; i++) {
prop = Modernizr._prefixes[i] + 'clip-path'
if (window.CSS.supports(prop, value)) {
return true;
}
}
return false;
}
// Otherwise, use Modernizr.testStyles and examine the property manually
return Modernizr.testStyles('#modernizr { ' + Modernizr._prefixes.join('clip-path:' + value + '; ') + ' }', function (elem, rule) {
var style = getComputedStyle(elem),
clip = style.clipPath;
if (!clip || clip == "none") {
clip = false;
for (var i = 0; i < Modernizr._domPrefixes.length; i++) {
test = Modernizr._domPrefixes[i] + 'ClipPath';
if (style[test] && style[test] !== "none") {
clip = true;
break;
}
}
}
return Modernizr.testProp('clipPath') && clip;
});
});
}
})(Modernizr);
Check this codepen to see it in action.
I'm working on a website for a school project, I'm using a template called quantua. If you go to live demo of the template ( http://www.templatesjoomla.net/index.php/joomla3-x/244-quantua-joomla-3-x.html ), you can see that when resizing the browser window the image shrinks so much that a black background appears. I don't want it to do that, how can the resizing be achived like on this (http://www.websitetemplatesonline.com/free-template/progress-business.html) template? I played with css quite a bit, but i failed, so I guess it has to do with javascript?
heres the javascript code
(function($) {
var NivoSlider = function(element, options){
// Defaults are below
var settings = $.extend({}, $.fn.nivoSlider.defaults, options);
// Useful variables. Play carefully.
var vars = {
currentSlide: 0,
currentImage: '',
totalSlides: 0,
running: false,
paused: false,
stop: false,
controlNavEl: false
};
// Get this slider
var slider = $(element);
slider.data('nivo:vars', vars).addClass('nivoSlider');
// Find our slider children
var kids = slider.children();
kids.each(function() {
var child = $(this);
var link = '';
if(!child.is('img')){
if(child.is('a')){
child.addClass('nivo-imageLink');
link = child;
}
child = child.find('img:first');
}
// Get img width & height
var childWidth = (childWidth === 0) ? child.attr('width') : child.width(),
childHeight = (childHeight === 0) ? child.attr('height') : child.height();
if(link !== ''){
link.css('display','none');
}
child.css('display','none');
vars.totalSlides++;
});
// If randomStart
if(settings.randomStart){
settings.startSlide = Math.floor(Math.random() * vars.totalSlides);
}
// Set startSlide
if(settings.startSlide > 0){
if(settings.startSlide >= vars.totalSlides) { settings.startSlide = vars.totalSlides - 1; }
vars.currentSlide = settings.startSlide;
}
// Get initial image
if($(kids[vars.currentSlide]).is('img')){
vars.currentImage = $(kids[vars.currentSlide]);
} else {
vars.currentImage = $(kids[vars.currentSlide]).find('img:first');
}
// Show initial link
if($(kids[vars.currentSlide]).is('a')){
$(kids[vars.currentSlide]).css('display','block');
}
// Set first background
var sliderImg = $('<img class="nivo-main-image" src="#" />');
sliderImg.attr('src', vars.currentImage.attr('src')).show();
slider.append(sliderImg);
// Detect Window Resize
$(window).resize(function() {
slider.children('img').width(slider.width());
sliderImg.attr('src', vars.currentImage.attr('src'));
sliderImg.stop().height('auto');
$('.nivo-slice').remove();
$('.nivo-box').remove();
});
//Create caption
slider.append($('<div class="nivo-caption"></div>'));
// Process caption function
var processCaption = function(settings){
var nivoCaption = $('.nivo-caption', slider);
if(vars.currentImage.attr('title') != '' && vars.currentImage.attr('title') != undefined){
var title = vars.currentImage.attr('title');
if(title.substr(0,1) == '#') title = $(title).html();
if(nivoCaption.css('display') == 'block'){
setTimeout(function(){
nivoCaption.html(title);
}, settings.animSpeed);
} else {
nivoCaption.html(title);
nivoCaption.stop().fadeIn(settings.animSpeed);
}
} else {
nivoCaption.stop().fadeOut(settings.animSpeed);
}
}
//Process initial caption
processCaption(settings);
// In the words of Super Mario "let's a go!"
var timer = 0;
if(!settings.manualAdvance && kids.length > 1){
timer = setInterval(function(){ nivoRun(slider, kids, settings, false); }, settings.pauseTime);
}
// Add Direction nav
if(settings.directionNav){
slider.append('<div class="nivo-directionNav"><a class="nivo-prevNav">'+ settings.prevText +'</a><a class="nivo-nextNav">'+ settings.nextText +'</a></div>');
// Hide Direction nav
if(settings.directionNavHide){
$('.nivo-directionNav', slider).hide();
slider.hover(function(){
$('.nivo-directionNav', slider).show();
}, function(){
$('.nivo-directionNav', slider).hide();
});
}
$('a.nivo-prevNav', slider).live('click', function(){
if(vars.running) { return false; }
clearInterval(timer);
timer = '';
vars.currentSlide -= 2;
nivoRun(slider, kids, settings, 'prev');
});
$('a.nivo-nextNav', slider).live('click', function(){
if(vars.running) { return false; }
clearInterval(timer);
timer = '';
nivoRun(slider, kids, settings, 'next');
});
}
// Add Control nav
if(settings.controlNav){
vars.controlNavEl = $('<div class="nivo-controlNav"></div>');
slider.after(vars.controlNavEl);
for(var i = 0; i < kids.length; i++){
if(settings.controlNavThumbs){
vars.controlNavEl.addClass('nivo-thumbs-enabled');
var child = kids.eq(i);
if(!child.is('img')){
child = child.find('img:first');
}
if(child.attr('data-thumb')) vars.controlNavEl.append('<a class="nivo-control" rel="'+ i +'"><img src="'+ child.attr('data-thumb') +'" alt="" /></a>');
} else {
vars.controlNavEl.append('<a class="nivo-control" rel="'+ i +'">'+ (i + 1) +'</a>');
}
}
//Set initial active link
$('a:eq('+ vars.currentSlide +')', vars.controlNavEl).addClass('active');
$('a', vars.controlNavEl).bind('click', function(){
if(vars.running) return false;
if($(this).hasClass('active')) return false;
clearInterval(timer);
timer = '';
sliderImg.attr('src', vars.currentImage.attr('src'));
vars.currentSlide = $(this).attr('rel') - 1;
nivoRun(slider, kids, settings, 'control');
});
}
//For pauseOnHover setting
if(settings.pauseOnHover){
slider.hover(function(){
vars.paused = true;
clearInterval(timer);
timer = '';
}, function(){
vars.paused = false;
// Restart the timer
if(timer === '' && !settings.manualAdvance){
timer = setInterval(function(){ nivoRun(slider, kids, settings, false); }, settings.pauseTime);
}
});
}
// Event when Animation finishes
slider.bind('nivo:animFinished', function(){
sliderImg.attr('src', vars.currentImage.attr('src'));
vars.running = false;
// Hide child links
$(kids).each(function(){
if($(this).is('a')){
$(this).css('display','none');
}
});
// Show current link
if($(kids[vars.currentSlide]).is('a')){
$(kids[vars.currentSlide]).css('display','block');
}
// Restart the timer
if(timer === '' && !vars.paused && !settings.manualAdvance){
timer = setInterval(function(){ nivoRun(slider, kids, settings, false); }, settings.pauseTime);
}
// Trigger the afterChange callback
settings.afterChange.call(this);
});
You are looking in the wrong place. use firebug to inspect and know which css file is being used. the file is default.css. Line 159. Thats what you should be playing with. this is what it looks like
.nivoSlider {
float: left;
position: relative;
width: 100%;
height: 480px;
overflow: hidden;
background: #000
this is the block of code that affects the presentation of the navigation bar. but to eradicate the blackness down there, you can use this close fix
change the property height of the nivoslider class to auto on line 159
change the backgroud property of the navigation class from transparent to black on line 296
change the margin-top property of the id menu class to 316px on line 285
this is not guaranteed to not distort especially the last point. but keep trying.
I have the following example:
var page = require('webpage').create(),
system = require('system');
if (system.args.length < 3) {
console.log('Usage: printheaderfooter.js URL filename');
phantom.exit(1);
} else {
var address = system.args[1];
var output = system.args[2];
page.viewportSize = { width: 600, height: 600 };
page.paperSize = {
format: 'A4',
margin: "1cm"
footer: {
height: "1cm",
contents: phantom.callback(function(pageNum, numPages) {
if (pageNum == numPages) {
return "";
}
return "<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>";
})
}
};
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 200);
}
});
}
In the example above I use footer_style class that look likes in my css file the following:
.footer_style {
text-align:right;
}
But unfortunately that dosen't works. I'm trying to create pdf file such as follows:
./phantomjs rasterize.js index.html test.pdf
We know that classes do not work but inline styles do. What we can do is replace the class with the computed style.
Here is a function that will take a piece of html, create a temporary element in the body with the html, compute the style for each element with a class, add the computed style inline and return the new html.
function replaceClassWithStyle(html) {
return page.evaluate(function(html) {
var host = document.createElement('div');
host.innerHTML = html;
document.body.appendChild(host); // if not appended, values will be blank
var elements = host.getElementsByTagName('*');
for (var i in elements) {
if (elements[i].className) {
elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText);
}
}
document.body.removeChild(host);
return host.innerHTML;
}, html);
}
Then simply call this function in your footer:
page.paperSize = {
footer: {
contents: phantom.callback(function(pageNum, numPages) {
if (pageNum == numPages) {
return "";
}
return replaceClassWithStyle("<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>");
})
}
};
You will need to move all this inside page.open().
I tested it and the footer is aligned to the right.
I have an update to mak's excellent answer for PhantomJS 1.9.7.
This version fixes:
Circumvent bug which 'blank's the parent document (PhantomJS 1.9.7)
Style mixups when styles are nested (do depth-first traversal instead)
Also works when tags do not have classes
/**
* Place HTML in the parent document, convert CSS styles to fixed computed style declarations, and return HTML.
* (required for headers/footers, which exist outside of the HTML document, and have trouble getting styling otherwise)
*/
function replaceCssWithComputedStyle(html) {
return page.evaluate(function(html) {
var host = document.createElement('div');
host.setAttribute('style', 'display:none;'); // Silly hack, or PhantomJS will 'blank' the main document for some reason
host.innerHTML = html;
// Append to get styling of parent page
document.body.appendChild(host);
var elements = host.getElementsByTagName('*');
// Iterate in reverse order (depth first) so that styles do not impact eachother
for (var i = elements.length - 1; i >= 0; i--) {
elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText);
}
// Remove from parent page again, so we're clean
document.body.removeChild(host);
return host.innerHTML;
}, html);
}
From my past experience, phantomjs does not support styles in custom header/footer.
The only solution that I found is to apply an inline style like this :
var page = require('webpage').create(),
system = require('system');
if (system.args.length < 3) {
console.log('Usage: printheaderfooter.js URL filename');
phantom.exit(1);
} else {
var address = system.args[1];
var output = system.args[2];
page.viewportSize = { width: 600, height: 600 };
page.paperSize = {
format: 'A4',
margin: "1cm",
footer: {
height: "1cm",
contents: phantom.callback(function(pageNum, numPages) {
return "<h1 style='text-align:right'>Footer" + pageNum + " / " + numPages + "</h1>";
})
}
};
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 200);
}
});
}
Note : A comma is missing in your code after margin: "1cm"
I'm building a responsive site that uses javascript to create a select nav for the primary navigation menu when the viewport is less than 800px wide. This select nav works as planned.
Now, I'm trying to add a SECOND responsive select nav to a couple of pages (pages that obviously include the primary navigation menu). I've duplicated the script (the script used to enable the primary navigation menu to become a select nav), and tried renaming a couple variables to get the secondary navigation menu to act responsively (similar to the primary navigation menu). The responsive select nav appears for the secondary navigation menu when the viewport goes down below 800px, however, when you select a secondary page from this menu, nothing happens. The user isn't taken to a new secondary page.
Can you help me troubleshoot this?
I tried to set up a jfiddle http://jsfiddle.net/R3AD3/
Here is the script for the primary navigation menu:
function selectnav() {
var select = document.createElement('select');
var first = document.createElement('option');
first.innerHTML = 'Main Navigation';
first.setAttribute('selected', 'selected');
select.setAttribute('id', 'mobile');
select.appendChild(first);
var nav = document.getElementById('nav');
var loadLinks = function(element, hyphen, level) {
var e = element;
var children = e.children;
for(var i = 0; i < e.children.length; ++i) {
var currentLink = children[i];
switch(currentLink.nodeName) {
case 'A':
var option = document.createElement('option');
option.innerHTML = (level++ < 1 ? '' : hyphen) + currentLink.innerHTML;
option.value = currentLink.href;
select.appendChild(option);
break;
default:
if(currentLink.nodeName === 'UL') {
(level < 2) || (hyphen += hyphen);
}
loadLinks(currentLink, hyphen, level);
break;
}
}
}
loadLinks(nav, '- ', 0);
nav.appendChild(select);
var mobile = document.getElementById('mobile');
if(mobile.addEventListener) {
mobile.addEventListener('change', function () {
window.location.href = mobile.options[mobile.selectedIndex].value;
});
} else if(mobile.attachEvent) {
mobile.attachEvent('onchange', function () {
window.location.href = mobile.options[mobile.selectedIndex].value;
});
} else {
mobile.onchange = function () {
window.location.href = mobile.options[mobile.selectedIndex].value;
}
}
}
Here is the script that I duplicated... I then renamed a couple variables:
function selectnav_EP() {
var select = document.createElement('select');
var first = document.createElement('option');
first.innerHTML = 'Electric Playground Nav';
first.setAttribute('selected', 'selected');
select.setAttribute('id', 'mobile');
select.appendChild(first);
var nav = document.getElementById('nav_EP');
var loadLinks = function(element, hyphen, level) {
var e = element;
var children = e.children;
for(var i = 0; i < e.children.length; ++i) {
var currentLink = children[i];
switch(currentLink.nodeName) {
case 'A':
var option = document.createElement('option');
option.innerHTML = (level++ < 1 ? '' : hyphen) + currentLink.innerHTML;
option.value = currentLink.href;
select.appendChild(option);
break;
default:
if(currentLink.nodeName === 'UL') {
(level < 2) || (hyphen += hyphen);
}
loadLinks(currentLink, hyphen, level);
break;
}
}
}
loadLinks(nav, '- ', 0);
nav.appendChild(select);
var mobile = document.getElementById('mobile');
if(mobile.addEventListener) {
mobile.addEventListener('change', function () {
window.location.href = mobile.options[mobile.selectedIndex].value;
});
} else if(mobile.attachEvent) {
mobile.attachEvent('onchange', function () {
window.location.href = mobile.options[mobile.selectedIndex].value;
});
} else {
mobile.onchange = function () {
window.location.href = mobile.options[mobile.selectedIndex].value;
}
}
}
In the footer, I call upon both of these scripts.
Here is the exact page to my website
http://brianlueck.com/wordpress/electric-playground/
Narrow your browser window below 800px to see the responsive select navs appear... you'll notice that the primary navigation menu works fine, however, the secondary navigation menu doesn't function properly because it doesn't link off to the pages it should link to.
Can anyone help?