text:
module("tinymce.Formatter - Apply", {
	setupModule: function() {
		document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea>

<textarea id="elm3"></textarea>';
		QUnit.stop();

		tinymce.init({
			selector: "#elm1",
			plugins: "noneditable",
			add_unload_trigger: false,
			skin: false,
			indent: false,
			extended_valid_elements: 'b[id|style|title],i[id|style|title],span[id|class|style|title|contenteditable],font[face|size]',
			forced_root_block: '',
			convert_fonts_to_spans: false,
			disable_nodechange: true,
			entities: 'raw',
			valid_styles: {
				'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
			},
			init_instance_callback: function(ed) {
				QUnit.start();
				window.editor = ed;
			}
		});
	}
});

function getContent() {
	return editor.getContent().toLowerCase().replace(/[\r]+/g, '');
}

test('apply inline to a list', function() {
	editor.formatter.register('format', {
		inline: 'b',
		toggle: false
	});
	editor.getBody().innerHTML = '
1234

first element

second element

5678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[1].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

first element

second element

5678
', 'selection of a list');
});

test('Toggle OFF - Inline element on selected text', function() {
	// Toggle OFF - Inline element on selected text
	editor.formatter.register('format', {
		inline: 'b',
		toggle: false
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('b')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.toggle('format');
	equal(getContent(), '
1234
');
});

test('Toggle OFF - Inline element on partially selected text', function() {
	// Toggle OFF - Inline element on partially selected text
	editor.formatter.register('format', {
		inline: 'b',
		toggle: 0
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('b')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('b')[0].firstChild, 2);
	editor.selection.setRng(rng);
	editor.formatter.toggle('format');
	equal(getContent(), '
1234
');
});

test('Toggle OFF - Inline element on partially selected text in start/end elements', function() {
	// Toggle OFF - Inline element on partially selected text in start/end elements
	editor.formatter.register('format', {
		inline: 'b',
		toggle: false
	});
	editor.getBody().innerHTML = '
1234

1234
'; //'
1234

1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('b')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('b')[1].firstChild, 3);
	editor.selection.setRng(rng);
	editor.formatter.toggle('format');
	equal(getContent(), '
1234

1234
');
});

test('Toggle OFF - Inline element with data attribute', function() {
	editor.formatter.register('format', {inline: 'b'});
	editor.getBody().innerHTML = '
1
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('b')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('b')[0].firstChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.toggle('format');
	equal(getContent(), '
1
');
});

test('Toggle ON - NO inline element on selected text', function() {
	// Inline element on selected text
	editor.formatter.register('format', {
		inline: 'b',
		toggle: true
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element on selected text');
	editor.formatter.toggle('format');
	equal(getContent(), '
1234
', 'Toggle ON - NO inline element on selected text');
});

test('Selection spanning from within format to outside format with toggle off', function() {
	editor.formatter.register('format', {
		inline: 'b',
		toggle: false
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('b')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].lastChild, 2);
	editor.selection.setRng(rng);
	editor.formatter.toggle('format');
	equal(getContent(), '
1234
', 'Extend formating if start of selection is already formatted');
});

test('Inline element on partially selected text', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 1);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 3);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element on partially selected text');
	editor.formatter.toggle('format');
	equal(getContent(), '
1234
', 'Toggle ON - NO inline element on partially selected text');
});

test('Inline element on partially selected text in start/end elements', function() {
	// Inline element on partially selected text in start/end elements
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234

1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 1);
	rng.setEnd(editor.dom.select('p')[1].firstChild, 3);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

1234
');
});

test('Inline element on selected element', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element on selected element');
});

test('Inline element on multiple selected elements', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234

1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

1234
', 'Inline element on multiple selected elements');
});

test('Inline element on multiple selected elements with various childnodes', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
123456789

123456789
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
123456789

123456789
', 'Inline element on multiple selected elements with various childnodes');
});

test('Inline element with attributes', function() {
	editor.formatter.register('format', {
		inline: 'b',
		attributes: {
			title: 'value1',
			id: 'value2'
		}
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element with attributes');
});

test('Inline element with styles', function() {
	editor.formatter.register('format', {
		inline: 'b',
		styles: {
			color: '#ff0000',
			fontSize: '10px'
		}
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element with styles');
});

test('Inline element with attributes and styles', function() {
	editor.formatter.register('format', {
		inline: 'b',
		attributes: {
			title: 'value1',
			id: 'value2'
		},
		styles: {
			color: '#ff0000',
			fontSize: '10px'
		}
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element with attributes and styles');
});

test('Inline element with wrapable parents', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
x1234y
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('span')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
x1234y
', 'Inline element with wrapable parents');
});

test('Inline element with redundant child', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0], 0);
	rng.setEnd(editor.dom.select('p')[0], 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element with redundant child');
});

test('Inline element with redundant parent', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('em')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('em')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element with redundant parent');
});

test('Inline element with redundant child of similar type 1', function() {
	editor.formatter.register('format', [{
		inline: 'b'
	}, {
		inline: 'strong'
	}]);
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0], 0);
	rng.setEnd(editor.dom.select('p')[0], 3);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element with redundant child of similar type 1');
});

test('Inline element with redundant child of similar type 2', function() {
	editor.formatter.register('format', [{
		inline: 'b'
	}, {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	}]);
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0], 0);
	rng.setEnd(editor.dom.select('p')[0], 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element with redundant child of similar type 2');
});

test('Inline element with redundant children of similar types', function() {
	editor.formatter.register('format', [{
		inline: 'b'
	}, {
		inline: 'strong'
	}, {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	}]);
	editor.getBody().innerHTML = '
a12345678b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0], 0);
	rng.setEnd(editor.dom.select('p')[0], 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a12345678b
', 'Inline element with redundant children of similar types');
});

test('Inline element with redundant parent 1', function() {
	editor.formatter.register('format', [{
		inline: 'b'
	}, {
		inline: 'strong'
	}]);
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('em')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('em')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element with redundant parent 1');
});

test('Inline element with redundant parent 2', function() {
	editor.formatter.register('format', [{
		inline: 'b'
	}, {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	}]);
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('em')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('em')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element with redundant parent 2');
});

test('Inline element with redundant parents of similar types', function() {
	editor.formatter.register('format', [{
		inline: 'b'
	}, {
		inline: 'strong'
	}, {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	}]);
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('em')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('em')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element with redundant parents of similar types');
});

test('Inline element merged with parent and child', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
a123456b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('b')[0].firstChild, 1);
	rng.setEnd(editor.dom.select('b')[0].lastChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a123456b
', 'Inline element merged with parent and child');
});

test('Inline element merged with child 1', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	});
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element merged with child 1');
});

test('Inline element merged with child 2', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	});
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element merged with child 2');
});

test('Inline element merged with child 3', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	});
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element merged with child 3');
});

test('Inline element merged with child 3', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		},
		merge: true
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element merged with child 3');
});

test('Inline element merged with child 4', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			color: '#00ff00'
		}
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element merged with child 4');
});

test('Inline element with attributes merged with child 1', function() {
	editor.formatter.register('format', {
		inline: 'font',
		attributes: {
			face: 'arial'
		},
		merge: true
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element with attributes merged with child 1');
});

test('Inline element with attributes merged with child 2', function() {
	editor.formatter.register('format', {
		inline: 'font',
		attributes: {
			size: '7'
		}
	});
	editor.getBody().innerHTML = '
a1234b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a1234b
', 'Inline element with attributes merged with child 2');
});

test('Inline element merged with left sibling', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
12345678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].lastChild, 0);
	rng.setEnd(editor.dom.select('p')[0].lastChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
12345678
', 'Inline element merged with left sibling');
});

test('Inline element merged with right sibling', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
12345678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
12345678
', 'Inline element merged with right sibling');
});

test('Inline element merged with left and right siblings', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
123456
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].childNodes[1], 0);
	rng.setEnd(editor.dom.select('p')[0].childNodes[1], 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
123456
', 'Inline element merged with left and right siblings');
});

test('Inline element merged with data attributed left sibling', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
12345678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].lastChild, 0);
	rng.setEnd(editor.dom.select('p')[0].lastChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
12345678
', 'Inline element merged with left sibling');
});

test('Don\'t merge siblings with whitespace between 1', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
a b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].lastChild, 1);
	rng.setEnd(editor.dom.select('p')[0].lastChild, 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a b
', 'Don\'t merge siblings with whitespace between 1');
});

test('Don\'t merge siblings with whitespace between 1', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
a b
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
a b
', 'Don\'t merge siblings with whitespace between 2');
});

test('Inline element not merged in exact mode', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			color: '#00ff00'
		},
		exact: true
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element not merged in exact mode');
});

test('Inline element merged in exact mode', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			color: '#ff0000'
		},
		exact: true
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Inline element merged in exact mode');
});

test('Deep left branch', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234text1text2

5678

9012
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('ins')[0].firstChild, 1);
	rng.setEnd(editor.dom.select('p')[2].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234text1text2

5678

9012
', 'Deep left branch');
});

test('Deep right branch', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
9012

5678

1234text1text2
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('em')[3].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
9012

5678

1234text1text2
', 'Deep right branch');
});

test('Full element text selection on two elements with a table in the middle', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.getBody().innerHTML = '
1234

123

5678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[1].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

123

5678
', 'Full element text selection on two elements with a table in the middle');
});

test('Inline element on selected text with variables', function() {
	editor.formatter.register('format', {
		inline: 'b',
		styles: {
			color: '%color'
		},
		attributes: {
			title: '%title'
		}
	}, {
		color: '#ff0000',
		title: 'title'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format', {
		color: '#ff0000',
		title: 'title'
	});
	equal(getContent(), '
1234
', 'Inline element on selected text');
});

test('Remove redundant children', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			fontFamily: 'arial'
		}
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0], 0);
	rng.setEnd(editor.dom.select('p')[0], 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Remove redundant children');
});

test('Inline element on selected text with function values', function() {
	editor.formatter.register('format', {
		inline: 'b',
		styles: {
			color: function(vars) {
				return vars.color + '00ff';
			}
		},
		attributes: {
			title: function(vars) {
				return vars.title + '2';
			}
		}
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format', {
		color: '#ff',
		title: 'title'
	});
	equal(getContent(), '
1234
', 'Inline element on selected text with function values');
});

test('Block element on selected text', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Block element on selected text');
});

test('Block element on partially selected text', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 1);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 3);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Block element on partially selected text');
});

test('Block element on selected element', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Block element on selected element');
});

test('Block element on selected elements', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '
1234

5678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

5678
', 'Block element on selected elements');
});

test('Block element on selected elements with attributes', function() {
	editor.formatter.register('format', {
		block: 'div',
		attributes: {
			'title': 'test'
		}
	});
	editor.getBody().innerHTML = '
1234

5678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

5678
', 'Block element on selected elements with attributes');
});

test('Block element on nested element', function() {
	editor.formatter.register('format', {
		block: 'p'
	});
	editor.getBody().innerHTML = '

1234

';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('h1')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('h1')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '

1234

', 'Block element on nested element');
});

test('Block element on selected non wrapped text 1', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '1234';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody().firstChild, 0);
	rng.setEnd(editor.getBody().firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Block element on selected non wrapped text 1');
});

test('Block element on selected non wrapped text 2', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '1234
4567
8910';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody().firstChild, 0);
	rng.setEnd(editor.getBody().lastChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

4567

8910
', 'Block element on selected non wrapped text 2');
});

test('Block element on selected non wrapped text 3', function() {
	editor.formatter.register('format', {
		block: 'div'
	});
	editor.getBody().innerHTML = '
1234

4567
8910
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 7);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

4567

8910
', 'Block element on selected non wrapped text 3');
});

test('Block element wrapper 1', function() {
	editor.formatter.register('format', {
		block: 'blockquote',
		wrapper: 1
	});
	editor.getBody().innerHTML = '
1234

5678
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('h1')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '

1234

5678

', 'Block element wrapper 1');
});

test('Block element wrapper 2', function() {
	editor.formatter.register('format', {
		block: 'blockquote',
		wrapper: 1
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('h1')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('h1')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '

1234

', 'Block element wrapper 2');
});

test('Block element wrapper 3', function() {
	editor.formatter.register('format', {
		block: 'blockquote',
		wrapper: 1
	});
	editor.getBody().innerHTML = '

1234

';
	var rng = editor.dom.createRng();
	rng.setStart(editor.getBody(), 0);
	rng.setEnd(editor.getBody(), 3);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '

1234

', 'Block element wrapper 3');
});

test('Apply format on single element that matches a selector 1', function() {
	editor.formatter.register('format', {
		selector: 'p',
		attributes: {
			title: 'test'
		},
		styles: {
			'color': '#ff0000'
		},
		classes: 'a b c'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Apply format on single element that matches a selector');
});

test('Apply format on single element parent that matches a selector 2', function() {
	editor.formatter.register('format', {
		selector: 'div',
		attributes: {
			title: 'test'
		},
		styles: {
			'color': '#ff0000'
		},
		classes: 'a b c'
	});
	editor.getBody().innerHTML = '

1234

test

1234

';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('div')[0], 1);
	rng.setEnd(editor.dom.select('div')[0], 2);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '

1234

test

1234

', 'Apply format on single element parent that matches a selector');
});

test('Apply format on multiple elements that matches a selector 2', function() {
	editor.formatter.register('format', {
		selector: 'p',
		attributes: {
			title: 'test'
		},
		styles: {
			'color': '#ff0000'
		},
		classes: 'a b c'
	});
	editor.getBody().innerHTML = '
1234

test

1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[1].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234

test

1234
', 'Apply format on multiple elements that matches a selector');
});

test('Apply format on top of existing selector element', function() {
	editor.formatter.register('format', {
		selector: 'p',
		attributes: {
			title: 'test2'
		},
		styles: {
			'color': '#00ff00'
		},
		classes: 'a b c'
	});
	editor.getBody().innerHTML = '
1234
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
1234
', 'Apply format on top of existing selector element');
});

test('Format on single li that matches a selector', function() {
	editor.formatter.register('format', {
		inline: 'span',
		selector: 'li',
		attributes: {
			title: 'test'
		},
		styles: {
			'color': '#ff0000'
		},
		classes: 'a b c'
	});
	editor.getBody().innerHTML = '
text
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('div')[0], 0);
	rng.setEnd(editor.dom.select('div')[0], 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
text
', 'Apply format on single element that matches a selector');
});

test('Format on single div that matches a selector', function() {
	editor.formatter.register('format', {
		inline: 'span',
		selector: 'div',
		attributes: {
			title: 'test'
		},
		styles: {
			'color': '#ff0000'
		},
		classes: 'a b c'
	});
	editor.getBody().innerHTML = '
text
';
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('div')[0], 0);
	rng.setEnd(editor.dom.select('div')[0], 1);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
text
', 'Apply format on single element that matches a selector');
});

test('Bold and italics is applied to text that is not highlighted', function() {
	var rng = editor.dom.createRng();
	editor.setContent('
test1 test2 test3 test4 test5 test6
');
	rng.setStart(editor.dom.select('strong')[0].firstChild, 6);
	rng.setEnd(editor.dom.select('strong')[0].firstChild, 11);
	editor.focus();
	editor.selection.setRng(rng);
	editor.execCommand('Italic');
	equal(editor.getContent(), '
test1 test2 test3 test4 test5 test6
', 'Selected text should be bold.');
});

test('Apply color format to links as well', function() {
	editor.setContent('
123abc456
');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].lastChild, 3);
	editor.selection.setRng(rng);

	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			color: '#FF0000'
		},
		links: true
	});
	editor.formatter.apply('format');

	equal(
		editor.getContent(),
		'
123abc456
',
		'Link should have it\'s own color.'
	);
});

test('Color on link element', function() {
	editor.setContent('
123abc456
');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('span')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('span')[0].lastChild, 3);
	editor.selection.setRng(rng);

	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			color: '#FF0000'
		},
		links: true
	});
	editor.formatter.apply('format');

	equal(
		editor.getContent(),
		'
123abc456
',
		'Link should have it\'s own color.'
	);
});

test("Applying formats in lists", function() {
	editor.setContent('

text

nested

');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('li')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('li')[0].firstChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply("h1");
	equal(editor.getContent(), '

text

nested

', "heading should not automatically apply to sublists");
});

test("Applying formats on a list including child nodes", function(){
	editor.formatter.register('format', {inline: 'strong'});
	editor.setContent('

a

b

c

d

e

f

g

');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('li')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('li')[6].firstChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply("format");
	equal(editor.getContent(), '

a

b

c

d

e

f

g

', "should be applied to all sublists");
});

test('Block format on li element', function() {
	editor.setContent('

text

nested

');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('li')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('li')[1].firstChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply("h1");
	equal(editor.getContent(), '

text

nested

', "heading should automatically apply to sublists, when selection spans the sublist");
});

test('Block on li element 2', function() {
	editor.setContent('

before

nested

after

');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('li')[0].lastChild, 1);
	rng.setEnd(editor.dom.select('li')[0].lastChild, 2);
	editor.selection.setRng(rng);
	editor.formatter.apply("h1");
	equal(editor.getContent(), '

before

nested

after

', "heading should automatically apply to sublists, when selection spans the sublist");
});

test('Block on li element 3', function() {
	editor.setContent('

before

nested

after

');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('li')[1].firstChild, 0);
	rng.setEnd(editor.dom.select('li')[0].lastChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply("h1");
	equal(editor.getContent(), '

before

nested

after

', "heading should automatically apply to sublists, when selection spans the sublist");
});

test('Block on li element 4', function() {
	editor.setContent('

before

nested

after

');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('li')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('li')[0].lastChild, 1);
	editor.selection.setRng(rng);
	editor.formatter.apply("h1");
	equal(editor.getContent(), '

before

nested

after

', "heading should apply correctly when selection is after a sublist");
});

test('Underline colors 1', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			'color': '#ff0000'
		}
	});
	editor.setContent('
test
');
	editor.execCommand('SelectAll');
	editor.formatter.apply('format');
	equal(editor.getContent(), '
test
', 'Coloring an underlined text should result in a colored underline');
});

test('Underline colors 2', function() {
	editor.formatter.register('format', {
		inline: "span",
		exact: true,
		styles: {
			'textDecoration': 'underline'
		}
	});
	editor.setContent('
test
');
	editor.execCommand('SelectAll');
	editor.formatter.apply('format');
	equal(editor.getContent(), '
test
', 'Underlining colored text should result in a colored underline');
});

test('Underline colors 3', function() {
	editor.formatter.register('format', {
		inline: "span",
		exact: true,
		styles: {
			'textDecoration': 'underline'
		}
	});
	editor.setContent('
This is some example text
');
	editor.execCommand('SelectAll');
	editor.formatter.apply('format');
	equal(editor.getContent(), '
This is some example text
', 'Underlining colored and underlined text should result in a colored underline');
});

test('Underline colors 4', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			'color': '#ff0000'
		}
	});
	editor.setContent('
yellowredyellow
');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('span')[1].firstChild, 6);
	rng.setEnd(editor.dom.select('span')[1].firstChild, 9);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(getContent(), '
yellowredyellow
',
		'Coloring an colored underdlined text should result in newly colored underline'
	);
});

test('Underline colors 5', function() {
	editor.formatter.register('format', {
		inline: "span",
		exact: true,
		styles: {
			'textDecoration': 'underline'
		}
	});
	editor.setContent('
This is some example text

This is some example text

This is some example text
');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('strong')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('span')[4].lastChild, 5);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
This is some example text

This is some example text

This is some example text
', 'Colored elements should be underlined when selection is across multiple paragraphs');
});

test('Underline colors 6', function() {
	editor.formatter.register('format', {
		inline: 'span',
		exact: true,
		styles: {
			'color': '#ff0000'
		}
	});
	editor.setContent('
This is some text.
');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('span')[0].firstChild, 8);
	rng.setEnd(editor.dom.select('span')[0].firstChild, 12);
	editor.selection.setRng(rng);
	editor.formatter.apply('format');
	editor.formatter.remove('format');
	equal(editor.getContent(), '
This is some text.
', 'Children nodes that are underlined should be removed if their parent nodes are underlined');
});

test('Underline colors 7', function() {
	editor.formatter.register('format', {
		inline: 'span',
		exact: true,
		styles: {
			'color': '#ff0000'
		}
	});
	editor.setContent('
This is some text.
');
	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('span')[1].firstChild, 0);
	rng.setEnd(editor.dom.select('span')[1].firstChild, 4);
	editor.selection.setRng(rng);
	editor.formatter.remove('format');
	equal(editor.getContent(), '
This is some text.
', 'Children nodes that are underlined should be removed if their parent nodes are underlined');
});

test('Caret format inside single block word', function() {
	editor.setContent('
abc
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 2, 'p', 2);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc
');
});

test('Caret format inside non-ascii single block word', function() {
	editor.setContent('
noël
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 2, 'p', 2);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
noël
');
});

test('Caret format inside first block word', function() {
	editor.setContent('
abc 123
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 2, 'p', 2);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc 123
');
});

test('Caret format inside last block word', function() {
	editor.setContent('
abc 123
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 5, 'p', 5);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc 123
');
});

test('Caret format inside middle block word', function() {
	editor.setContent('
abc 123 456
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 5, 'p', 5);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc 123 456
');
});

test('Caret format on word separated by non breaking space', function() {
	editor.setContent('
one two
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 1, 'p', 1);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
one\u00a0two
');
});

test('Caret format inside single inline wrapped word', function() {
	editor.setContent('
abc 123 456
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('em', 1, 'em', 1);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc 123 456
');
});

test('Caret format inside word before similar format', function() {
	editor.setContent('
abc 123 456
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 1, 'p', 1);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc 123 456
');
});

test('Caret format inside last inline wrapped word', function() {
	editor.setContent('
abc abc 123 456
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('em', 5, 'em', 5);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc abc 123 456
');
});

test('Caret format before text', function() {
	editor.setContent('
a
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 0, 'p', 0);
	editor.formatter.apply('format');
	Utils.type('b');
	equal(editor.getContent(), '
ba
');
});

test('Caret format after text', function() {
	editor.setContent('
a
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 1, 'p', 1);
	editor.formatter.apply('format');
	Utils.type('b');
	equal(editor.getContent(), '
ab
');
});

test('Caret format and no key press', function() {
	editor.setContent('
a
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 0, 'p', 0);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
a
');
});

test('Caret format and arrow left', function() {
	editor.setContent('
a
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 0, 'p', 0);
	editor.formatter.apply('format');
	Utils.type({
		keyCode: 37
	});
	equal(editor.getContent(), '
a
');
});

test('Caret format and arrow right', function() {
	editor.setContent('
a
');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('p', 0, 'p', 0);
	editor.formatter.apply('format');
	Utils.type({
		keyCode: 39
	});
	equal(editor.getContent(), '
a
');
});

test('Caret format and backspace', function() {
	var rng;

	if (tinymce.isOpera) {
		ok(true, "Skip Opera since faking backspace doesn't work.");
		return;
	}

	editor.formatter.register('format', {
		inline: 'b'
	});

	editor.setContent('
abc
');
	rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 3);
	rng.setEnd(editor.dom.select('p')[0].firstChild, 3);
	editor.selection.setRng(rng);

	editor.formatter.apply('format');
	Utils.type('\b');
	equal(editor.getContent(), '
ab
');
});

test('Caret format on word in li with word in parent li before it', function() {
	editor.setContent('

one

two

');
	editor.formatter.register('format', {
		inline: 'b'
	});
	Utils.setSelection('ul li li', 1, 'ul li li', 1);
	editor.formatter.apply('format');
	equal(editor.getContent(), '

one

two

');
});

test('Selector format on whole contents', function() {
	editor.setContent('
a
');
	editor.formatter.register('format', {
		inline: 'span',
		selector: '*',
		classes: 'test'
	});
	Utils.setSelection('p', 0, 'p', 1);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
a
');
});

test('format inline on contentEditable: false block', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.setContent('
abc

def
');
	Utils.setSelection('p:nth-child(2)', 0, 'p:nth-child(2)', 3);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc

def
', 'Text is not bold');
});

test('format block on contentEditable: false block', function() {
	editor.formatter.register('format', {
		block: 'h1'
	});
	editor.setContent('
abc

def
');
	Utils.setSelection('p:nth-child(2)', 0, 'p:nth-child(2)', 3);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc

def
', 'P is not h1');
});

test('contentEditable: false on start and contentEditable: true on end', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.setContent('
abc

def

ghi
');
	Utils.setSelection('p:nth-child(2)', 0, 'p:nth-child(3)', 3);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc

def

ghi
', 'Text in last paragraph is bold');
});

test('contentEditable: true on start and contentEditable: false on end', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.setContent('
abc

def
');
	Utils.setSelection('p:nth-child(1)', 0, 'p:nth-child(2)', 3);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc

def
', 'Text in first paragraph is bold');
});

test('contentEditable: true inside contentEditable: false', function() {
	editor.formatter.register('format', {
		inline: 'b'
	});
	editor.setContent('
abc

def
');
	Utils.setSelection('span', 0, 'span', 3);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc

def
', 'Text is bold');
});

test('Del element wrapping blocks', function() {
	editor.setContent('
a
');
	Utils.setSelection('p', 0, 'p', 1);
	editor.formatter.register('format', {
		block: 'del',
		wrapper: true
	});
	editor.formatter.apply('format');
	equal(getContent(), '
a
');
});

test('Del element replacing block', function() {
	editor.setContent('
a
');
	Utils.setSelection('p', 0, 'p', 1);
	editor.formatter.register('format', {
		block: 'del'
	});
	editor.formatter.apply('format');
	equal(getContent(), 'a');
});

test('Del element as inline', function() {
	editor.setContent('
a
');
	Utils.setSelection('p', 0, 'p', 1);
	editor.formatter.register('format', {
		inline: 'del'
	});
	editor.formatter.apply('format');
	equal(getContent(), '
a
');
});

test('Align specified table element with collapsed: false and selection collapsed', function() {
	editor.setContent('

a

');
	Utils.setSelection('td', 0, 'td', 0);
	editor.formatter.register('format', {
		selector: 'table',
		collapsed: false,
		styles: {
			'float': 'right'
		}
	});
	editor.formatter.apply('format', {}, editor.getBody().firstChild);
	equal(getContent(), '

a

');
});

test('Align nested table cell to same as parent', function() {
	editor.setContent(
		'
' +
			'
' +
				'
' +
					'a' +
						'
' +
							'
' +
								'
' +
									'b	' +
								'
' +
							'
' +
						'
' +
					'	' +
				'
' +
			'
' +
		'
'
	);

	Utils.setSelection('b', 0);

	editor.formatter.register('format', {
		selector: 'td',
		styles: {
			'text-align': 'right'
		}
	});

	editor.formatter.apply('format', {}, editor.$('td td')[0]);

	equal(
		getContent(),
		'
' +
			'
' +
				'
' +
					'a' +
						'
' +
							'
' +
								'
' +
									'b	' +
								'
' +
							'
' +
						'
' +
					'	' +
				'
' +
			'
' +
		'
'
	);
});

test('Apply ID format to around existing bookmark node', function() {
	editor.getBody().innerHTML = '
ab
';

	var rng = editor.dom.createRng();
	rng.setStart(editor.dom.select('p')[0].firstChild, 0);
	rng.setEnd(editor.dom.select('p')[0].lastChild, 1);
	editor.selection.setRng(rng);

	editor.formatter.register('format', {
		inline: 'span',
		attributes: {
			id: 'id'
		}
	});
	editor.formatter.apply('format');

	equal(Utils.normalizeHtml(editor.getBody().innerHTML), '
ab
');
});

test('Bug #5134 - TinyMCE removes formatting tags in the getContent', function() {
	editor.setContent('');
	editor.formatter.register('format', {
		inline: 'strong',
		toggle: false
	});
	editor.formatter.apply('format');
	equal(getContent(), '', 'empty TinyMCE');
	editor.selection.setContent('a');
	equal(getContent(), 'a', 'bold text inside TinyMCE');
});

test('Bug #5134 - TinyMCE removes formatting tags in the getContent - typing', function() {
	editor.setContent('');
	editor.formatter.register('format', {
		inline: 'strong',
		toggle: false
	});
	editor.formatter.apply('format');
	equal(getContent(), '', 'empty TinyMCE');
	Utils.type('a');
	equal(getContent(), 'a', 'bold text inside TinyMCE');
});

test('Bug #5453 - TD contents with BR gets wrapped in block format', function() {
	editor.setContent('

abc
123

');
	Utils.setSelection('td', 1, 'td', 1);
	editor.formatter.register('format', {
		block: 'h1'
	});
	editor.formatter.apply('format');
	equal(getContent(), '

abc
123

');
});

test('Bug #6471 - Merge left/right style properties', function() {
	editor.formatter.register('format', {
		inline: 'span',
		styles: {
			fontWeight: 'bold'
		}
	});
	editor.setContent('
abc
');
	Utils.setSelection('p', 2, 'p', 3);
	editor.formatter.apply('format');
	Utils.setSelection('p', 1, 'p', 2);
	editor.formatter.apply('format');
	Utils.setSelection('p', 0, 'p', 1);
	editor.formatter.apply('format');
	equal(editor.getContent(), '
abc
');
});

asyncTest('Bug #6518 - Apply div blocks to inline editor paragraph', function() {
	tinymce.init({
		selector: "#elm2",
		inline: true,
		add_unload_trigger: false,
		skin: false,
		indent: false,
		convert_fonts_to_spans: false,
		disable_nodechange: true,
		entities: 'raw',
		valid_styles: {
			'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
		},
		init_instance_callback: function(ed) {
            QUnit.start();

			ed.setContent('
a

b
');
			ed.selection.select(ed.getBody().firstChild, true);
			ed.selection.collapse(true);
			ed.formatter.register('format', {
				block: 'div'
			});
			ed.formatter.apply('format');
			equal(ed.getContent(), '
a

b
');
		}
	});
});

asyncTest('Bug #7412 - valid_styles affects the Bold and Italic buttons, although it shouldn\'t', function() {
    tinymce.init({
        selector: "#elm3",
        add_unload_trigger: false,
        valid_styles: {
            span: 'color,background-color,font-size,text-decoration,padding-left'
        },
        init_instance_callback: function(ed) {
            QUnit.start();

            ed.getBody().innerHTML = '
1 1234 1
';
            var rng = ed.dom.createRng();
            rng.setStart(ed.dom.select('span')[0], 0);
            rng.setEnd(ed.dom.select('span')[0], 1);
            ed.selection.setRng(rng);
            ed.formatter.toggle('bold');
            equal(ed.getContent(), '
1 1234 1
');
        }
    });
});

test('Format selection from with end at beginning of block', function(){
	editor.setContent("
one

two
");
	editor.focus();
	Utils.setSelection('#a', 0, '#b', 0);
	editor.execCommand('formatBlock', false, 'h1');
	equal(getContent(), '
one

two
');
});

test('Format selection over fragments', function(){
	editor.setContent("
abcd
");
	Utils.setSelection('strong', 1, 'em', 0);
	editor.formatter.apply('underline');
	equal(getContent(), '
abcd
');
});

test("Wrapper with fontSize should retain priority within a branch of nested inline format wrappers", function() {
	editor.setContent("
abc
");
	Utils.setSelection('p', 0, 'p', 3);

	editor.formatter.apply('fontsize', {value: '18px'});
	editor.formatter.apply('bold');
	editor.formatter.apply('underline');
	editor.formatter.apply('forecolor', {value: '#ff0000'});

    equal(getContent(), '
abc
');
});

test("Child wrapper having the same format as the immediate parent, shouldn't be removed if it also has other formats merged", function() {
	editor.getBody().innerHTML = '
a bc
';
	Utils.setSelection('span span', 0, 'span span', 1);
	editor.formatter.apply('fontname', {value: "verdana"});
	equal(getContent(), '
a bc
');
});

test("When format with backgroundColor is applied, all the nested childNodes having fontSize should receive backgroundColor as well", function() {
	editor.getBody().innerHTML = '
a b c
';
	editor.selection.select(editor.dom.select('p')[0]);

	editor.formatter.apply('hilitecolor', {value: "#ff0000"});
	equal(getContent(), '
a b c
');

	editor.formatter.remove('hilitecolor', {value: "#ff0000"});
	equal(getContent(), '
a b c
');
});

test("TINY-782: Can't apply sub/sup to word on own line with large font", function() {
	editor.getBody().innerHTML = '
abc
';
	Utils.setSelection('span', 0, 'span', 3);
	editor.formatter.apply('superscript');
	equal(getContent(), '
abc
');
});

test("TINY-671: Background color on nested font size bug", function() {
	editor.getBody().innerHTML = '
abc
';
	Utils.setSelection('span', 0, 'span', 3);
	editor.formatter.apply('hilitecolor', {value: '#ff0000'});
	equal(getContent(), '
abc
');
});

test("TINY-865: Font size removed when changing background color", function() {
	editor.getBody().innerHTML = '
a b c
';
	Utils.setSelection('span span:nth-child(2)', 0, 'span span:nth-child(2)', 1);
	editor.formatter.apply('hilitecolor', {value: '#ff0000'});
    equal(getContent(), '
a b c
');
});

test("TINY-935: Text color, then size, then change color wraps span doesn't change color", function() {
    editor.getBody().innerHTML = '
text
';
    Utils.setSelection('span', 0, 'span', 4);
    editor.formatter.apply('forecolor', {value: '#ff0000'});
    equal(getContent(), '
text
');
});

test("GH-3519: Font family selection does not work after changing font size", function() {
    editor.getBody().innerHTML = '
text
';
    Utils.setSelection('span', 0, 'span', 4);
    editor.formatter.apply('fontname', {value: "verdana"});
    equal(getContent(), '
text
');
});

redpajama_set_name: RedPajamaGithub


text:
Jennifer Ladouceur: A Role Model Inspiring Passion & Innovation in Others
in Successful Businesswomen July20 Profiles, Successful-Businesswomen-Magaz-Feb20-Profiles, Women's World
Jennifer Ladouceur | President & Co-Founder | Women Leadership NationT Inc.
Businesswomen today deserve access to leadership development support designed specifically to meet their needs. Women in the workplace have big dreams. Imagine a gender-balanced workplace, where women are properly supported and given opportunities to lead. Where organizations thrive and benefit from increased profitability, enhanced creativity & innovations, and collaborative corporate cultures; where they create an environment where everyone can thrive. Creating such Unified Workplaces that would attract, develop, engage, and retain, is a women leader –Jennifer Ladouceur, President & Co-Founder at Women Leadership Nation™ Inc.
"For WLN to become North America's "go-to training and development firm" for those companies serious about gaining momentum in closing the Gender Gap and creating a Unified Workplace™; while helping women leaders create the career of their dreams"
Specially for Professional Women
In the beginning of WLN's journey, it had initially launched a company that was designed to offer retreats specifically for professional women, with a focus on helping them to escape the daily grind and take the necessary time to do some self-reflection on where they are today, where they want to be tomorrow and how to get there. It quickly realized that in many cases women working full time and also balancing a household along with other demands simply finds it too hard to make the much-needed time for them.
Jennifer was faced with having to iterate her business model "pivot" and bring the solution to the women, directly to the workplace itself. Success derives from solving a realworld problem and when creating a new approach, a new solution engaging the community you will be working with from the early stages, which helps you to ensure you are creating a service or developing a program that will eventually generate measurable results. After significant consultation, WLN was reborn with a new focus on helping the companies to create an environment (a corporate culture) that allows for everyone to thrive; while also helping the women in workplace to succeed and grow personally and professionally.
Personalized Training Programs
WLN offers personalized authentic leadership training, development, assessments and certification solutions designed to leverage diversity & create an environment where everyone can thrive. Most companies simply offer Band-Aid solutions; whereas, at WLN, the company focuses on providing a more holistic solution. All personalized training programs are designed to be highly experiential, and the company helps clients create a Unified Workplace™ Strategy that touches on all 12 Unity Building Blocks, components that are necessary to make measurable progress in closing the gap & better-supporting women leaders.
Support Women Leaders
Jennifer's goal is to help companies, particularly those operating in male-dominated industries such as technology, science, film & television, among many others disrupt the status quo and find ways to better support women leaders at all levels throughout the organization. She will catalyze this change by continuing to develop holistic solutions that target the 12 Building Blocks to Unity™, a proprietary framework created by WLN.
Close the Gender-gap
What makes WLN different from other training companies is the approach it takes to solve the gender gap. A trailblazing thought leader, Jennifer thrives at developing and launching new solutions, new business models, and innovative approaches to solve complex problems & create new market opportunities. Uniquely positioned, Jennifer's career spans a diverse range of high-profile leadership positions in both the private and public sectors, which has provided her with a wealth of knowledge and insight that makes it possible for her to think differently and create new ideas. She regularly delivers keynote speeches on women's leadership and the need to take a different approach to close the gender gap; she has also spoken at TEDx, where she shared a very personal story on the topic of Finding Your Authentic Self.
Jennifer is the recipient of 11 marketing awards, received the Women of Distinction Award in the Business, and was identified in 2019 as a Women of Influence. She holds a Master Business Administration (MBA), Masters Certificate in Municipal Leadership, Economic Development Certificate, professional Canadian Economic Development Ec.D. designation, Certification from the Schulich Business Incubator & Entrepreneurship Development Program, Graduate Diploma in Management, Marketing Management Certificate, Harvard Higher Educating Teaching Certificate, is a Reiki Master, and a Certified TotalSDI™ Facilitator. Jennifer's education is diverse having studied business, marketing, economic development, public relations, journalism, and graphic design, which is another contributor to her ability to innovate and see problems/opportunities differently.
In her current role, Jennifer is the President and Co-Founder of Women Leadership Nation™ Inc. (WLN), a boutique leadership advisory and training & development company specializing in helping organizations to close the gender gap, increase resiliency and create a Unified Workplace™; while also helping women leaders successfully navigate the workplace and create the career of their dreams. Having experienced being the only woman at the table in many organizations, Jennifer has spent the past four years conducting research, interviewing leaders, and creating a new approach to helping organizations close the gender gap and help women leaders thrive.
Jennifer is a mom of seven, successful businesswomen and a cancer survivor.
Ability to Collaborate
Collaboration over competition. We live in a world of abundance, and yet most people choose to focus their thoughts around a scarcity mindset, which severely limits the ability to collaborate, innovate, and flourish. A vital attribute businesswoman should possess is the ability to see new opportunities that can arise by being radically generous and collaborative, leading with a mindset of abundance. At WLN-have formed strong partnerships with many women leadership organizations that provide win-win opportunities for everyone.
"Surround yourself with people smarter than you & soak in as much new knowledge, insights, and different perspectives as you can. Diversity of thought will help you to hone your own skills and provide you with an ability to think differently from your competitors, hence providing you with a competitive advantage. As well as, remember starting a new business is a long road with many roadblocks & delays that can at times make you feel isolated and discouraged, but you can't lose faith, and you need to remember that resiliency and remaining driven and passionate about your vision is the key to staying the path and succeeding in the long term. Don't forget to build a community of support around you", says Jennifer
Kelly Hall: A Leader with Compassion, Determination, and Persistence
Carolyn Hogg: An Entrepreneurial Leader covering all the Tasks

redpajama_set_name: RedPajamaCommonCrawl


Following a fitness program has many benefits not just for the vanity purposes of people that want to achieve and maintain a toned and fit body, but also for those that want to strengthen their bodies and improve their overall wellness so they can stand a chance against unexpected illnesses that can slow them down. For training athletes, a good workout routine helps them to fully prepare for their main event by improving their physical resistance and endurance so they can last in their field long enough to beat out their opponents and win the highest goal possible.
Fitness training programs, however, must be developed by a professional fitness trainer so it can particularly address an individual's current health and activity level, and take their lifestyle into consideration in order to ensure the efficiency of the routine, which is why it is not recommended to just copy someone else's routine for any matter. In physical training, there are always standards and rules that must be followed by training individuals to avoid muscle strain, accidents, and any debilitating injury, which are all very likely when there is lack of proper guidance from a certified professional.
The importance of having a personal trainer when it comes to following a fitness routine is more than just safety, because when it comes to reaching goals in a specified time, they are also the best one to go to as their expertise also gives them all the knowledge required to understand when there are adjustments that need to be made on a routine.A customized routine is the best way to achieve targeted results as this can ensure that the routines followed are specific for the client's body type, so no time is wasted doing irrelevant exercises that may not even yield any result at all.
Quite interestingly, fitness coaches are now also available through an online program where they can still guide their clients just as effectively as they would on a normal training routine, but with more time flexibility for both sides so they can conveniently schedule their program when their time allows. This type of online training service is still based on client profiling, as this will always be the trainer's basis in creating a custom program, although over the internet, where they can still act as a personal guide and as a consultant anytime needed.
The essential functions of a personal trainer is still maintained in an online service, but with more advantages in terms of time flexibility, which is helpful for busier individuals that want to keep a professional training and diet coach that will help them realize their dreams.
← Get A Better Body Today By Subsequent These Straightforward Health and fitness Suggestions!


Digital transformation is flipping IT architectures inside out, as data and content move from the private, centralized cloud and on-premises data centers to public cloud services and SaaS providers, beyond an enterprise's current edge. For digital businesses this means the boundary between the digital and physical worlds is blurring at the digital edge, where commerce, population centers and digital ecosystems meet.
In this dynamic environment, people in the response flow can add an hour. When everything is constantly changing, and you're continuously pivoting, how can you accurately plan or forecast your business or anticipate an event–the holy grail of digital business?
If you're wondering how wide-spread application state can be coordinated throughout such a dynamic landscape, you'd be right to do so. Coordination is needed not just across internal business services, but also across disparate services that may or may not be connected to a common messaging platform up and down the application layer stack.
Today's businesses are looking to integrate applications and IT services to achieve new business models. Digital transformation requires standardized applications and protocols that allow everything to work together. Speedy time to market drives business value, and in this dynamic digital environment, users won't wait for an app to catch up, or for everyone to get on the same standard.
Business application giant SAP® has transformed more than 345,000 companies throughout the world in how they perform enterprise resource planning, customer relationship, product lifecycle, supply chain and database management. SAP is continuing its evolution by transforming itself into a world-class enterprise application cloud platform company with its SAP Cloud portfolio.
By shifting the digital storefront from websites to APIs, these "API-driven" companies are accelerating digital business. As a result of moving their product development to APIs, digital businesses are essentially positioning their business interfaces across multiple clouds and PaaS environments in all industries.


This front disc brake pad set is just what you need to get your vehicle stopping in good order again!
The ceramic brake pads I ordered and installed in my Colorado gives me the smoothest brakes and stops that anyone could ask for.
Thanks to the chat, I was able to get quick assistance in making sure I was ordering the correct break pads. They have since been installed and are working great. No squeaking.


text:
Every Premier League and Football League club's average 2018/19 attendance - ranked in order
13 Sunderland pubs from yesteryear - how many of them can you remember?
Best In
Man, 42, who was attacked in Sunderland street dies in hospital
A man who suffered serious injuries after being attacked in a Sunderland street has died in hospital.
By David Allison
Wednesday, 15 May, 2019, 11:09
At about 2.50am on Sunday, police received a report that a man had been assaulted following a disturbance in Edward Burdis Street, Southwick.
Emergency services attended the scene of the incident and the victim was taken to hospital with serious life-threatening injuries.
Northumbria Police has confirmed that Paul Hutchinson, 42, from the Ford Estate area of Sunderland, died in hospital yesterday.
His family are being supported by specialist officers and have asked that their privacy is respected as they come to terms with their loss.
A 43-year-old man was arrested on suspicion of causing grievous bodily harm and has since been released on police bail.
Senior investigating officer Detective Chief Inspector Dave Cole said: "This was a devastating incident that has tragically led to Paul's death.
Police in Edward Burdis Street, earlier this week.
Thanks, {{email}} has been added to our newsletter. If this is the first time you have subscribed to emails from JPIMedia Ltd, the publishers of Sunderland Echo, please check your inbox to verify your email address.
"Our thoughts are with his family and friends at this difficult time, and our officers will continue to offer them any support that they may need.
"This assault has come following a disturbance in the street and we understand a number of people were in the area, so may have seen something.
"Residents are likely to have heard raised voices prior to the assault and may have witnessed an argument outside of an address.
"We are committed to determining the circumstances surrounding Paul's death.
"One person has been arrested in connection with the ongoing investigation, and officers will remain in the area to carry out enquiries and offer any reassurance to residents.
"I would like to thank members of the public who have already got in touch and passed on information to police, and would ask any witnesses yet to come forward to please pick up the phone."
Anyone who can assist the police investigation is asked to call 101 quoting log 132 12/05/19 or Crimestoppers anonymously on 0800 555 111.
Information can also be reported online at www.northumbria.police.uk
Best In Sunderland
More from Sunderland Echo


Our Layered Name Ring is the perfect gift for any mother, an exquisite statement of love for your children you can carry with you always. Whether you're treating yourself to this simply exquisite ring, or looking for a thoughtful present for that special mother in your life, this personalized layered name ring is definitely a purchase she will absolutely fall in love with.
We designed and crafted this unique ring from the finest quality sterling silver, and this is available to be plated in 24k gold or rose gold.
On top of this durable yet elegant band is a custom engraving, with any names of your choice, and the amount of names you'd prefer. A truly one-of-a-kind piece you will cherish forever, Order yours today and enjoy free shipping worldwide!
You can return new, unopened jewelry sold by oNecklace.com within 90 days of delivery. Please note that there will be a 30% restocking fee on all items.
In the event you receive a damaged piece of jewelry or a piece of jewelry with a mistake, please contact us immediately via the 'Email" icon shown on the bottom left of this window and we will do everything we can to be sure you are 100% satisfied with your order.
How do I keep my jewelry looking new?
This was for my granddaughter and she's worn it every day! I was also very happy with quality of chain.
Really nice, quality wise. The one for kid is the same size than the one for adults. I thought it will be smaller like the chain. But it's ok. Not desapointed at all.


To ensure the safety of goods and customer satisfaction, Lombok Marketplace tests the feasibility of packing of the materials used and the ways and conditions to be used. Because, every item has a special handler to keep it safe.
1. Before packing the item, we determine what expedition company we will use, how long the estimated shipment is. Thus consumers will be very easy to see the status of goods and consumers do not have to worry anymore because we use the expedition that has been guaranteed security.
2. Goods you have ordered we will analyze the type. Whether the goods include crockery, liquid, and so forth.
3. The goods are then we coated with a burble wrap that serves as a silencer and shock from the outside.
4. Not only burble wrap, we also use Styrofoam or polystyrene to maintain the integrity of goods.
5. After the goods are coated with the above items, we then wrap with corrugated sheet or corrugated paperboard whose purpose is to withstand shocks and pressure from the outside.
6. For perishable items, we also add a kind of wooden case to protect the goods during the delivery up to the customer's hand.
Happy shopping at Marketplace Lombok and enjoy the benefits and safety.


Although the Yahoo! app is a native iOS app, MobileSafari's CSS3 support seems powerful enough that I thought it would be fun to try re-implementing this small feature using only web technology.
By using a border-radius on the .sun-path we can use the .sun-animation div as the yellow filling. When we animate the expansion of that div it should show, like the native app, the evolution of the sun through the day.
The original Yahoo app animates the filling of the area below the arc, using what looks like a custom easing function. The built-in ease-out function that CSS transition supports should be a a pretty close approximation so we'll use that.
To get the perfect smoothness, we want the animation to be hardware accelerated. On iOS, this means using a CSS3 transform. However, MobileSafari fails to observe the overflow: hidden property over the border radius. Instead of filling in the area under our arc, it glitches and fills in a rectangle until the animation is complete, (at which point the border-radius is observed again).
This will grow the yellow translucent area over a two second period and ease the speed of the animation as the glow approaches its final destination.
Adding the sun that travels along the arc involves a few things: first, finding a way to pictorially render a sun , then deciding how to make the sun travel, and finally synchronizing the path of the sun so it moves with the expanding area below the arc.
Unicode is a wonderful thing: rather than create an image in photoshop we can use one of two sunshine characters and apply color and text-shadow to have the sun really shine. If you have the correct font support, these characters should just work: ☼ ☀. If not, visit the unicode reference pages for "black (or white) sun with rays".
// the bottom-left of the widget.
Now it's starting to look like the real, native weather widget. However, if you look closely at the running codepen you'll notice that the movement of the sun isn't 100% in sync with the filling of the arc!
At this point we need to stop and take a step back. Why aren't they in sync? It's because the expanding width only travels on a horizontal distance but the arc of the sun travels along the entire arc: the sun have to go a longer distance. Because both animations are specified (in the transition propery) to take the same amount of time, their horizontal position is clearly not going to stay in sync when they're traveling different distances.
This is complicated further by the presence of an easing function: we could figure out the mathematics of a linear animation, and even let the browser know using CSS (to guarantee the hardware acceleration). But as soon as we want to use a non-linear easing function like ease-out, the mathematics becomes a bucket-load more complex and we'd have to start generating an arbitrarily large number of classes just to make everything work smoothly. That would not be a cool hack, or a good use of CSS.
CSS alone is not enough for all animations that look (but aren't) very simple.
Experimenting with a key-framed approach using -webkit-animation to improve the synchronization of the sun and the glow.
I have a series of other articles planned about how we can use CSS to incorporate some of the best UI techniques of the Yahoo! iOS weather app: it contains a UX gold mine of attention to detail. In the meantime, Chris Coyier of CSS Tricks has also published a great tutorial on how to recreate the interactive side-swiping parallax scrolling feature of the app.
Follow @LeeMallabone to find out when my follow-up posts are published, and for more front-end tips & tricks every two weeks.
Have you come across many browser bugs in the mobile world? Got any epic CSS3 hacks to share? Let me know in the comments below, thanks for reading!
You could use images with the id's for the animations instead of nesting multiple div's with background images, but nice post on basic animations.
One nice consequence of using divs is that the animation doesn't need to block waiting for image resources before it can start.


How Do You Calculate Radioactive Decay?
An element's radioactive decay can be determined through a single equation which requires imputing the isotope's half life, its rate of decay and the decay time since the rate of decay is measured.
Every isotope has its own half-life. The half-life is the amount of time it takes for a given quantity of the isotope to lose half of its radioactivity. It is a constant and can be found in reference material. The rate of decay, also referred to as the activity of the isotope, is not a constant because it is dependent on the amount of material being measured. This number is measured in atoms per second and then converted to a mathematical unit called a curie. If trying to determine the radioactive decay at the exact moment that the activity is measured, only these two numbers are required for the equation. The radioactive decay is determined by multiplying the rate of decay and the half-life.
However, to determine the decay at different times after measuring the activity, find the natural log of the time elapsed divided by the isotope's half-life. Then multiply that number by the calculated rate of decay taken at the time referenced by the equation.
What Is a Radioactive Element?
How Do You Calculate Exponential Growth and Decay?


text:
package de.cosmocode.collections.tree;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import de.cosmocode.collections.tree.iterator.LevelOrderIterator;
import de.cosmocode.collections.tree.iterator.PostOrderIterator;
import de.cosmocode.collections.tree.iterator.PreOrderIterator;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 *
 This is an abstract implementation of {@link Tree}.
 * It delegates most methods to getRoot().
 *

 *
 The following methods are left without an implementation:

 *

 *
{@link #getRoot()}

 *
{@link #setRootElement(TreeNode)}

 *

 *
 * @author Oliver Lorenz
 *
 * @param <E>
 */
public abstract class AbstractTree<E> implements Tree<E> {

    /**
     * Indicates that the given root element is null.
     * Can be used in a NullPointerException.
     *
     * @deprecated should be replaced with {@link Preconditions#checkNotNull(Object, Object)}
     */
    @Deprecated
    public static final String ERR_ROOT_NULL = "root must not be null";

    private final Iterable<E> preOrderIterable = new Iterable<E>() {

        @Override
        public Iterator<E> iterator() {
            return new PreOrderIterator<E>(getRoot());
        }

        @Override
        public String toString() {
            return Iterables.toString(this);
        }

    };

    private final Iterable<E> postOrderIterable = new Iterable<E>() {

        @Override
        public Iterator<E> iterator() {
            return new PostOrderIterator<E>(getRoot());
        }

        @Override
        public String toString() {
            return Iterables.toString(this);
        }

    };

    private final Iterable<E> levelOrderIterable = new Iterable<E>() {

        @Override
        public Iterator<E> iterator() {
            return new LevelOrderIterator<E>(getRoot());
        }

        @Override
        public String toString() {
            return Iterables.toString(this);
        }

    };

    /**
     * Returns an {@code Iterable<T>} that returns a new {@link PreOrderIterator}
     * on each call to iterator().
     * @return a pre-ordered Iterable of this tree
     * @see TraverseMode#PRE_ORDER
     */
    protected Iterable<E> getPreOrderIterable() {
        return preOrderIterable;
    }

    /**
     * Returns an {@code Iterable<T>} that returns a new {@link PostOrderIterator}
     * on each call to iterator().
     * @return a post-ordered Iterable of this tree
     * @see TraverseMode#POST_ORDER
     */
    protected Iterable<E> getPostOrderIterable() {
        return postOrderIterable;
    }

    /**
     * Returns an {@code Iterable<T>} that returns a new {@link LevelOrderIterator}
     * on each call to iterator().
     * @return a level-ordered Iterable of this tree
     * @see TraverseMode#LEVEL_ORDER
     */
    protected Iterable<E> getLevelOrderIterable() {
        return levelOrderIterable;
    }

    @Override
    public TreeNode<E> addChild(E childData) {
        return getRoot().addChild(childData);
    }

    @Override
    public void addChildNode(TreeNode<E> child) {
        getRoot().addChildNode(child);
    }

    @Override
    public List<TreeNode<E>> addChildren(E... children) {
        return getRoot().addChildren(children);
    }

    @Override
    public boolean contains(TreeNode<E> descendant) {
        return getRoot().contains(descendant);
    }

    @Override
    public TreeNode<E> getChildAt(int index) throws IndexOutOfBoundsException {
        return getRoot().getChildAt(index);
    }

    @Override
    public Collection<TreeNode<E>> getChildren() {
        return getRoot().getChildren();
    }

    @Override
    public int getNumberOfChildren() {
        return getRoot().getNumberOfChildren();
    }

    @Override
    public void insertChildAt(int index, TreeNode<E> child) throws IndexOutOfBoundsException {
        getRoot().insertChildAt(index, child);
    }

    @Override
    public void removeChildNode(TreeNode<E> child) {
        getRoot().removeChildNode(child);
    }

    @Override
    public void removeChildAt(int index) throws IndexOutOfBoundsException {
        getRoot().removeChildAt(index);
    }

    @Override
    public void setChildren(Collection<TreeNode<E>> children) {
        getRoot().setChildren(children);
    }

    @Override
    public List<TreeNode<E>> toPreOrderedList() {
        final List<TreeNode<E>> list = Lists.newLinkedList();
        walkInPreOrder(getRoot(), list);
        return list;
    }

    @Override
    public Iterable<E> traverse(final TraverseMode mode) {
        switch (mode) {
            case PRE_ORDER: {
                return getPreOrderIterable();
            }
            case POST_ORDER: {
                return getPostOrderIterable();
            }
            case IN_ORDER: {
                throw new UnsupportedOperationException("not yet implemented");
            }
            case LEVEL_ORDER: {
                return getLevelOrderIterable();
            }
            default: {
                throw new IllegalArgumentException("Unknown TraverseMode " + mode);
            }
        }
    }

    @Override
    public abstract TreeNode<E> getRoot();

    @Override
    public abstract void setRootElement(TreeNode<E> rootElement);

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getRoot() == null) ? 0 : getRoot().hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        return this == obj || obj != null && obj instanceof Tree<?> && this.equals((Tree<?>) obj);
    }

    @Override
    public boolean equals(final Tree<?> t) {
        // the null check is for convenience, so that equals never breaks
        if (getRoot() == null) {
            return t.getRoot() == null;
        } else {
            return getRoot().equals(t.getRoot());
        }
    }

    /**
     * Walks the Tree in pre-order style. This is a recursive method, and is
     * called from the toList() method with the root element as the first
     * argument. It appends to the second argument, which is passed by reference
     * as it recurses down the tree.
     * @param element the starting element.
     * @param list the output of the walk.
     */
    private void walkInPreOrder(TreeNode<E> element, List<TreeNode<E>> list) {
        list.add(element);
        for (TreeNode<E> data : element.getChildren()) {
            walkInPreOrder(data, list);
        }
    }

}


If compliance is a concern a one time treatment with high dose oral formulation is appropriate , IU over days with a follow up dose in 3 months if necessary [ 2 ]. He was in the 50th percentile for both height and weight at his 2 month visit, but has fallen to below the 3rd percentile for weight and is at the 3rd percentile for height. Some formulations of vitamin D may contain propylene glycol, which is toxic at high doses so caution is advised [ 2 ]. A large observational study looked at the relationship between vitamin D and fatigue in young women. Following vitamin D replacement, her BDI was 16 mild depression. He is appropriately diagnosed with failure to thrive at this visit based on deviation across two major percentiles on standardized growth curves.
J Clin Sleep Med 6: If this association is confirmed, it may improve how we treat depression.
If compliance is a concern a one time treatment with high dose oral formulation is appropriateIU over days with a follow up dose in 3 months if necessary [ 2 ]. J Allergy Clin Immunol It directly interacts with the cells that are responsible for fighting infection 4.
The diagnosis of rickets was made and the patient was started on IU of vitamin D and calcium carbonate mg daily. He has been exclusively breastfed and his mother has not introduced solid foods as of yet to his diet.
Prostaglandin D2 functions as a physiologic regulator of sleep and affects the central nervous system homeostatic sleep pressure Fig. Impaired Wound Healing Slow healing of wounds after surgery or injury may be a sign that your vitamin D levels are too low.
There is limited prevalence estimates for vitamin D deficiency rickets in North America and the United Kingdom. A few studies have found that taking high-dose vitamin D supplements may reduce various types of pain in people who are deficient 39 Metaphyseal fraying and cupping of distal radius and ulna and the distal aspects of the second through fifth metacarpals.
It is the most common metabolic bone disease in the world and is easily treatable as well as preventable with sun exposure and dietary supplementation [ 1 ]. Immunology In one case, a woman who complained of chronic daytime fatigue and headaches was found to have a vitamin D blood level of only 5.
J Clin Sleep Med 8: Conclusions While rickets is a disease that has plagued society for many centuries it is certainly still a significant cause for both skeletal and non-skeletal complications in today's culture. The exact relationship between vitamin D and depression is not understood, however, and the few randomized controlled trials on this have hinted at a causal relationship.
Education on proper nutrition during pregnancy and supplementation during breastfeeding is necessary to prevent its growing resurgence. One study examined the association between vitamin D levels and back pain in more than 9, older women. However, when hair loss is severe, it may be the result of essay on the proverb god helps those who help themselves disease or nutrient deficiency.
Am J Clin Nutr Paper presented at: Vitamin D is primarily made in the skin after exposure to UV-B radiation to nm wavelengths [ 2 ]. Radiographic improvement should manifest within 3 months of appropriate treatment.
Regardless of these findings, adequate vitamin D intake and maintaining blood levels within the optimal range may be a good strategy for protecting bone mass vitamin d case study reducing fracture risk.
At presentation, her BDI was 21; her vitamin D level was These classic findings may be paired with a separation of the periosteum from the diaphysis secondary to unmineralized osteoid when evaluating radiographic evidence of rickets [ 13 ]. Feeling tired can have many causes, and vitamin D deficiency may be one of them.
Introduction Rickets is often considered an "old" disease, a nutritional deficiency that has plagued communities for centuries. A skeletal survey was ordered showing metaphyseal fraying and cupping of bilateral distal femurs, bilateral proximal and distal tibiae and fibulae, bilateral proximal and distal humeri, bilateral distal radii and ulni and the distal aspects of 2nd through the 5th metacarpals most consistent with rickets of the extremities, see radiograph 1 and 2.
His mother and father are of normal stature.
Phosphate was low at 2. Further increased risk is associated with dark-skinned individuals, lack of UV-B exposure, solely breastfed infants and prematurity. Results wedding speech sample best man a test-tube study suggest that the vitamin increases the production of compounds that are crucial for forming new skin as part of the wound-healing process The re-emergence of vitamin D deficiency in westernized societies is thought to be multifactorial secondary to poor dietary intake, popularization of breastfeeding, and diminished exposure to sunlight.
In a large observational study in more than 1, middle-aged women in menopause or postmenopause, researchers found a strong link between low vitamin D levels and low bone mineral density Proper childhood maintenance visits with growth and development screenings are critical for early detection of this easily treatable condition.
Patient 2 Patient 2 was 58 years old, and she had type 2 diabetes. It found that those with severe vitamin D deficiency were dissertation illustration likely to have higher levels of inflammatory markers that can jeopardize healing For more information on how to reduce fatigue, consider reading about the 11 best vitamins and supplements to boost energy.
His mother and father are of normal stature. The Bottom Line Vitamin D deficiency is incredibly common and most people are unaware of it. A number of studies have found that taking vitamin D supplements at a dosage of up to 4, IU daily may reduce your risk of respiratory tract juno character analysis essay89.
Vitamin D helps maintain bone health in a number of ways. Case studies have shown philippine statistics authority application letter very low blood levels can cause fatigue that has a severe negative effect on quality of life 11 A level of 25 hydroxy vitamin D OH D less than You can also find a variety of vitamin D supplements on Amazon.
Alkaline phosphatase was elevated at on repeat Patient 1 was treated with vitamin D replacement therapy, and her BDI after treatment was 12, representing mild depression. Summary Low blood levels of vitamin D may be a cause or contributing factor to bone pain and lower back pain.
His review of systems is negative for emesis, diarrhea, fever, appetite changes, swallowing abnormalities, respiratory symptoms, apnea, repeated acute illnesses, or frequent injuries.
Arch Biochem Biophys J Clin Endocrinol Metab However, a controlled study found that women who were vitamin D deficient experienced no improvement in bone mineral density when they took high-dose supplements, even if their blood levels improved In review studies, researchers have linked vitamin D teenage pregnancy essay tagalog to depression, particularly in older adults 19 In younger infants months 1, IU daily has been suggested.
One study on people who had dental surgery found that certain aspects of healing were compromised by vitamin D deficiency Laboratory studies ordered were complete metabolic profile, thyroid stimulating hormone TSHlead level, and complete blood count CBC.
MS revised the manuscript critically for important intellectual content. Postgrad Med J Low bone mineral density is an indication that your bones have lost calcium and other minerals.
Her presenting BDI was 26, and her vitamin D level was 8. His catch-up growth has lead to a current weight at 2 years of age in the 45th percentile and height in the 30th percentile Figure 1. Its supply stems from two well-known sources: You can either increase your sun exposure, eat more vitamin-D-rich foodssuch as fatty fish or fortified dairy products.
Though vitamin D deficiency is commonly understood to be disproportionately represented in underserved populations Kakarala et al.
A skeletal survey was ordered showing metaphyseal fraying and cupping of bilateral distal femurs, bilateral proximal and distal tibiae and fibulae, bilateral proximal and distal humeri, bilateral distal radii and ulni and the distal aspects of 2nd through the 5th metacarpals most consistent with rickets of the extremities, see radiograph 1 and 2.
If you think you may have a deficiency, it's important that you speak to your doctor business plan for medicine store get your blood levels measured. There is no family history of malabsorptive conditions.
Increased awareness of potential dangers of sun exposure, skin-protective behavior, and urbanization of the population are thought to be some of the factors underlying the increase in prevalence of vitamin D deficiency and insufficiency Holick Figure 1 Growth Chart: On the other hand, most of the controlled trials, which carry more scientific weight than observational studies, didn't show a link between the two For one, it improves your body's absorption of calcium.
Skeletal survey: While a full sleep evaluation before vitamin D repletion revealed the presence of heavy daytime napping and pervasive fatigue, the PSG did not show evidence of sleep disordered breathing or a sleep-related movement disorder McCarty Curr Opin Allergy Clin Immunol Argumentative essay on zero tolerance in schools areata is an autoimmune disease characterized by severe hair junior course personal problem solving skills from the head and other parts of the body.
His estimated weight needs were calculated to 0. Although a causal relationship cannot be confirmed by this case alone, the temporal relationship as well as biological plausibility makes this a possibility.
Metaphyseal fraying and cupping involving bilateral distal femurs, bilateral proximal and distal tibiae and fibulae, bilateral proximal and distal humeri. Fortunately, a vitamin D deficiency is usually easy to fix. A depressed mood may also be a sign of vitamin D deficiency. Research presented at the 94th Annual Meeting of The Endocrine Society examined if vitamin Where do you put your name on an annotated bibliography apa replacement in vitamin D deficient patients with major depressive disorder would have an effect on depressive symptoms.
McCarty postulated that vitamin D deficiency may contribute to symptoms of sleepiness via components of inflammatory cascades, including known sleep regulating substances McCarty et al.
Getting enough of this vitamin is important for preserving bone mass as you get older. Hair loss is often attributed to stresswhich is certainly a common cause. Am J Physiol His mother was also instructed to keep a strict food diary. However, even blood levels that aren't extremely low may have a negative impact on your energy levels.
Hypertension in Blacks: a literature review.


www.kurser.dk is a platform where the users can create and find courses. This is both for private and companys, who's looking for courses to develop themselves or their employees.
The platform is built, so it's easy to create, but also to find courses you're interested in. Furthermore, there's an advanced algorithm behind how the courses are shown, and also an upgraded admin panel where the client can run the platform from. It has been a longer process, since there's a lot of stuff that has to work together, both the stuff you see when you're visiting the site, but also the coding behind it.
After a lot of development and testing, we can finally proudly present a functional, user-friendly, and last but not least, beautiful website.
You can explore the website by tapping the button below.


To preserve those gorgeous garlic flavours and extend shelf-life, then one should store garlic in terracotta garlic pots (or garlic keepers).
Designed to provide natural garlic storage conditions for a garlic friendly environment!
Whole bulbs of garlic will keep for several months or more when stored in a garlic pot which will keep the garlic dry & at room temperature, restricting light & providing ample air circulation. Definitely, do not go refrigerate your garlic!
All of our garlic pots have holes designed to promote good ventilation.
Our garlic keepers are hand made by ourselves in the UK from English terracotta.
CLICK HERE for instructions on how to keep garlic in garlic pots.


text:
Q: C# Editing a text file I have a single text file that I am trying to edit. Basically the text file holds data for a request in a business. So it'll store the name, employee ID, request type, request total, request status, and the date and time in that order. I have to be able to edit the total amount for a selected line. I'm using a list view to be able to select the item. So for example I have to take Smith's request, and edit the $2.00 and change it to let's say $4.00.

Ryan Rock ,345 ,Food ,$456.00 ,Pending ,4/2/2015 3:48:45 PM
Smith ,4567 ,Food ,$2.00 ,Pending ,4/2/2015 6:26:37 PM
Jerry ,444 ,Travel ,$22.00 ,Pending ,4/2/2015 6:26:47 PM

private void btnModify_Click(object sender, EventArgs e)
    {
        foreach (ListViewItem item in listView1.Items)
            if (item.Selected)
            {
                string selected = item.Text.ToString();
                string str;

                double total;
                bool totalCheck = double.TryParse(txtTotal.Text, out total);

                    if (totalCheck)
                    {
                        var lines = File.ReadAllLines("../../textFile/ExpenseReportingData.txt");
                        lines[3] = "7";
                        File.WriteAllLines("../../textFile/ExpenseReportingData.txt", lines);
                    }
                    else
                    {
                        MessageBox.Show("Please Enter A Valid Ammount", "Error");
                    }
            }
    }

Any help would be greatly appreciated. Thanks.

A: to edit a value on a specific line u could do something like this :
for (int i = 0; i < lines.Length; i++)
        {
            string[] lineData = lines[i].Split(',');//split the line into an array ["Smith" ,"4567" ,"Food" ,"$2.00" ,"Pending" ,"4/2/2015 6:26:37 PM"]
            if (lineData[0] == "Smith")//0 is the index of the client name
            {
                lineData[3] = "$4.00";//modifie the value
                lines[i] = String.Join(",", lineData);
                File.WriteAllLines("../../textFile/ExpenseReportingData.txt", lines);
            }
        }

but I wouldn't recommend it , you should use a database to hold your data and each client has to have an unique id (many clients can have the same name this would create issues)
or you can try to use a XMl / JSON type of formatting as your text file

redpajama_set_name: RedPajamaStackExchange