Skip to content

Instantly share code, notes, and snippets.

@iopq
Created November 20, 2016 08:20
Show Gist options
  • Save iopq/007ac1a0c2e6526dbb2b3f76731f9f2a to your computer and use it in GitHub Desktop.
Save iopq/007ac1a0c2e6526dbb2b3f76731f9f2a to your computer and use it in GitHub Desktop.
extern crate core;
extern crate html5ever;
#[macro_use]
extern crate string_cache;
#[macro_use]
extern crate tendril;
use html5ever::parse_document;
use html5ever::rcdom::{Element, Handle, RcDom};
use html5ever::serialize::serialize;
use html5ever::tree_builder::interface::{AppendNode, AppendText, TreeSink};
use std::io;
use std::rc::Rc;
use tendril::TendrilSink;
fn main() {
let stdin = io::stdin();
let mut dom: RcDom = parse_document(RcDom::default(), Default::default())
.from_utf8()
.read_from(&mut stdin.lock())
.unwrap();
insert_into_head(&dom.document.clone(), &mut dom);
walk(&dom.document.clone(), &mut dom);
serialize(&mut io::stdout(), &dom.document, Default::default()).unwrap();
}
fn walk(handle: &Handle, mut dom: &mut RcDom) {
let mut node = handle.borrow_mut();
if let Element(ref name, _, ref mut attrs) = node.node {
if name.local == atom!("img") {
for attr in attrs.iter_mut() {
if attr.name.local == atom!("id") && attr.value == format_tendril!("id3") {
attr.value = format_tendril!("randomid3456346");
}
}
}
}
for child in node.children.iter() {
walk(&child.clone(), &mut dom);
}
}
fn insert(handle: &Handle, dom: &mut RcDom) {
let new_element: Handle = dom.create_element(
qualname!(html, "style"), vec![]);
dom.append(new_element.clone(), AppendText(format_tendril!("#randomid3456346 {{ width: 100px }}")));
dom.append(handle.clone(), AppendNode(new_element));
}
fn insert_into_head(handle: &Handle, mut dom: &mut RcDom) -> bool {
let mut found = false;
{
let node = handle.borrow();
if let Element(ref name, _, _) = node.node {
if name.local == atom!("head") {
found = true;
}
}
if !found {
for child in node.children.iter() {
if insert_into_head(&child.clone(), dom) {
return true;
}
}
}
}
if found {
insert(&handle, &mut dom);
}
found
}
fn find_head(handle: &Handle) -> Option<&mut Handle> {
let node = handle.borrow();
match node.node {
Element(ref name, _, _) if name.local == atom!("head") =>
return Some(&mut handle), //fails because borrow checker
_ => {
if node.children.len() > 0 {
for child in node.children.iter() {
return find_head(child)
}
}
}
}
None
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment