Skip to content

Instantly share code, notes, and snippets.

@dhaffner
Last active August 29, 2015 13:58
Show Gist options
  • Save dhaffner/10327161 to your computer and use it in GitHub Desktop.
Save dhaffner/10327161 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>title</title>
<style type="text/css">
body, html {
width: 100%;
height: 100%;
}
body {
font-size: 20px;
line-height: 30px;
background-color: rgba(0, 0, 255, 0.4);
}
body * {
line-height: inherit;
}
span {
background-color: rgba(255, 255, 255, 0.6);
white-space: nowrap;
}
span.wrapped {
outline: 2px solid rgba(255, 0, 0, 0.6);
background-color: rgba(255, 255, 255, 0.1);
}
span.end-of-line {
outline: 2px solid rgba(0, 255, 0, 0.6);
background-color: rgba(255, 255, 255, 0.1);
}
</style>
</head>
<body>
<div class='wrap-watch'>
Here is a sentence with a bunch of words in it. Trying to <span>determine where line-wraps will happen.</span>
<span>Hannibal Buress</span> is a stand-up comedian, <span>actor and television writer currently</span> living in <span>New York City</span>. His latest special <span>"Live from Chicago"</span> airs March 29th on Comedy Central.
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="/wrapped.js" type="text/javascript"></script>
</body>
</html>
// Goal: selector for matching elements that are line-wrapped [line-broken, etc]
// Ideas:
// '... span:nth-line(-)' match a span that is on the nth line of text in its
// container
//
// '.. span:wrapped' match a span that is line-wrapped (not on 1st line)
// '.. span:orphan' match span that is last element on its line
var wrapped = {};
(function(self, $) {
var $body = $('body'),
$spans = $('span'),
displayType = /^inline/;
function offsetTop(node, rect) {
return node.offsetTop ||
(isTextNode(node) && (rect || getBoundingClientRect(node)).top);
}
function isTextNode(node) {
return node.nodeType == 3;
}
function isInline(node) {
return displayType.test($(node).css('display'));
}
function isEmptyNode(node, rect) {
var rect = rect || getBoundingClientRect(node);
return rect.width + rect.height === 0;
}
function getBoundingClientRect(textNode) {
if (document.createRange) {
var range = document.createRange();
range.selectNodeContents(textNode);
if (range.getBoundingClientRect) {
return range.getBoundingClientRect();
}
}
}
function textOrInline(node) {
return isTextNode(node) || isInline(node);
}
$.expr[':'].wrapped = function(obj, index, meta, stack) {
var prev = obj.previousSibling;
if (!textOrInline(prev) || isEmptyNode(prev))
return false;
return textOrInline(obj) && offsetTop(prev) < offsetTop(obj);
};
// end-of-line(node) = inline(node) && inline(node.next) && ..
$.expr[':']['end-of-line'] = function(obj, index, meta, stack) {
var next = obj.nextSibling;
if (isEmptyNode(next))
return false;
return textOrInline(obj) && offsetTop(next) > offsetTop(obj);
};
$body.click(function() {
$spans.each(function() {
var $self = $(this);
$self.toggleClass('wrapped', $self.is(':wrapped'));
$self.toggleClass('end-of-line', $self.is(':end-of-line'));
});
});
console.log('wrapped.js');
})(wrapped, $);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment