Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vCard/JSON extraction #19443

Closed
wants to merge 32 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
eb2c7e0
Merge pull request #11 from servo/master
niravjain Nov 13, 2017
015ef37
Merge pull request #12 from servo/master
CJ8664 Nov 22, 2017
43aeb7c
Added microdata module
niravjain Nov 24, 2017
f306835
Code to send msg from servo to servoshell (EmbedderMsg)
CJ8664 Nov 25, 2017
0530512
Merge branch 'master' of https://github.com/CJ8664/servo
CJ8664 Nov 25, 2017
f939632
naming convention
CJ8664 Nov 25, 2017
3d68d2a
trying serde_json crate
CJ8664 Nov 25, 2017
a4ed961
Uploading erroneous code
CJ8664 Nov 25, 2017
4628943
Uploading erroneous code
CJ8664 Nov 25, 2017
cbfc666
Merge remote-tracking branch 'refs/remotes/origin/serde_try' into ser…
CJ8664 Nov 25, 2017
146dd58
Merge pull request #13 from CJ8664/serde_try
CJ8664 Nov 25, 2017
9284187
serde json working for Hashmap
CJ8664 Nov 25, 2017
dd4dc70
Updated the servo-shell communication
CJ8664 Nov 29, 2017
43650c2
vCard working
CJ8664 Nov 29, 2017
19408a0
Adding adr to vCard
niravjain Nov 30, 2017
79d140d
Adding adr to vCard
niravjain Nov 30, 2017
aab6900
Merged vcard and json logic
CJ8664 Nov 30, 2017
35468f8
Fixed tidy errors
niravjain Nov 30, 2017
8cafd64
Updated code to pass the type of microdata as a parameter
CJ8664 Dec 1, 2017
87d1efa
Merge branch 'vcard' of https://github.com/CJ8664/servo into vcard
CJ8664 Dec 1, 2017
c580c3f
Added code to notify user via change in title
CJ8664 Dec 1, 2017
3cd9731
Created dummy test cases
CJ8664 Dec 1, 2017
d0cb12e
Removed JSON code and replaced with a stub
CJ8664 Dec 1, 2017
0ae2d08
Merge pull request #14 from CJ8664/vcard
CJ8664 Dec 1, 2017
7131823
Merge pull request #15 from servo/master
CJ8664 Dec 1, 2017
a3e5b9f
Updated manifest
CJ8664 Dec 1, 2017
0e5023d
Partially updated the code based on reviews
CJ8664 Dec 2, 2017
37f70c6
Fixed lint issues
CJ8664 Dec 2, 2017
543de1c
Fixed lint issues
CJ8664 Dec 2, 2017
a781bba
Merge fix
CJ8664 Dec 12, 2017
04a043d
Merge branch 'servo-master'
CJ8664 Dec 12, 2017
c740aab
Rebuild cargo
CJ8664 Dec 12, 2017
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Fixed tidy errors

  • Loading branch information
niravjain committed Nov 30, 2017
commit 35468f8a1b631f83414895a6daa4b7421d938288
@@ -923,7 +923,7 @@ impl Element {
&self.local_name
}

pub fn tag_name(&self) -> DOMString{
pub fn tag_name(&self) -> DOMString {
self.TagName()

This comment has been minimized.

Copy link
@jdm

jdm Dec 1, 2017

Member

You should be able to import ElementMethods and invoke TagName() directly from the caller.

This comment has been minimized.

Copy link
@vjhebbar

vjhebbar Dec 2, 2017

Contributor

This public method was added to test something, this will be removed.

}

@@ -12,39 +12,38 @@ use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::node::Node;
use dom::text::Text;
use serde_json;
use std::borrow::Cow;
use std::collections::HashMap;
use serde_json;

pub struct Microdata {}

This comment has been minimized.

Copy link
@jdm

jdm Dec 1, 2017

Member

Rather than an empty structure with static methods, we should use plain old functions in this file instead. Code in other modules can use microdata::parse instead.

#[derive(Serialize,Clone)]
#[derive(Clone,Serialize)]
#[serde(untagged)]
enum Data {
StrValue(String),
VecValue(Vec<Data>),
DataValue(Box<Data>),
HashValue(HashMap<String,Data>)
HashValue(HashMap<String, Data>)
}

impl Microdata {
//[Pref="dom.microdata.testing.enabled"]
pub fn parse(doc: &Document, node : &Node) -> HashMap<String, String> {
pub fn parse(doc: &Document, node: &Node) -> HashMap<String, String> {

This comment has been minimized.

Copy link
@jdm

jdm Dec 1, 2017

Member

Rather than returning a hashmap with two known keys, we should return a richer data type - a structure that contains two Option fields would be more clear.

This comment has been minimized.

Copy link
@vjhebbar

vjhebbar Dec 2, 2017

Contributor

Would an enum be suitable here? Something like

enum Microdata {
JSON(some type),
vCard(some type)
}
Construct it as Microdata::JSON(jsonString) or Microdata::VCARD(vcardString) based on conditional checks and return it as Option and use a match statement to get appropriate representation at the client end.

This comment has been minimized.

Copy link
@jdm

jdm Dec 2, 2017

Member

That would be sensible!

//let dup_doc = Cow::Borrowed(doc);
let serialized_vcard = Self::parse_vcard(doc);
let serialized_json = Self::parse_json(node);
let mut serialized_data : HashMap<String, String> = HashMap::new();
let mut serialized_data: HashMap<String, String> = HashMap::new();
serialized_data.insert("vcard".to_string(), serialized_vcard);
serialized_data.insert("json".to_string(), serialized_json);
return serialized_data;
}

pub fn parse_vcard(doc: &Document) -> String {

let ele = doc.upcast::<Node>();
let mut start_vcard = false;
let mut result : String = String::new();
let mut master_map : HashMap<String, HashMap<String, String>> = HashMap::new();
let mut master_key : String = String::new();
let mut result: String = String::new();
let mut master_map: HashMap<String, HashMap<String, String>> = HashMap::new();
let mut master_key: String = String::new();

result += "BEGIN:VCARD\nPROFILE:VCARD\nVERSION:4.0\nSOURCE:";
result += doc.url().as_str();
@@ -57,13 +56,13 @@ impl Microdata {

result += "\n";

for element in ele.traverse_preorder().filter_map(DomRoot::downcast::<Element>){
for element in ele.traverse_preorder().filter_map(DomRoot::downcast::<Element>) {

This comment has been minimized.

Copy link
@jdm

jdm Dec 1, 2017

Member

Please add comments like // Step 3.4 and // https://html.spec.whatwg.org/multipage/#concept-property-value as appropriate in these new methods to allow easily matching the implementation against the specification.

if element.is::<HTMLElement>() {
if element.has_attribute(&local_name!("itemtype")){
if element.has_attribute(&local_name!("itemtype")) {
let mut atoms = element.get_tokenlist_attribute(&local_name!("itemtype"), );
if !atoms.is_empty() {
let val = atoms.remove(0);
if val.trim() == "http://microformats.org/profile/hcard"{
if val.trim() == "http://microformats.org/profile/hcard" {
if !start_vcard {
start_vcard = true;
} else {
@@ -76,7 +75,7 @@ impl Microdata {
let mut atoms = element.get_tokenlist_attribute(&local_name!("itemprop"), );
if !atoms.is_empty() {
let temp_key = atoms.remove(0);
if element.has_attribute(&local_name!("itemscope")){
if element.has_attribute(&local_name!("itemscope")) {
master_key = String::from(temp_key.trim()).to_owned();
let dup_master_key = Cow::Borrowed(&master_key);
master_map.entry(dup_master_key.to_string()).or_insert(HashMap::new());
@@ -94,55 +93,49 @@ impl Microdata {
}

for (info_type, detail_map) in &master_map {

match info_type.as_str() {
"n" => {
let mut n_value: String = String::new();

let mut n_value : String = String::new();

let name_parts = ["family-name", "given-name", "additional-name", "honorific-prefix", "honorific-suffix"];
let name_parts = ["family-name", "given-name",
"additional-name", "honorific-prefix", "honorific-suffix"];
for part in name_parts.iter() {
if detail_map.contains_key(*part) {
n_value += format!("{};",detail_map.get(*part).unwrap()).as_str();
n_value += format!("{};", detail_map.get(*part).unwrap()).as_str();
}
}
n_value.pop();

result += format!("{}:{}\n", info_type.as_str(), n_value).as_str();

},
"org" => {

let mut org_value : String = String::new();
let mut org_value: String = String::new();

let org_parts = ["organization-name", "organization-unit"];
for part in org_parts.iter() {
if detail_map.contains_key(*part) {
org_value += format!("{};",detail_map.get(*part).unwrap()).as_str();
org_value += format!("{};", detail_map.get(*part).unwrap()).as_str();
}
}
org_value.pop();

result += format!("{}:{}\n", info_type.as_str(), org_value).as_str();

},
"tel" => {

},
"adr" => {
let mut adr_value: String = String::new();

let mut adr_value : String = String::new();

let adr_parts = ["street-address", "locality", "region", "postal-code", "country-name", "post-office-box", "extended-address"];
let adr_parts = ["street-address", "locality", "region", "postal-code",
"country-name", "post-office-box", "extended-address"];
for part in adr_parts.iter() {
if detail_map.contains_key(*part) {
adr_value += format!("{};",detail_map.get(*part).unwrap()).as_str();
adr_value += format!("{};", detail_map.get(*part).unwrap()).as_str();
}
}
adr_value.pop();

result += format!("{}:{}\n", info_type.as_str(), adr_value).as_str();

},
_ => {},
}
@@ -154,14 +147,14 @@ impl Microdata {
}

pub fn parse_json(node: &Node) -> String {
let json_data : Data = Self::traverse(node).unwrap();
let json_data: Data = Self::traverse(node).unwrap();
let json = serde_json::to_string(&json_data);
//println!("printing json from microdata {:?}", json);
return json.ok().unwrap();
}

fn get_attr_value(element: &Element, property: &str)-> Option<String> {
println!("{:?}",property);
fn get_attr_value(element: &Element, property: &str) -> Option<String> {
println!("{:?}", property);
// let mut atoms = match property {
// "itemprop" => element.get_tokenlist_attribute(&local_name!("itemprop"), ),
// "itemtype" => element.get_tokenlist_attribute(&local_name!("itemtype"), ),
@@ -177,43 +170,44 @@ impl Microdata {
Some(String::from("itemprop"))
}

fn traverse( node: &Node)-> Option<Data> {
if !node.is::<Element>(){
if let Some(ref text) = node.downcast::<Text>(){
fn traverse(node: &Node) -> Option<Data> {
if !node.is::<Element>() {
if let Some(ref text) = node.downcast::<Text>() {
let mut content = String::new();
content.push_str(&text.upcast::<CharacterData>().data());
return Some(Data::StrValue(String::from(content)));
}
None
}
else {
} else {
let element = node.downcast::<Element>().unwrap();
let mut head_str = String::from("");
let mut parent_vec:Vec<Data> = Vec::new();
let item_type = Self::get_attr_value(element,"itemtype").unwrap();
// if element.has_attribute(&local_name!("itemscope")) && element.has_attribute(&local_name!("itemtype")) && !element.has_attribute(&local_name!("itemprop")) {
let mut parent_vec: Vec<Data> = Vec::new();
let item_type = Self::get_attr_value(element, "itemtype").unwrap();
// if element.has_attribute(&local_name!("itemscope")) &&
// element.has_attribute(&local_name!("itemtype")) &&
// !element.has_attribute(&local_name!("itemprop")) {
// head_str = String::from("items");
// let mut propMap:HashMap<String,Data> = HashMap::new();
// //Data::HashValue(propMap)
// let item_type = Self::get_attr_value(element,"item_type").unwrap();

// }
// else if element.has_attribute(&local_name!("itemprop")) && element.has_attribute(&local_name!("item_type")) {
// else if element.has_attribute(&local_name!("itemprop")) &&
// element.has_attribute(&local_name!("item_type")) {

// head_str = Self::get_attr_value(element,"itemprop").unwrap();
// let item_type = Self::get_attr_value(element,"item_type").unwrap();

// }
// else {
// } else {
// return None;
// }
let mut inner_map:HashMap<String,Data> = HashMap::new();
for child in node.children(){
if let Some(childData) = Self::traverse(child.upcast::<Node>()){
let mut inner_map: HashMap<String, Data> = HashMap::new();
for child in node.children() {
if let Some(childData) = Self::traverse(child.upcast::<Node>()) {
parent_vec.push(childData);
}
}
inner_map.insert(head_str,Data::VecValue(parent_vec));
inner_map.insert(head_str, Data::VecValue(parent_vec));
Some(Data::HashValue(inner_map))
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.