When mousing into a .thumb element I'd like to change #full-image's src to the .thumb element's src. What I have that is not working:
(defaction change-src [selector src]
[selector] (ef/set-attr :src src))
(defaction thumb-hover []
[".thumb"] (events/listen :mouseenter
#(change-src "#full-image"
; Looks like the following needs to be replaced
; with some $(this).attr('src') equivalent.
(ef/from % (ef/get-attr :src)))))
Can anyone point me to where I can use this? Enfocus is built on domina which is built on closure libs which is built on plain js. I don't know which layer I should be looking for this or if that is even the idiomatic solution.
I got it working with .-currentTarget. See http://ckirkendall.github.io/enfocus-site/#doc-events and http://docs.closure-library.googlecode.com/git/class_goog_events_Event.html.
(defaction change-src [selector src]
[selector] (ef/set-attr :src src))
(defaction thumb-hover []
[".thumb"] (events/listen :mouseenter
#(change-src "#full-image"
(ef/from (.-currentTarget %)
(ef/get-attr :src)))))
Related
I'm trying to change the color of the link text in a link to yellow on a page that another script (not controlled by me) generates. More specifically, I'm searching for specific text in two tables on this page. Once I find the text (which are hyperlinks) I want to change their color to yellow.
I am using HTML::Element and I can find the text easily. The problem is, there is no specified link color, so the links use the default value of blue. I am trying to add the HTML element of font color to the tag but I'm not having much luck.
If I try using something like (where "$a" is the HTML::Element object for the link I'm trying to edit):
$a->attr("font color", "yellow");
It adds the attribute but doesn't change the text color of the link content.
if I try something like:
my $content = $a->content;
$content->attr("font color", "yellow");
That only adds the text
<font color=yellow>
to the content without, again, changing the actual content text color.
Trying to splice it in doesn't work either.
I finally hit upon this:
my $yellowFont = HTML::Element->new('font', 'color' => 'yellow');
foreach my $item_ref ($a->content_refs_list) {
next if ref $$item_ref;
$yellowFont->push_content($$item_ref);
}
print $yellowFont->as_HTML, "\n";
Which works beautifully in the sense that it creates:
<font color="yellow">201301022150-Job5</font>
But that change isn't reflected in the html document!
I'm at a loss as to how to insert the font color attribute into the original html document.
Below is my entire script. It's a mess because I've been trying a variety of different methods without success.
#!/usr/local/bin/perl
use warnings;
use strict;
use HTML::TableExtract qw(tree);
use Data::Dumper qw(Dumper);
my #jobList = ();
if ($ARGV[0]) {#jobList = $ARGV[0];} else {die ("Need list of jobs as argument\n")};
my $ddHTMLFile = "./tmp_aptg";
my $te1 = HTML::TableExtract->new( depth => 1, count => 0);
my $te2 = HTML::TableExtract->new( depth => 1, count => 1);
$te1->parse_file($ddHTMLFile);
$te2->parse_file($ddHTMLFile);
my $table1 = $te1->first_table_found;
my $table2 = $te2->first_table_found;
my $table1_tree = $table1->tree;
my $table2_tree = $table2->tree;
foreach my $a ($table1_tree->find_by_tag_name("a")) {
my $href = $a->attr("href");
if ($href =~ m/$jobList[0]/) {
my $yellowFont = HTML::Element->new('font', 'color' => 'yellow');
foreach my $item_ref ($a->content_refs_list) {
next if ref $$item_ref;
$yellowFont->push_content($$item_ref);
}
#print $yellowFont->as_HTML, "\n";
$a->replacewith
$a->dump;
#my $table1_html = $table1_tree->as_HTML;
#my $document1_tree = $te1->tree;
#my $document1_html = $document1_tree->as_HTML;
#my $document_html = $document1_html;
#print "$document_html";
}
}
Each time somebody uses the <font> tag, we have to sacrifice a hecatomb of cute kittens to the angry webdevs that were promised semantic markup. A font in itself has no semantics. Instead, such things can be easily done via CSS which unsuprisingly excels at changing the color of elements.
To set the color of one element to yellow, we have to add the following code to the style attribute:
color: yellow !important;
Something like
$a->attr(style => "color: yellow !important;");
is likely to do the trick, although that would overwrite any previous contents. We could try to append our color to the previous contents, but we have no guarantee that the CSS already there is valid.
If the target browsers understand CSS3 (*sigh*), we could use some nice selectors to do that job for us, like
<style>
table a[href~="$foo"] { color: yellow !important }
</style>
where $foo holds a sane string to be literally matched (no regexes).
Here is a data-url you can copy&paste into your address bar to see this (hopefully) working:
data:text/html,<style>table a[href~="foo"] { color: yellow !important }</style><table><tr><td>bar</td><td>foo</tr></table>
The other solution would be to create a new <span> element that carries the CSS, and is the sole child of the link. The former childs of <a> would then be childs of the <span>.
# not tested, but looks reasonable
my $span = HTML::Element->new("span", style => "...");
my #childs = $a->detach_content;
$span->push_content(#childs);
$a->push_content($span);
This is slightly different from the previous solution, but this difference shouldn't matter unless some advanced CSS tricks were used in the page layout.
If you really have to, you can adapt this solution to use font tags.
"pleease don't! can we haz <span>?" ← the kittens.
To see what you can do with the HTML element objects, see the HTML::Element documentation.
This is how my application layout page is looking (here is a part of it)
%html
%body
#main
.content
= yield
Sometimes (not always) I need to add "id" attribute to .content div. How can I do it from a html.haml page?
Note: I don't mean to do it in runtime using javascript.
UPDATE: thanks, but I forgot to mention that this "id" is different for each page. In other words, each html.haml page might have its own "id" for .content.
And another solution:
%html
%body
#main
.content{id: #content_id}
= yield
#some .html.haml page
- #content_id = "my_id"
If you don't define #content_id then .content would be without id.
You can just daisy chain ids and classes as much as you want
%html
%body
#main
.content#random-id.random-class
= yield
You can do this to add attributes like id to a tag:
.content{:id => "foo"}
You can add attributes via ruby a Hash and set the value through a conditional expression.
%html
%body
#main
.content{:id => (id_needed ? 'my_id' : nil)}
= yield
I am trying to create a histogram of the letters (a,b,c,etc..) on a specified web page. I plan to make the histogram itself using a hash. However, I am having a bit of a problem actually getting the HTML.
My current code:
#!/usr/local/bin/ruby
require 'net/http'
require 'open-uri'
# This will be the hash used to store the
# histogram.
histogram = Hash.new(0)
def open(url)
Net::HTTP.get(URI.parse(url))
end
page_content = open('_insert_webpage_here')
page_content.each do |i|
puts i
end
This does a good job of getting the HTML. However, it gets it all. For www.stackoverflow.com it gives me:
<body><h1>Object Moved</h1>This document may be found here</body>
Pretending that it was the right page, I don't want the html tags. I'm just trying to get Object Moved and This document may be found here.
Is there any reasonably easy way to do this?
When you require 'open-uri', you don't need to redefine open with Net::HTTP.
require 'open-uri'
page_content = open('http://www.stackoverflow.com').read
histogram = {}
page_content.each_char do |c|
histogram[c] ||= 0
histogram[c] += 1
end
Note: this does not strip out <tags> within the HTML document, so <html><body>x!</body></html> will have { '<' => 4, 'h' => 2, 't' => 2, ... } instead of { 'x' => 1, '!' => 1 }. To remove the tags, you can use something like Nokogiri (which you said was not available), or some sort of regular expression (such as the one in Dru's answer).
See the section "Following Redirection" on the Net::HTTP Documentation here
Stripping html tags without Nokogiri
puts page_content.gsub(/<\/?[^>]*>/, "")
http://codesnippets.joyent.com/posts/show/615
I have a string of HTML in Rails. I'd like to truncate the string after a certain number of characters not including the HTML markup. Also, if the split happens to fall in the middle of an opening and closing tag, I'd like to close the open tag/s. For example;
html = "123<a href='#'>456</a>7890"
truncate_markup(html, :length => 5) --> "123<a href='#'>45</a>"
the regular truncate function works fine, just pass :escape => false as an option to keep the HTML intact. eg:
truncate(#html_text, :length => 230, :omission => "" , :escape => false)
RubyOnRails.org
*Edit I didn't read the question very carefully (or at all TBH), so this answer does not solve this question... It IS the answer I happened to be looking for though, so hopefully it helps 1 or 2 people :)
There are two completely different solutions both with the same name: truncate_html
https://github.com/ianwhite/truncate_html : This is a gem and uses an html parser (nokogiri)
https://github.com/hgmnz/truncate_html : This is a file you put in your helpers directory. It uses regular expressions and has no dependencies.
You should solve this problem with CSS rather than Ruby. You are doing something that affects the DOM layout, and there is no way to programmatically devise a solution that will work consistently.
Let's say you get your HTML parser gem working, and you find a lowest common denominator character count that will work most of the time.
What happens if you change font sizes, or your site layout? You'll have to recalculate the character count again.
Or let's say your html has something like this in it: <p><br /></p><br /> That is zero characters, however it would cause a big chunk of blank text to be inserted. It could even be a <blockquote> or <code> tag with too much padding or margin to throw your layout totally out of whack.
Or the inverse, let's say you have this 3 ≅ λ (3 ≅ λ) That is 26 characters long, but for display purposes it is only 5.
The point being that character count tells you nothing about how something will render in the browser. Not to mention the fact HTML parsers are hefty pieces of code that can at times be unreliable.
Here is some good CSS to deal with this. The :after pseudo class will add a white fade to the last line of content. Very nice transition.
body { font-size: 16px;}
p {font-size: 1em; line-height: 1.2em}
/* Maximum height math is:
line-height * #oflines - 0.4
the 0.4 offset is to make the cutoff look nicer */
.lines-3{height: 3.2em;}
.lines-6{height: 6.8em;}
.truncate {overflow: hidden; position:relative}
.truncate:after{
content:"";
height: 1em;
display: block;
width: 100%;
position:absolute;
background-color:white;
opacity: 0.8;
bottom: -0.3em
}
You can add as many .lines-x classes as you see fit. I used em but px is just as good.
Then apply this to your element: <div class="truncate lines-3">....lots of stuff.. </div>
and the fiddle: http://jsfiddle.net/ke87h/
You could use the truncate_html plugin for this. It uses nokogiri and htmlentities gems and does exactly what the plugin name suggests.
We had this need in zendone.com. The problem was that the existing solutions were very slow when truncating long HTML documents (MBs) into shorter ones (KBs). I ended up coding a library based in Nokogiri called truncato. The library includes some benchmarks comparing its performance with other libs.
This will help you without any extra effort
raw your_string.truncate(200)
your_tagged_string.truncate(60).html_safe
You can use
truncate(html.gsub(/(<[^>]+>)/, ''), 5)
We can do that with the help of simple_format http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
html = "123<a href='#'>456</a>7890"
simle_format(truncate_markup(html, :length => 5))
=> "123 456 7890"
You can use the truncate method in combination with sanitize.
truncate(sanitize(html_content), length: 100, separator: '</p>', escape: false)
This will truncate your HTML using the separator but it can produce HTML without closing tags. To fix this we can use the sanitize method again, which will clean the HTML and add the missing tags.
sanitize(truncate(sanitize(html_content), length: 100, separator: '</p>', escape: false))
Solving this problem from the client side:
view:
<script>
$(function() {
$('.post-preview').each(function() {
var tmp_height = $(this).innerHeight();
if ((tmp_height > 100) && (tmp_height < 200)) {
$(this).addClass("preview-small");
}
else if (tmp_height >= 200) {
$(this).addClass("preview-large")
}
else {
//do nothing
}
});
});
</script>
css
.preview-small {
height: 100px;
overflow: hidden;
}
.preview-large {
height: 200px;
overflow: hidden;
}
I am trying to remove all the relative image path slashes from a chunk of HTML that contains several other elements.
For example
<img src="../../../../images/upload/1/test.jpg />
would need to become
<img src="http://s3.amazonaws.com/website/images/upload/1/test.jpg" />
I was thinking of writing this as a rails helper, and just passing the entire block into the method, and make using Nokogiri or Hpricot to parse the HTML instead, but I don't really know.
Any help would be great
Cheers
Adam
No need to reinvent the wheel, when the builtin 'uri' lib can do that for you:
require 'uri'
main_path = "http://s3.amazonaws.com/website/a/b/c"
relative_path = "../../../../images/upload/1/test.jpg"
URI.join(main_path, relative_path).to_s
# ==> "http://s3.amazonaws.com/images/upload/1/test.jpg"
One way to construct an absolute path given the absolute URL of the page and a relative path found on that page:
pageurl = 'http://s3.amazonaws.com/website/foo/bar/baz/quux/index.html'
relative = '../../../../images/upload/1/test.jpg'
absolute = pageurl.sub(/\/[^\/]*$/, '')
relative.split('/').each do |d|
if d == '..'
absolute.sub!(/\/[^\/]*$/, '')
else
absolute << "/#{d}"
end
end
p absolute
Alternatively, you could cheat a bit:
'http:/'+File.expand_path(File.dirname(pageurl.sub(/^http:/, ''))+'/'+relative)
This chunk might help:
html = '<img src="../../../../images/upload/1/test.jpg />'
absolute_uri = "http://s3.amazonaws.com/website/images"
html.gsub(/(\.\.\/)+images/, absolute_uri)